#ifndef SkPicturePlayback_DEFINED
#define SkPicturePlayback_DEFINED

#include "SkPicture.h"
#include "SkReader32.h"

#include "SkBitmap.h"
#include "SkMatrix.h"
#include "SkPaint.h"
#include "SkPath.h"
#include "SkPathHeap.h"
#include "SkRegion.h"
#include "SkPictureFlat.h"
#include "SkShape.h"
#include "SkThread.h"

class SkPictureRecord;
class SkStream;
class SkWStream;

class SkPicturePlayback {
public:
    SkPicturePlayback();
    SkPicturePlayback(const SkPicturePlayback& src);
    explicit SkPicturePlayback(const SkPictureRecord& record);
    explicit SkPicturePlayback(SkStream*);

    virtual ~SkPicturePlayback();

    void draw(SkCanvas& canvas);

    void serialize(SkWStream*) const;

    void dumpSize() const;
    
    // Can be called in the middle of playback (the draw() call). WIll abort the
    // drawing and return from draw() after the "current" op code is done
    void abort();

private:

    class TextContainer {
    public:
        size_t length() { return fByteLength; }
        const void* text() { return (const void*) fText; }
        size_t fByteLength;
        const char* fText;
    };

    const SkBitmap& getBitmap() {
        int index = getInt();
        SkASSERT(index > 0);
        return fBitmaps[index - 1];
    }

    int getIndex() { return fReader.readInt(); }
    int getInt() { return fReader.readInt(); }

    const SkMatrix* getMatrix() {
        int index = getInt();
        if (index == 0) {
            return NULL;
        }
        SkASSERT(index > 0 && index <= fMatrixCount);
        return &fMatrices[index - 1];
    }

    const SkPath& getPath() {
        return (*fPathHeap)[getInt() - 1];
    }

    SkPicture& getPicture() {
        int index = getInt();
        SkASSERT(index > 0 && index <= fPictureCount);
        return *fPictureRefs[index - 1];
    }
    
    SkShape* getShape() {
        int index = getInt();
        SkASSERT(index > 0 && index <= fShapeCount);
        return fShapes[index - 1];
    }
    
    const SkPaint* getPaint() {
        int index = getInt();
        if (index == 0) {
            return NULL;
        }
        SkASSERT(index > 0 && index <= fPaintCount);
        return &fPaints[index - 1];
    }

    const SkRect* getRectPtr() {
        if (fReader.readBool()) {
            return fReader.skipRect();
        } else {
            return NULL;
        }
    }

    const SkIRect* getIRectPtr() {
        if (fReader.readBool()) {
            return (const SkIRect*)fReader.skip(sizeof(SkIRect));
        } else {
            return NULL;
        }
    }

    const SkRegion& getRegion() {
        int index = getInt();
        SkASSERT(index > 0);
        return fRegions[index - 1];
    }

    SkScalar getScalar() { return fReader.readScalar(); }

    void getText(TextContainer* text) {
        size_t length = text->fByteLength = getInt();
        text->fText = (const char*)fReader.skip(length);
    }

    void init();

#ifdef SK_DEBUG_SIZE
public:
    int size(size_t* sizePtr);
    int bitmaps(size_t* size);
    int paints(size_t* size);
    int paths(size_t* size);
    int regions(size_t* size);
#endif

#ifdef SK_DEBUG_DUMP
private:
    void dumpBitmap(const SkBitmap& bitmap) const;
    void dumpMatrix(const SkMatrix& matrix) const;
    void dumpPaint(const SkPaint& paint) const;
    void dumpPath(const SkPath& path) const;
    void dumpPicture(const SkPicture& picture) const;
    void dumpRegion(const SkRegion& region) const;
    int dumpDrawType(char* bufferPtr, char* buffer, DrawType drawType);
    int dumpInt(char* bufferPtr, char* buffer, char* name);
    int dumpRect(char* bufferPtr, char* buffer, char* name);
    int dumpPoint(char* bufferPtr, char* buffer, char* name);
    void dumpPointArray(char** bufferPtrPtr, char* buffer, int count);
    int dumpPtr(char* bufferPtr, char* buffer, char* name, void* ptr);
    int dumpRectPtr(char* bufferPtr, char* buffer, char* name);
    int dumpScalar(char* bufferPtr, char* buffer, char* name);
    void dumpText(char** bufferPtrPtr, char* buffer);
    void dumpStream();

public:
    void dump() const;
#endif

private:
    SkPathHeap* fPathHeap;  // reference counted
    SkBitmap* fBitmaps;
    int fBitmapCount;
    SkMatrix* fMatrices;
    int fMatrixCount;
    SkPaint* fPaints;
    int fPaintCount;
    SkRegion* fRegions;
    int fRegionCount;
    mutable SkFlattenableReadBuffer fReader;

    SkPicture** fPictureRefs;
    int fPictureCount;
    SkShape** fShapes;
    int fShapeCount;

    SkRefCntPlayback fRCPlayback;
    SkTypefacePlayback fTFPlayback;
    SkFactoryPlayback*   fFactoryPlayback;
    SkMutex fDrawMutex;
};

#endif
