
/*
 * Copyright 2011 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */
#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"

#ifdef SK_BUILD_FOR_ANDROID
#include "SkThread.h"
#endif

class SkPictureRecord;
class SkStream;
class SkWStream;

class SkPicturePlayback {
public:
    SkPicturePlayback();
    SkPicturePlayback(const SkPicturePlayback& src);
    explicit SkPicturePlayback(const SkPictureRecord& record);
    explicit SkPicturePlayback(SkStream*, uint32_t pictureVersion = PICTURE_VERSION_JB);

    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];
    }

    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.skipT<SkRect>();
        } else {
            return NULL;
        }
    }

    const SkIRect* getIRectPtr() {
        if (fReader.readBool()) {
            return &fReader.skipT<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;

    SkRefCntPlayback fRCPlayback;
    SkTypefacePlayback fTFPlayback;
    SkFactoryPlayback*   fFactoryPlayback;
#ifdef SK_BUILD_FOR_ANDROID
    SkMutex fDrawMutex;
#endif
};

#endif
