/*
 * 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/SkBitmap.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkColor.h"
#include "include/core/SkFilterQuality.h"
#include "include/core/SkImage.h"
#include "include/core/SkImageFilter.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/SkPoint.h"
#include "include/core/SkRRect.h"
#include "include/core/SkRect.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkScalar.h"
#include "include/core/SkSize.h"
#include "include/core/SkString.h"
#include "include/core/SkSurface.h"
#include "include/core/SkTypes.h"
#include "include/effects/SkImageFilters.h"
#include "include/private/SkTArray.h"

#include <utility>

namespace skiagm {

// Each method of this type must draw its geometry inside 'r' using 'p'
typedef void(*drawMth)(SkCanvas* canvas, const SkRect& r, const SkPaint& p);

static void draw_rect(SkCanvas* canvas, const SkRect& r, const SkPaint& p) {
    canvas->drawRect(r, p);
}

static void draw_oval(SkCanvas* canvas, const SkRect& r, const SkPaint& p) {
    canvas->drawOval(r, p);
}

static void draw_rrect(SkCanvas* canvas, const SkRect& r, const SkPaint& p) {
    SkScalar xRad = r.width() / 4.0f;
    SkScalar yRad = r.height() / 4.0f;

    SkRRect rr;
    rr.setRectXY(r, xRad, yRad);
    canvas->drawRRect(rr, p);
}

static void draw_drrect(SkCanvas* canvas, const SkRect& r, const SkPaint& p) {
    SkScalar xRad = r.width() / 4.0f;
    SkScalar yRad = r.height() / 4.0f;

    SkRRect outer;
    outer.setRectXY(r, xRad, yRad);
    SkRRect inner = outer;
    inner.inset(xRad, yRad);
    canvas->drawDRRect(outer, inner, p);
}

static void draw_path(SkCanvas* canvas, const SkRect& r, const SkPaint& p) {
    SkPath path;

    path.moveTo(r.fLeft, r.fTop);
    path.lineTo(r.fLeft, r.fBottom);
    path.lineTo(r.fRight, r.fBottom);
    path.close();

    canvas->drawPath(path, p);
}

static void draw_points(SkCanvas* canvas, const SkRect& r, const SkPaint& p) {
    SkPoint pts0[2] = { { r.fLeft, r.fTop }, { r.fRight, r.fBottom } };
    SkPoint pts1[2] = { { r.fLeft, r.fBottom }, { r.fRight, r.fTop } };

    canvas->drawPoints(SkCanvas::kLines_PointMode, 2, pts0, p);
    canvas->drawPoints(SkCanvas::kLines_PointMode, 2, pts1, p);
}

static void draw_bitmap(SkCanvas* canvas, const SkRect& r, const SkPaint& p) {
    SkBitmap bm;

    bm.allocN32Pixels(64, 64);
    SkCanvas temp(bm);
    temp.clear(SK_ColorMAGENTA);

    canvas->drawBitmapRect(bm, r, &p);
}

constexpr drawMth gDrawMthds[] = {
    draw_rect, draw_oval, draw_rrect, draw_drrect, draw_path, draw_points, draw_bitmap
};

static void add_paint(SkTArray<SkPaint>* paints, sk_sp<SkImageFilter> filter) {
    SkPaint& p = paints->push_back();
    p.setImageFilter(std::move(filter));
    SkASSERT(p.canComputeFastBounds());
}

// Create a selection of imagefilter-based paints to test
static void create_paints(SkTArray<SkPaint>* paints, sk_sp<SkImageFilter> source) {
    {
        SkMatrix scale;
        scale.setScale(2.0f, 2.0f);

        sk_sp<SkImageFilter> scaleMIF(
            SkImageFilters::MatrixTransform(scale, kLow_SkFilterQuality, source));

        add_paint(paints, std::move(scaleMIF));
    }

    {
        SkMatrix rot;
        rot.setRotate(-33.3f);

        sk_sp<SkImageFilter> rotMIF(
            SkImageFilters::MatrixTransform(rot, kLow_SkFilterQuality, source));

        add_paint(paints, std::move(rotMIF));
    }

    {
        SkRect src = SkRect::MakeXYWH(20, 20, 10, 10);
        SkRect dst = SkRect::MakeXYWH(30, 30, 30, 30);
        sk_sp<SkImageFilter> tileIF(SkImageFilters::Tile(src, dst, nullptr));

        add_paint(paints, std::move(tileIF));
    }

    {
        sk_sp<SkImageFilter> dsif =
                SkImageFilters::DropShadow(10.0f, 10.0f, 3.0f, 3.0f, SK_ColorRED, source);

        add_paint(paints, std::move(dsif));
    }

    {
        sk_sp<SkImageFilter> dsif =
            SkImageFilters::DropShadowOnly(27.0f, 27.0f, 3.0f, 3.0f, SK_ColorRED, source);

        add_paint(paints, std::move(dsif));
    }

    add_paint(paints, SkImageFilters::Blur(3, 3, source));
    add_paint(paints, SkImageFilters::Offset(15, 15, source));
}

// This GM visualizes the fast bounds for various combinations of geometry
// and image filter
class ImageFilterFastBoundGM : public GM {
public:
    ImageFilterFastBoundGM() {
        this->setBGColor(0xFFCCCCCC);
    }

protected:
    static constexpr int kTileWidth = 100;
    static constexpr int kTileHeight = 100;
    static constexpr int kNumVertTiles = 7;
    static constexpr int kNumXtraCols = 2;

    SkString onShortName() override { return SkString("filterfastbounds"); }

    SkISize onISize() override {
        return SkISize::Make((SK_ARRAY_COUNT(gDrawMthds) + kNumXtraCols) * kTileWidth,
                             kNumVertTiles * kTileHeight);
    }

    static void draw_geom_with_paint(drawMth draw, const SkIPoint& off,
                                     SkCanvas* canvas, const SkPaint& p) {
        SkPaint redStroked;
        redStroked.setColor(SK_ColorRED);
        redStroked.setStyle(SkPaint::kStroke_Style);

        SkPaint blueStroked;
        blueStroked.setColor(SK_ColorBLUE);
        blueStroked.setStyle(SkPaint::kStroke_Style);

        const SkRect r = SkRect::MakeLTRB(20, 20, 30, 30);
        SkRect storage;

        canvas->save();
            canvas->translate(SkIntToScalar(off.fX), SkIntToScalar(off.fY));
            canvas->scale(1.5f, 1.5f);

            const SkRect& fastBound = p.computeFastBounds(r, &storage);

            canvas->save();
                canvas->clipRect(fastBound);
                (*draw)(canvas, r, p);
            canvas->restore();

            canvas->drawRect(r, redStroked);
            canvas->drawRect(fastBound, blueStroked);
        canvas->restore();
    }

    static void draw_savelayer_with_paint(const SkIPoint& off,
                                          SkCanvas* canvas,
                                          const SkPaint& p) {
        SkPaint redStroked;
        redStroked.setColor(SK_ColorRED);
        redStroked.setStyle(SkPaint::kStroke_Style);

        SkPaint blueStroked;
        blueStroked.setColor(SK_ColorBLUE);
        blueStroked.setStyle(SkPaint::kStroke_Style);

        const SkRect bounds = SkRect::MakeWH(10, 10);
        SkRect storage;

        canvas->save();
            canvas->translate(30, 30);
            canvas->translate(SkIntToScalar(off.fX), SkIntToScalar(off.fY));
            canvas->scale(1.5f, 1.5f);

            const SkRect& fastBound = p.computeFastBounds(bounds, &storage);

            canvas->saveLayer(&fastBound, &p);
            canvas->restore();

            canvas->drawRect(bounds, redStroked);
            canvas->drawRect(fastBound, blueStroked);
        canvas->restore();
    }

    void onDraw(SkCanvas* canvas) override {

        SkPaint blackFill;

        //-----------
        // Normal paints (no source)
        SkTArray<SkPaint> paints;
        create_paints(&paints, nullptr);

        //-----------
        // Paints with a PictureImageFilter as a source
        sk_sp<SkPicture> pic;

        {
            SkPictureRecorder rec;

            SkCanvas* c = rec.beginRecording(10, 10);
            c->drawRect(SkRect::MakeWH(10, 10), blackFill);
            pic = rec.finishRecordingAsPicture();
        }

        SkTArray<SkPaint> pifPaints;
        create_paints(&pifPaints, SkImageFilters::Picture(pic));

        //-----------
        // Paints with a SkImageSource as a source

        auto surface(SkSurface::MakeRasterN32Premul(10, 10));
        {
            SkPaint p;
            SkCanvas* temp = surface->getCanvas();
            temp->clear(SK_ColorYELLOW);
            p.setColor(SK_ColorBLUE);
            temp->drawRect(SkRect::MakeLTRB(5, 5, 10, 10), p);
            p.setColor(SK_ColorGREEN);
            temp->drawRect(SkRect::MakeLTRB(5, 0, 10, 5), p);
        }

        sk_sp<SkImage> image(surface->makeImageSnapshot());
        sk_sp<SkImageFilter> imageSource(SkImageFilters::Image(std::move(image)));
        SkTArray<SkPaint> bmsPaints;
        create_paints(&bmsPaints, std::move(imageSource));

        //-----------
        SkASSERT(paints.count() == kNumVertTiles);
        SkASSERT(paints.count() == pifPaints.count());
        SkASSERT(paints.count() == bmsPaints.count());

        // horizontal separators
        for (int i = 1; i < paints.count(); ++i) {
            canvas->drawLine(0,
                             i*SkIntToScalar(kTileHeight),
                             SkIntToScalar((SK_ARRAY_COUNT(gDrawMthds) + kNumXtraCols)*kTileWidth),
                             i*SkIntToScalar(kTileHeight),
                             blackFill);
        }
        // vertical separators
        for (int i = 0; i < (int)SK_ARRAY_COUNT(gDrawMthds) + kNumXtraCols; ++i) {
            canvas->drawLine(SkIntToScalar(i * kTileWidth),
                             0,
                             SkIntToScalar(i * kTileWidth),
                             SkIntToScalar(paints.count() * kTileWidth),
                             blackFill);
        }

        // A column of saveLayers with PictureImageFilters
        for (int i = 0; i < pifPaints.count(); ++i) {
            draw_savelayer_with_paint(SkIPoint::Make(0, i*kTileHeight),
                                      canvas, pifPaints[i]);
        }

        // A column of saveLayers with BitmapSources
        for (int i = 0; i < pifPaints.count(); ++i) {
            draw_savelayer_with_paint(SkIPoint::Make(kTileWidth, i*kTileHeight),
                                      canvas, bmsPaints[i]);
        }

        // Multiple columns with different geometry
        for (int i = 0; i < (int)SK_ARRAY_COUNT(gDrawMthds); ++i) {
            for (int j = 0; j < paints.count(); ++j) {
                draw_geom_with_paint(*gDrawMthds[i],
                                     SkIPoint::Make((i+kNumXtraCols) * kTileWidth, j*kTileHeight),
                                     canvas, paints[j]);
            }
        }

    }

private:
    typedef GM INHERITED;
};

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

DEF_GM(return new ImageFilterFastBoundGM;)
}
