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

#include "SampleCode.h"
#include "SkData.h"
#include "SkDecodingImageGenerator.h"
#include "SkDumpCanvas.h"
#include "SkView.h"
#include "SkCanvas.h"
#include "SkGradientShader.h"
#include "SkGraphics.h"
#include "SkImageDecoder.h"
#include "SkOSFile.h"
#include "SkPath.h"
#include "SkPicture.h"
#include "SkPictureRecorder.h"
#include "SkRandom.h"
#include "SkRegion.h"
#include "SkShader.h"
#include "SkUtils.h"
#include "SkColorPriv.h"
#include "SkColorFilter.h"
#include "SkTime.h"
#include "SkTypeface.h"
#include "SkXfermode.h"
#include "SkStream.h"
#include "SkXMLParser.h"

#include "gm.h"

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

static SkBitmap load_bitmap() {
    SkBitmap bm;
    SkString directory = skiagm::GM::GetResourcePath();
    SkString path = SkOSPath::SkPathJoin(directory.c_str(), "mandrill_512.png");
    SkAutoDataUnref data(SkData::NewFromFileName(path.c_str()));
    if (data.get() != NULL) {
        SkInstallDiscardablePixelRef(SkDecodingImageGenerator::Create(
            data, SkDecodingImageGenerator::Options()), &bm);
    }
    return bm;
}

static void drawCircle(SkCanvas* canvas, int r, SkColor color) {
    SkPaint paint;
    paint.setAntiAlias(true);
    paint.setColor(color);

    canvas->drawCircle(SkIntToScalar(r), SkIntToScalar(r), SkIntToScalar(r),
                       paint);
}

class PictureView : public SampleView {
    SkBitmap fBitmap;
public:
    PictureView() {

        fBitmap = load_bitmap();

        SkPictureRecorder recorder;

        recorder.beginRecording(100, 100, NULL, 0);
        fSubPicture = recorder.endRecording();

        SkCanvas* canvas = recorder.beginRecording(100, 100, NULL, 0);
        SkPaint paint;
        paint.setAntiAlias(true);

        canvas->drawBitmap(fBitmap, 0, 0, NULL);

        drawCircle(canvas, 50, SK_ColorBLACK);
        canvas->drawPicture(fSubPicture);
        canvas->translate(SkIntToScalar(50), 0);
        canvas->drawPicture(fSubPicture);
        canvas->translate(0, SkIntToScalar(50));
        canvas->drawPicture(fSubPicture);
        canvas->translate(SkIntToScalar(-50), 0);
        canvas->drawPicture(fSubPicture);

        fPicture = recorder.endRecording();

        // fPicture now has (4) references to fSubPicture. We can release our ref,
        // and just unref fPicture in our destructor, and it will in turn take care of
        // the other references to fSubPicture
        fSubPicture->unref();
    }

    virtual ~PictureView() {
        fPicture->unref();
    }

protected:
    // overrides from SkEventSink
    virtual bool onQuery(SkEvent* evt) {
        if (SampleCode::TitleQ(*evt)) {
            SampleCode::TitleR(evt, "Picture");
            return true;
        }
        return this->INHERITED::onQuery(evt);
    }

    void drawSomething(SkCanvas* canvas) {
        SkPaint paint;

        canvas->save();
        canvas->scale(0.5f, 0.5f);
        canvas->drawBitmap(fBitmap, 0, 0, NULL);
        canvas->restore();

        const char beforeStr[] = "before circle";
        const char afterStr[] = "after circle";

        paint.setAntiAlias(true);

        paint.setColor(SK_ColorRED);
        canvas->drawData(beforeStr, sizeof(beforeStr));
        canvas->drawCircle(SkIntToScalar(50), SkIntToScalar(50),
                           SkIntToScalar(40), paint);
        canvas->drawData(afterStr, sizeof(afterStr));
        paint.setColor(SK_ColorBLACK);
        paint.setTextSize(SkIntToScalar(40));
        canvas->drawText("Picture", 7, SkIntToScalar(50), SkIntToScalar(62),
                         paint);

    }

    virtual void onDrawContent(SkCanvas* canvas) {
        this->drawSomething(canvas);

        SkPictureRecorder recorder;
        this->drawSomething(recorder.beginRecording(100, 100, NULL, 0));
        SkAutoTUnref<SkPicture> pict(recorder.endRecording());

        canvas->save();
        canvas->translate(SkIntToScalar(300), SkIntToScalar(50));
        canvas->scale(-SK_Scalar1, -SK_Scalar1);
        canvas->translate(-SkIntToScalar(100), -SkIntToScalar(50));
        canvas->drawPicture(pict);
        canvas->restore();

        canvas->save();
        canvas->translate(SkIntToScalar(200), SkIntToScalar(150));
        canvas->scale(SK_Scalar1, -SK_Scalar1);
        canvas->translate(0, -SkIntToScalar(50));
        canvas->drawPicture(pict);
        canvas->restore();

        canvas->save();
        canvas->translate(SkIntToScalar(100), SkIntToScalar(100));
        canvas->scale(-SK_Scalar1, SK_Scalar1);
        canvas->translate(-SkIntToScalar(100), 0);
        canvas->drawPicture(pict);
        canvas->restore();

#ifdef SK_DEVELOPER
        if (false) {
            SkDebugfDumper dumper;
            SkDumpCanvas dumpCanvas(&dumper);
            dumpCanvas.drawPicture(pict);
        }
#endif

        // This used to re-record the sub-picture and redraw the parent
        // A capability that is now forbidden!

        SkRandom rand(SampleCode::GetAnimTime());
        canvas->translate(SkIntToScalar(10), SkIntToScalar(250));
        canvas->drawPicture(fPicture);
        delayInval(500);
    }

private:
    #define INVAL_ALL_TYPE  "inval-all"

    void delayInval(SkMSec delay) {
        (new SkEvent(INVAL_ALL_TYPE, this->getSinkID()))->postDelay(delay);
    }

    virtual bool onEvent(const SkEvent& evt) {
        if (evt.isType(INVAL_ALL_TYPE)) {
            this->inval(NULL);
            return true;
        }
        return this->INHERITED::onEvent(evt);
    }

    SkPicture*  fPicture;
    SkPicture*  fSubPicture;

    typedef SampleView INHERITED;
};

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

static SkView* MyFactory() { return new PictureView; }
static SkViewRegister reg(MyFactory);
