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

#include "gm/gm.h"
#include "include/core/SkBBHFactory.h"
#include "include/core/SkBlendMode.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkMatrix.h"
#include "include/core/SkPaint.h"
#include "include/core/SkPath.h"
#include "include/core/SkPicture.h"
#include "include/core/SkPictureRecorder.h"
#include "include/core/SkRect.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkSize.h"
#include "include/core/SkString.h"

static sk_sp<SkPicture> make_picture() {
    SkPictureRecorder rec;
    SkCanvas* canvas = rec.beginRecording(100, 100);

    SkPaint paint;
    paint.setAntiAlias(true);

    paint.setColor(0x800000FF);
    canvas->drawRect(SkRect::MakeWH(100, 100), paint);

    paint.setColor(0x80FF0000);
    canvas->drawPath(SkPath::Polygon({{0, 0}, {100, 0}, {100, 100}}, false), paint);

    paint.setColor(0x8000FF00);
    canvas->drawPath(SkPath::Polygon({{0, 0}, {100, 0}, {0, 100}}, false), paint);

    paint.setColor(0x80FFFFFF);
    paint.setBlendMode(SkBlendMode::kPlus);
    canvas->drawRect(SkRect::MakeXYWH(25, 25, 50, 50), paint);

    return rec.finishRecordingAsPicture();
}

// Exercise the optional arguments to drawPicture
//
class PictureGM : public skiagm::GM {
public:
    PictureGM()
        : fPicture(nullptr)
    {}

protected:
    void onOnceBeforeDraw() override {
         fPicture = make_picture();
    }

    SkString getName() const override { return SkString("pictures"); }

    SkISize getISize() override { return SkISize::Make(450, 120); }

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

        SkMatrix matrix;
        SkPaint paint;

        canvas->drawPicture(fPicture);

        matrix.setTranslate(110, 0);
        canvas->drawPicture(fPicture, &matrix, nullptr);

        matrix.postTranslate(110, 0);
        canvas->drawPicture(fPicture, &matrix, &paint);

        paint.setAlphaf(0.5f);
        matrix.postTranslate(110, 0);
        canvas->drawPicture(fPicture, &matrix, &paint);
    }

private:
    sk_sp<SkPicture> fPicture;

    using INHERITED = skiagm::GM;
};

// Exercise drawing a picture with a cull rect of non-zero top-left corner.
//
// See skbug.com/40040654, which would fail
// ```
//   dm -m picture_cull_rect --config serialize-8888
// ```
// until that bug is fixed.
class PictureCullRectGM : public skiagm::GM {
public:
    PictureCullRectGM()
        : fPicture(nullptr)
    {}

protected:
    void onOnceBeforeDraw() override {
        SkPictureRecorder rec;
        SkRTreeFactory rtreeFactory;
        SkCanvas* canvas = rec.beginRecording(100, 100, &rtreeFactory);

        SkPaint paint;
        paint.setAntiAlias(false);

        SkRect rect = SkRect::MakeLTRB(0, 80, 100, 100);

        // Make picture complex enough to trigger the cull rect and bbh (RTree) computations.
        // (A single drawRect won't trigger it.)
        paint.setColor(0x800000FF);
        canvas->drawRect(rect, paint);
        canvas->drawOval(rect, paint);

        fPicture = rec.finishRecordingAsPicture();

        SkASSERT(fPicture->cullRect().top() == 80);
    }

    SkString getName() const override { return SkString("picture_cull_rect"); }

    SkISize getISize() override { return SkISize::Make(120, 120); }

    void onDraw(SkCanvas* canvas) override {
        canvas->clipRect(SkRect::MakeLTRB(0, 60, 120, 120));
        canvas->translate(10, 10);
        canvas->drawPicture(fPicture);
    }

private:
    sk_sp<SkPicture> fPicture;

    using INHERITED = skiagm::GM;
};

DEF_GM(return new PictureGM;)
DEF_GM(return new PictureCullRectGM;)
