/*
 * Copyright 2012 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#ifndef SkImage_DEFINED
#define SkImage_DEFINED

#include "SkAlpha.h"
#include "SkImageEncoder.h"
#include "SkRefCnt.h"
#include "SkScalar.h"

class SkData;
class SkCanvas;
class SkPaint;
class SkShader;
class GrContext;
class GrTexture;

// need for TileMode
#include "SkShader.h"

enum SkColorType {
    kAlpha_8_SkColorType,
    kRGB_565_SkColorType,
    kRGBA_8888_SkColorType,
    kBGRA_8888_SkColorType,

#if SK_PMCOLOR_BYTE_ORDER(B,G,R,A)
    kPMColor_SkColorType = kBGRA_8888_SkColorType,
#elif SK_PMCOLOR_BYTE_ORDER(R,G,B,A)
    kPMColor_SkColorType = kRGBA_8888_SkColorType,
#else
    #error "SK_*32_SHFIT values must correspond to BGRA or RGBA byte order"
#endif

    kLastEnum_SkColorType = kBGRA_8888_SkColorType
};

struct SkImageInfo {
    int         fWidth;
    int         fHeight;
    SkColorType fColorType;
    SkAlphaType fAlphaType;
};

bool operator==(const SkImageInfo& lhs, const SkImageInfo& rhs);
bool operator!=(const SkImageInfo& lhs, const SkImageInfo& rhs);

/**
 *  SkImage is an abstraction for drawing a rectagle of pixels, though the
 *  particular type of image could be actually storing its data on the GPU, or
 *  as drawing commands (picture or PDF or otherwise), ready to be played back
 *  into another canvas.
 *
 *  The content of SkImage is always immutable, though the actual storage may
 *  change, if for example that image can be re-created via encoded data or
 *  other means.
 */
class SK_API SkImage : public SkRefCnt {
public:
    SK_DECLARE_INST_COUNT(SkImage)

#ifdef SK_SUPPORT_LEGACY_COLORTYPE
    typedef SkColorType ColorType;

    static const SkColorType kAlpha_8_ColorType     = kAlpha_8_SkColorType;
    static const SkColorType kRGB_565_ColorType     = kRGB_565_SkColorType;
    static const SkColorType kRGBA_8888_ColorType   = kRGBA_8888_SkColorType;
    static const SkColorType kBGRA_8888_ColorType   = kBGRA_8888_SkColorType;
    static const SkColorType kPMColor_ColorType     = kPMColor_SkColorType;
    static const SkColorType kLastEnum_ColorType    = kLastEnum_SkColorType;
#endif

#ifdef SK_SUPPORT_LEGACY_ALPHATYPE
    typedef SkAlphaType AlphaType;

    static const SkAlphaType kIgnore_AlphaType   = kIgnore_SkAlphaType;
    static const SkAlphaType kOpaque_AlphaType   = kOpaque_SkAlphaType;
    static const SkAlphaType kPremul_AlphaType   = kPremul_SkAlphaType;
    static const SkAlphaType kUnpremul_AlphaType = kUnpremul_SkAlphaType;
#endif

    typedef SkImageInfo Info;

    static SkImage* NewRasterCopy(const Info&, const void* pixels, size_t rowBytes);
    static SkImage* NewRasterData(const Info&, SkData* pixels, size_t rowBytes);
    static SkImage* NewEncodedData(SkData*);

    /**
     * GrTexture is a more logical parameter for this factory, but its
     * interactions with scratch cache still has issues, so for now we take
     * SkBitmap instead. This will be changed in the future. skbug.com/1449
     */
    static SkImage* NewTexture(const SkBitmap&);

    int width() const { return fWidth; }
    int height() const { return fHeight; }
    uint32_t uniqueID() const { return fUniqueID; }

    /**
     * Return the GrTexture that stores the image pixels. Calling getTexture
     * does not affect the reference count of the GrTexture object.
     * Will return NULL if the image does not use a texture.
     */
    GrTexture* getTexture();

    SkShader*   newShaderClamp() const;
    SkShader*   newShader(SkShader::TileMode, SkShader::TileMode) const;

    void draw(SkCanvas*, SkScalar x, SkScalar y, const SkPaint*);

    /**
     *  Draw the image, cropped to the src rect, to the dst rect of a canvas.
     *  If src is larger than the bounds of the image, the rest of the image is
     *  filled with transparent black pixels.
     *
     *  See SkCanvas::drawBitmapRectToRect for similar behavior.
     */
    void draw(SkCanvas*, const SkRect* src, const SkRect& dst, const SkPaint*);

    /**
     *  Encode the image's pixels and return the result as a new SkData, which
     *  the caller must manage (i.e. call unref() when they are done).
     *
     *  If the image type cannot be encoded, or the requested encoder type is
     *  not supported, this will return NULL.
     */
    SkData* encode(SkImageEncoder::Type t = SkImageEncoder::kPNG_Type,
                   int quality = 80) const;

protected:
    SkImage(int width, int height) :
        fWidth(width),
        fHeight(height),
        fUniqueID(NextUniqueID()) {

        SkASSERT(width >= 0);
        SkASSERT(height >= 0);
    }

private:
    const int       fWidth;
    const int       fHeight;
    const uint32_t  fUniqueID;

    static uint32_t NextUniqueID();

    typedef SkRefCnt INHERITED;
};

#endif
