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

#include "gm.h"
#include "SkCanvas.h"
#include "SkData.h"
#include "SkImage.h"
#include "SkPictureRecorder.h"
#include "SkSurface.h"

static void draw_something(SkCanvas* canvas, const SkRect& bounds) {
    SkPaint paint;
    paint.setAntiAlias(true);
    paint.setColor(SK_ColorRED);
    paint.setStyle(SkPaint::kStroke_Style);
    paint.setStrokeWidth(10);
    canvas->drawRect(bounds, paint);
    paint.setStyle(SkPaint::kFill_Style);
    paint.setColor(SK_ColorBLUE);
    canvas->drawOval(bounds, paint);
}

typedef SkImage* (*ImageMakerProc)(GrContext*, const SkPicture*, const SkImageInfo&);

static SkImage* make_raster(GrContext*, const SkPicture* pic, const SkImageInfo& info) {
    SkAutoTUnref<SkSurface> surface(SkSurface::NewRaster(info));
    surface->getCanvas()->clear(0);
    surface->getCanvas()->drawPicture(pic);
    return surface->newImageSnapshot();
}

static SkImage* make_texture(GrContext* ctx, const SkPicture* pic, const SkImageInfo& info) {
    if (!ctx) {
        return nullptr;
    }
    SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTarget(ctx, SkBudgeted::kNo,
                                                               info, 0));
    surface->getCanvas()->clear(0);
    surface->getCanvas()->drawPicture(pic);
    return surface->newImageSnapshot();
}

static SkImage* make_pict_gen(GrContext*, const SkPicture* pic, const SkImageInfo& info) {
    return SkImage::NewFromPicture(pic, info.dimensions(), nullptr, nullptr);
}

static SkImage* make_encode_gen(GrContext* ctx, const SkPicture* pic, const SkImageInfo& info) {
    SkAutoTUnref<SkImage> src(make_raster(ctx, pic, info));
    if (!src) {
        return nullptr;
    }
    SkAutoTUnref<SkData> encoded(src->encode(SkImageEncoder::kPNG_Type, 100));
    if (!encoded) {
        return nullptr;
    }
    return SkImage::NewFromEncoded(encoded);
}

const ImageMakerProc gProcs[] = {
    make_raster,
    make_texture,
    make_pict_gen,
    make_encode_gen,
};

/*
 *  Exercise drawing pictures inside an image, showing that the image version is pixelated
 *  (correctly) when it is inside an image.
 */
class ImageShaderGM : public skiagm::GM {
    SkAutoTUnref<SkPicture> fPicture;

public:
    ImageShaderGM() {}

protected:
    SkString onShortName() override {
        return SkString("image-shader");
    }

    SkISize onISize() override {
        return SkISize::Make(850, 450);
    }

    void onOnceBeforeDraw() override {
        const SkRect bounds = SkRect::MakeWH(100, 100);
        SkPictureRecorder recorder;
        draw_something(recorder.beginRecording(bounds), bounds);
        fPicture.reset(recorder.endRecording());
    }

    void testImage(SkCanvas* canvas, SkImage* image) {
        SkAutoCanvasRestore acr(canvas, true);

        canvas->drawImage(image, 0, 0);
        canvas->translate(0, 120);

        const SkShader::TileMode tile = SkShader::kRepeat_TileMode;
        const SkMatrix localM = SkMatrix::MakeTrans(-50, -50);
        SkAutoTUnref<SkShader> shader(image->newShader(tile, tile, &localM));
        SkPaint paint;
        paint.setAntiAlias(true);
        paint.setShader(shader);
        canvas->drawCircle(50, 50, 50, paint);
    }

    void onDraw(SkCanvas* canvas) override {
        canvas->translate(20, 20);

        const SkImageInfo info = SkImageInfo::MakeN32Premul(100, 100);

        for (size_t i = 0; i < SK_ARRAY_COUNT(gProcs); ++i) {
            SkAutoTUnref<SkImage> image(gProcs[i](canvas->getGrContext(), fPicture, info));
            if (image) {
                this->testImage(canvas, image);
            }
            canvas->translate(120, 0);
        }
    }

private:
    typedef skiagm::GM INHERITED;
};
DEF_GM( return new ImageShaderGM; )

