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

#include "SkSurface_Base.h"
#include "SkCanvas.h"
#include "SkImagePriv.h"
#include "SkPicture.h"

/**
 *  What does it mean to ask for more than one canvas from a picture?
 *  How do we return an Image and then "continue" recording?
 */
class SkSurface_Picture : public SkSurface_Base {
public:
    SkSurface_Picture(int width, int height);
    virtual ~SkSurface_Picture();

    virtual SkCanvas* onNewCanvas() SK_OVERRIDE;
    virtual SkSurface* onNewSurface(const SkImageInfo&) SK_OVERRIDE;
    virtual SkImage* onNewImageSnapshot() SK_OVERRIDE;
    virtual void onDraw(SkCanvas*, SkScalar x, SkScalar y,
                        const SkPaint*) SK_OVERRIDE;
    virtual void onCopyOnWrite(ContentChangeMode) SK_OVERRIDE;

private:
    SkPicture*  fPicture;

    typedef SkSurface_Base INHERITED;
};

///////////////////////////////////////////////////////////////////////////////

SkSurface_Picture::SkSurface_Picture(int width, int height) : INHERITED(width, height) {
    fPicture = NULL;
}

SkSurface_Picture::~SkSurface_Picture() {
    SkSafeUnref(fPicture);
}

SkCanvas* SkSurface_Picture::onNewCanvas() {
    if (!fPicture) {
        fPicture = SkNEW(SkPicture);
    }
    SkCanvas* canvas = fPicture->beginRecording(this->width(), this->height());
    canvas->ref();  // our caller will call unref()
    return canvas;
}

SkSurface* SkSurface_Picture::onNewSurface(const SkImageInfo& info) {
    return SkSurface::NewPicture(info.fWidth, info.fHeight);
}

SkImage* SkSurface_Picture::onNewImageSnapshot() {
    if (fPicture) {
        return SkNewImageFromPicture(fPicture);
    } else {
        SkImageInfo info;
        info.fWidth = info.fHeight = 0;
        info.fColorType = kPMColor_SkColorType;
        info.fAlphaType = kOpaque_SkAlphaType;
        return SkImage::NewRasterCopy(info, NULL, 0);
    }
}

void SkSurface_Picture::onDraw(SkCanvas* canvas, SkScalar x, SkScalar y,
                               const SkPaint* paint) {
    if (!fPicture) {
        return;
    }
    SkImagePrivDrawPicture(canvas, fPicture, x, y, paint);
}

void SkSurface_Picture::onCopyOnWrite(ContentChangeMode /*mode*/) {
    // We always spawn a copy of the recording picture when we
    // are asked for a snapshot, so we never need to do anything here.
}

///////////////////////////////////////////////////////////////////////////////


SkSurface* SkSurface::NewPicture(int width, int height) {
    if ((width | height) < 0) {
        return NULL;
    }

    return SkNEW_ARGS(SkSurface_Picture, (width, height));
}
