#include "SampleCode.h"
#include "SkDumpCanvas.h"
#include "SkView.h"
#include "SkCanvas.h"
#include "Sk64.h"
#include "SkGradientShader.h"
#include "SkGraphics.h"
#include "SkImageDecoder.h"
#include "SkPath.h"
#include "SkPicture.h"
#include "SkRandom.h"
#include "SkRegion.h"
#include "SkShader.h"
#include "SkUtils.h"
#include "SkColorPriv.h"
#include "SkColorFilter.h"
#include "SkShape.h"
#include "SkTime.h"
#include "SkTypeface.h"
#include "SkXfermode.h"

#include "SkStream.h"
#include "SkXMLParser.h"

class SignalShape : public SkShape {
public:
    SignalShape() : fSignal(0) {}

    SkShape* setSignal(int n) {
        fSignal = n;
        return this;
    }

protected:
    virtual void onDraw(SkCanvas* canvas) {
    //    SkDebugf("---- sc %d\n", canvas->getSaveCount() - 1);
    }

private:
    int fSignal;
};

static SkPMColor SignalProc(SkPMColor src, SkPMColor dst) {
    return dst;
}

/*  Picture playback will skip blocks of draw calls that follow a clip() call
    that returns empty, and jump down to the corresponding restore() call.

    This is a great preformance win for drawing very large/tall pictures with
    a small visible window (think scrolling a long document). These tests make
    sure that (a) we are performing the culling, and (b) we don't get confused
    by nested save() calls, nor by calls to restoreToCount().
 */
static void test_saveRestoreCulling() {
    SkPaint signalPaint;
    SignalShape signalShape;

    SkPicture pic;
    SkRect r = SkRect::MakeWH(0, 0);
    int n;
    SkCanvas* canvas = pic.beginRecording(100, 100);
    int startN = canvas->getSaveCount();
    SkDebugf("---- start sc %d\n", startN);
    canvas->drawShape(signalShape.setSignal(1));
    canvas->save();
    canvas->drawShape(signalShape.setSignal(2));
    n = canvas->save();
    canvas->drawShape(signalShape.setSignal(3));
    canvas->save();
    canvas->clipRect(r);
    canvas->drawShape(signalShape.setSignal(4));
    canvas->restoreToCount(n);
    canvas->drawShape(signalShape.setSignal(5));
    canvas->restore();
    canvas->drawShape(signalShape.setSignal(6));
    SkASSERT(canvas->getSaveCount() == startN);

    SkBitmap bm;
    bm.setConfig(SkBitmap::kARGB_8888_Config, 100, 100);
    bm.allocPixels();
    SkCanvas c(bm);
    c.drawPicture(pic);
}

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

#include "SkImageRef_GlobalPool.h"

static SkBitmap load_bitmap() {
    SkStream* stream = new SkFILEStream("/skimages/sesame_street_ensemble-hp.jpg");
    SkAutoUnref aur(stream);
    
    SkBitmap bm;
    if (SkImageDecoder::DecodeStream(stream, &bm, SkBitmap::kNo_Config,
                                     SkImageDecoder::kDecodeBounds_Mode)) {
        SkPixelRef* pr = new SkImageRef_GlobalPool(stream, bm.config(), 1);
        bm.setPixelRef(pr)->unref();
    }
    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() {
        SkImageRef_GlobalPool::SetRAMBudget(16 * 1024);

        fBitmap = load_bitmap();

        fPicture = new SkPicture;
        SkCanvas* canvas = fPicture->beginRecording(100, 100);
        SkPaint paint;
        paint.setAntiAlias(true);
        
        canvas->drawBitmap(fBitmap, 0, 0, NULL);

        drawCircle(canvas, 50, SK_ColorBLACK);
        fSubPicture = new SkPicture;
        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 now has (4) references to us. We can release ours, and just
        // unref fPicture in our destructor, and it will in turn take care of
        // the other references to fSubPicture
        fSubPicture->unref();

        test_saveRestoreCulling();
    }
    
    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) {
        drawSomething(canvas);

        SkPicture* pict = new SkPicture;
        SkAutoUnref aur(pict);

        drawSomething(pict->beginRecording(100, 100));
        pict->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();

        if (false) {
            SkDebugfDumper dumper;
            SkDumpCanvas dumpCanvas(&dumper);
            dumpCanvas.drawPicture(*pict);
        }
        
        // test that we can re-record a subpicture, and see the results
        
        SkRandom rand(SampleCode::GetAnimTime());
        canvas->translate(SkIntToScalar(10), SkIntToScalar(250));
        drawCircle(fSubPicture->beginRecording(50, 50), 25,
                   rand.nextU() | 0xFF000000);
        canvas->drawPicture(*fPicture);
        delayInval(500);
    }
    
private:
    #define INVAL_ALL_TYPE  "inval-all"
    
    void delayInval(SkMSec delay) {
        (new SkEvent(INVAL_ALL_TYPE))->post(this->getSinkID(), 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);

