/*
 * 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 "gm/gm.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkClipOp.h"
#include "include/core/SkColor.h"
#include "include/core/SkColorFilter.h"
#include "include/core/SkFont.h"
#include "include/core/SkFontTypes.h"
#include "include/core/SkPaint.h"
#include "include/core/SkPathBuilder.h"
#include "include/core/SkRect.h"
#include "include/core/SkScalar.h"
#include "include/core/SkSize.h"
#include "include/core/SkString.h"
#include "include/core/SkTypeface.h"
#include "include/core/SkTypes.h"
#include "include/effects/SkGradientShader.h"
#include "tools/Resources.h"
#include "tools/ToolUtils.h"

#include <string.h>

namespace skiagm {

constexpr SkColor gPathColor = SK_ColorBLACK;
constexpr SkColor gClipAColor = SK_ColorBLUE;
constexpr SkColor gClipBColor = SK_ColorRED;

class ComplexClipGM : public GM {
public:
    ComplexClipGM(bool aaclip, bool saveLayer, bool invertDraw)
    : fDoAAClip(aaclip)
    , fDoSaveLayer(saveLayer)
    , fInvertDraw(invertDraw) {
        this->setBGColor(0xFFDEDFDE);
    }

protected:
    SkString onShortName() override {
        SkString str;
        str.printf("complexclip_%s%s%s",
                   fDoAAClip ? "aa" : "bw",
                   fDoSaveLayer ? "_layer" : "",
                   fInvertDraw ? "_invert" : "");
        return str;
    }

    SkISize onISize() override { return SkISize::Make(388, 780); }

    void onDraw(SkCanvas* canvas) override {
        SkPath path = SkPathBuilder()
                        .moveTo(0,   50)
                        .quadTo(0,   0,   50,  0)
                        .lineTo(175, 0)
                        .quadTo(200, 0,   200, 25)
                        .lineTo(200, 150)
                        .quadTo(200, 200, 150, 200)
                        .lineTo(0,   200)
                        .close()
                        .moveTo(50,  50)
                        .lineTo(150, 50)
                        .lineTo(150, 125)
                        .quadTo(150, 150, 125, 150)
                        .lineTo(50,  150)
                        .close()
                        .detach();
        if (fInvertDraw) {
            path.setFillType(SkPathFillType::kInverseEvenOdd);
        } else {
            path.setFillType(SkPathFillType::kEvenOdd);
        }
        SkPaint pathPaint;
        pathPaint.setAntiAlias(true);
        pathPaint.setColor(gPathColor);

        SkPath clipA = SkPath::Polygon({{10,  20}, {165, 22}, {70,  105}, {165, 177}, {-5,  180}}, true);

        SkPath clipB = SkPath::Polygon({{40,  10}, {190, 15}, {195, 190}, {40,  185}, {155, 100}}, true);

        SkFont font(ToolUtils::create_portable_typeface(), 20);

        constexpr struct {
            SkClipOp fOp;
            const char*      fName;
        } gOps[] = { //extra spaces in names for measureText
            {SkClipOp::kIntersect,         "Isect "},
            {SkClipOp::kDifference,        "Diff " },
        };

        canvas->translate(20, 20);
        canvas->scale(3 * SK_Scalar1 / 4, 3 * SK_Scalar1 / 4);

        if (fDoSaveLayer) {
            // We want the layer to appear symmetric relative to actual
            // device boundaries so we need to "undo" the effect of the
            // scale and translate
            SkRect bounds = SkRect::MakeLTRB(
              4.0f/3.0f * -20,
              4.0f/3.0f * -20,
              4.0f/3.0f * (this->getISize().fWidth - 20),
              4.0f/3.0f * (this->getISize().fHeight - 20));

            bounds.inset(100, 100);
            SkPaint boundPaint;
            boundPaint.setColor(SK_ColorRED);
            boundPaint.setStyle(SkPaint::kStroke_Style);
            canvas->drawRect(bounds, boundPaint);
            canvas->clipRect(bounds);
            canvas->saveLayer(&bounds, nullptr);
        }

        for (int invBits = 0; invBits < 4; ++invBits) {
            canvas->save();
            for (size_t op = 0; op < SK_ARRAY_COUNT(gOps); ++op) {
                this->drawHairlines(canvas, path, clipA, clipB);

                bool doInvA = SkToBool(invBits & 1);
                bool doInvB = SkToBool(invBits & 2);
                canvas->save();
                    // set clip
                    clipA.setFillType(doInvA ? SkPathFillType::kInverseEvenOdd :
                                      SkPathFillType::kEvenOdd);
                    clipB.setFillType(doInvB ? SkPathFillType::kInverseEvenOdd :
                                      SkPathFillType::kEvenOdd);
                    canvas->clipPath(clipA, fDoAAClip);
                    canvas->clipPath(clipB, gOps[op].fOp, fDoAAClip);

                    // In the inverse case we need to prevent the draw from covering the whole
                    // canvas.
                    if (fInvertDraw) {
                        SkRect rectClip = clipA.getBounds();
                        rectClip.join(path.getBounds());
                        rectClip.join(path.getBounds());
                        rectClip.outset(5, 5);
                        canvas->clipRect(rectClip);
                    }

                    // draw path clipped
                    canvas->drawPath(path, pathPaint);
                canvas->restore();


                SkPaint paint;
                SkScalar txtX = 45;
                paint.setColor(gClipAColor);
                const char* aTxt = doInvA ? "InvA " : "A ";
                canvas->drawSimpleText(aTxt, strlen(aTxt), SkTextEncoding::kUTF8, txtX, 220, font, paint);
                txtX += font.measureText(aTxt, strlen(aTxt), SkTextEncoding::kUTF8);
                paint.setColor(SK_ColorBLACK);
                canvas->drawSimpleText(gOps[op].fName, strlen(gOps[op].fName), SkTextEncoding::kUTF8, txtX, 220,
                                       font, paint);
                txtX += font.measureText(gOps[op].fName, strlen(gOps[op].fName), SkTextEncoding::kUTF8);
                paint.setColor(gClipBColor);
                const char* bTxt = doInvB ? "InvB " : "B ";
                canvas->drawSimpleText(bTxt, strlen(bTxt), SkTextEncoding::kUTF8, txtX, 220, font, paint);

                canvas->translate(250,0);
            }
            canvas->restore();
            canvas->translate(0, 250);
        }

        if (fDoSaveLayer) {
            canvas->restore();
        }
    }
private:
    void drawHairlines(SkCanvas* canvas, const SkPath& path,
                       const SkPath& clipA, const SkPath& clipB) {
        SkPaint paint;
        paint.setAntiAlias(true);
        paint.setStyle(SkPaint::kStroke_Style);
        const SkAlpha fade = 0x33;

        // draw path in hairline
        paint.setColor(gPathColor); paint.setAlpha(fade);
        canvas->drawPath(path, paint);

        // draw clips in hair line
        paint.setColor(gClipAColor); paint.setAlpha(fade);
        canvas->drawPath(clipA, paint);
        paint.setColor(gClipBColor); paint.setAlpha(fade);
        canvas->drawPath(clipB, paint);
    }

    bool fDoAAClip;
    bool fDoSaveLayer;
    bool fInvertDraw;

    using INHERITED = GM;
};

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

DEF_GM(return new ComplexClipGM(false, false, false);)
DEF_GM(return new ComplexClipGM(false, false, true);)
DEF_GM(return new ComplexClipGM(false, true, false);)
DEF_GM(return new ComplexClipGM(false, true, true);)
DEF_GM(return new ComplexClipGM(true, false, false);)
DEF_GM(return new ComplexClipGM(true, false, true);)
DEF_GM(return new ComplexClipGM(true, true, false);)
DEF_GM(return new ComplexClipGM(true, true, true);)
}  // namespace skiagm

DEF_SIMPLE_GM(clip_shader, canvas, 840, 650) {
    auto img = GetResourceAsImage("images/yellow_rose.png");
    auto sh = img->makeShader(SkSamplingOptions());

    SkRect r = SkRect::MakeIWH(img->width(), img->height());
    SkPaint p;

    canvas->translate(10, 10);
    canvas->drawImage(img, 0, 0);

    canvas->save();
    canvas->translate(img->width() + 10, 0);
    canvas->clipShader(sh, SkClipOp::kIntersect);
    p.setColor(SK_ColorRED);
    canvas->drawRect(r, p);
    canvas->restore();

    canvas->save();
    canvas->translate(0, img->height() + 10);
    canvas->clipShader(sh, SkClipOp::kDifference);
    p.setColor(SK_ColorGREEN);
    canvas->drawRect(r, p);
    canvas->restore();

    canvas->save();
    canvas->translate(img->width() + 10, img->height() + 10);
    canvas->clipShader(sh, SkClipOp::kIntersect);
    canvas->save();
    SkMatrix lm = SkMatrix::Scale(1.0f/5, 1.0f/5);
    canvas->clipShader(img->makeShader(SkTileMode::kRepeat, SkTileMode::kRepeat,
                                       SkSamplingOptions(), lm));
    canvas->drawImage(img, 0, 0);

    canvas->restore();
    canvas->restore();
}

DEF_SIMPLE_GM(clip_shader_layer, canvas, 430, 320) {
    auto img = GetResourceAsImage("images/yellow_rose.png");
    auto sh = img->makeShader(SkSamplingOptions());

    SkRect r = SkRect::MakeIWH(img->width(), img->height());

    canvas->translate(10, 10);
    // now add the cool clip
    canvas->clipRect(r);
    canvas->clipShader(sh);
    // now draw a layer with the same image, and watch it get restored w/ the clip
    canvas->saveLayer(&r, nullptr);
    canvas->drawColor(0xFFFF0000);
    canvas->restore();
}

DEF_SIMPLE_GM(clip_shader_nested, canvas, 256, 256) {
    float w = 64.f;
    float h = 64.f;

    const SkColor gradColors[] = {SK_ColorBLACK, SkColorSetARGB(128, 128, 128, 128)};
    auto s = SkGradientShader::MakeRadial({0.5f * w, 0.5f * h}, 0.1f * w, gradColors, nullptr,
                                            2, SkTileMode::kRepeat, 0, nullptr);

    SkPaint p;

    // A large black rect affected by two gradient clips
    canvas->save();
    canvas->clipShader(s);
    canvas->scale(2.f, 2.f);
    canvas->clipShader(s);
    canvas->drawRect(SkRect::MakeWH(w, h), p);
    canvas->restore();

    canvas->translate(0.f, 2.f * h);

    // A small red rect, with no clipping
    canvas->save();
    p.setColor(SK_ColorRED);
    canvas->drawRect(SkRect::MakeWH(w, h), p);
    canvas->restore();
}

namespace {

// Where is canvas->concat(persp) called relative to the clipShader calls.
enum ConcatPerspective {
    kConcatBeforeClips,
    kConcatAfterClips,
    kConcatBetweenClips
};
// Order in which clipShader(image) and clipShader(gradient) are specified; only meaningful
// when CanvasPerspective is kConcatBetweenClips.
enum ClipOrder {
    kClipImageFirst,
    kClipGradientFirst,

    kDoesntMatter = kClipImageFirst
};
// Which shaders have perspective applied as a local matrix.
enum LocalMatrix {
    kNoLocalMat,
    kImageWithLocalMat,
    kGradientWithLocalMat,
    kBothWithLocalMat
};
struct Config {
    ConcatPerspective fConcat;
    ClipOrder         fOrder;
    LocalMatrix       fLM;
};

static void draw_banner(SkCanvas* canvas, Config config) {
    SkString banner;
    banner.append("Persp: ");

    if (config.fConcat == kConcatBeforeClips || config.fLM == kBothWithLocalMat) {
        banner.append("Both Clips");
    } else {
        SkASSERT((config.fConcat == kConcatBetweenClips && config.fLM == kNoLocalMat) ||
                 (config.fConcat == kConcatAfterClips && (config.fLM == kImageWithLocalMat ||
                                                          config.fLM == kGradientWithLocalMat)));
        if ((config.fConcat == kConcatBetweenClips && config.fOrder == kClipImageFirst) ||
            config.fLM == kGradientWithLocalMat) {
            banner.append("Gradient");
        } else {
            SkASSERT(config.fOrder == kClipGradientFirst || config.fLM == kImageWithLocalMat);
            banner.append("Image");
        }
    }
    if (config.fLM != kNoLocalMat) {
        banner.append(" (w/ LM, should equal top row)");
    }

    static const SkFont kFont(ToolUtils::create_portable_typeface(), 12);
    canvas->drawString(banner.c_str(), 20.f, -30.f, kFont, SkPaint());
};

}  // namespace

DEF_SIMPLE_GM(clip_shader_persp, canvas, 1370, 1030) {
    // Each draw has a clipShader(image-shader), a clipShader(gradient-shader), a concat(persp-mat),
    // and each shader may or may not be wrapped with a perspective local matrix.

    // Pairs of configs that should match in appearance where first config doesn't use a local
    // matrix (top row of GM) and the second does (bottom row of GM).
    Config matches[][2] = {
            // Everything has perspective
            {{kConcatBeforeClips,  kDoesntMatter,      kNoLocalMat},
             {kConcatAfterClips,   kDoesntMatter,      kBothWithLocalMat}},
            // Image shader has perspective
            {{kConcatBetweenClips, kClipGradientFirst, kNoLocalMat},
             {kConcatAfterClips,   kDoesntMatter,      kImageWithLocalMat}},
            // Gradient shader has perspective
            {{kConcatBetweenClips, kClipImageFirst,    kNoLocalMat},
             {kConcatAfterClips,   kDoesntMatter,      kGradientWithLocalMat}}
    };

    // The image that is drawn
    auto img = GetResourceAsImage("images/yellow_rose.png");
    // Scale factor always applied to the image shader so that it tiles
    SkMatrix scale = SkMatrix::Scale(1.f / 4.f, 1.f / 4.f);
    // The perspective matrix applied wherever needed
    SkPoint src[4];
    SkRect::Make(img->dimensions()).toQuad(src);
    SkPoint dst[4] = {{0, 80.f},
                      {img->width() + 28.f, -100.f},
                      {img->width() - 28.f, img->height() + 100.f},
                      {0.f, img->height() - 80.f}};
    SkMatrix persp;
    SkAssertResult(persp.setPolyToPoly(src, dst, 4));

    SkMatrix perspScale = SkMatrix::Concat(persp, scale);

    auto drawConfig = [&](Config config) {
        canvas->save();

        draw_banner(canvas, config);

        // Make clipShaders (possibly with local matrices)
        bool gradLM = config.fLM == kGradientWithLocalMat || config.fLM == kBothWithLocalMat;
        const SkColor gradColors[] = {SK_ColorBLACK, SkColorSetARGB(128, 128, 128, 128)};
        auto gradShader = SkGradientShader::MakeRadial({0.5f * img->width(), 0.5f * img->height()},
                                                        0.1f * img->width(), gradColors, nullptr, 2,
                                                        SkTileMode::kRepeat, 0,
                                                        gradLM ? &persp : nullptr);
        bool imageLM = config.fLM == kImageWithLocalMat || config.fLM == kBothWithLocalMat;
        auto imgShader = img->makeShader(SkTileMode::kRepeat, SkTileMode::kRepeat,
                                         SkSamplingOptions(), imageLM ? perspScale : scale);

        // Perspective before any clipShader
        if (config.fConcat == kConcatBeforeClips) {
            canvas->concat(persp);
        }

        // First clipshader
        canvas->clipShader(config.fOrder == kClipImageFirst ? imgShader : gradShader);

        // Perspective between clipShader
        if (config.fConcat == kConcatBetweenClips) {
            canvas->concat(persp);
        }

        // Second clipShader
        canvas->clipShader(config.fOrder == kClipImageFirst ? gradShader : imgShader);

        // Perspective after clipShader
        if (config.fConcat == kConcatAfterClips) {
            canvas->concat(persp);
        }

        // Actual draw and clip boundary are the same for all configs
        canvas->clipIRect(img->bounds());
        canvas->clear(SK_ColorBLACK);
        canvas->drawImage(img, 0, 0);

        canvas->restore();
    };

    SkIRect grid = persp.mapRect(SkRect::Make(img->dimensions())).roundOut();
    grid.fLeft -= 20; // manual adjust to look nicer

    canvas->translate(10.f, 10.f);

    for (size_t i = 0; i < SK_ARRAY_COUNT(matches); ++i) {
        canvas->save();
        canvas->translate(-grid.fLeft, -grid.fTop);
        drawConfig(matches[i][0]);
        canvas->translate(0.f, grid.height());
        drawConfig(matches[i][1]);
        canvas->restore();

        canvas->translate(grid.width(), 0.f);
    }
}

DEF_SIMPLE_GM(clip_shader_difference, canvas, 512, 512) {
    auto image = GetResourceAsImage("images/yellow_rose.png");
    canvas->clear(SK_ColorGRAY);

    SkRect rect = SkRect::MakeWH(256, 256);
    SkMatrix local = SkMatrix::RectToRect(SkRect::MakeWH(image->width(), image->height()),
                                          SkRect::MakeWH(64, 64));
    auto shader = image->makeShader(SkTileMode::kRepeat, SkTileMode::kRepeat,
                                    SkSamplingOptions(), &local);

    SkPaint paint;
    paint.setColor(SK_ColorRED);
    paint.setAntiAlias(true);

    // TL: A rectangle
    {
        canvas->save();
        canvas->translate(0, 0);
        canvas->clipShader(shader, SkClipOp::kDifference);
        canvas->drawRect(rect, paint);
        canvas->restore();
    }
    // TR: A round rectangle
    {
        canvas->save();
        canvas->translate(256, 0);
        canvas->clipShader(shader, SkClipOp::kDifference);
        canvas->drawRRect(SkRRect::MakeRectXY(rect, 64.f, 64.f), paint);
        canvas->restore();
    }
    // BL: A path
    {
        canvas->save();
        canvas->translate(0, 256);
        canvas->clipShader(shader, SkClipOp::kDifference);

        SkPath path;
        path.moveTo(0.f, 128.f);
        path.lineTo(128.f, 256.f);
        path.lineTo(256.f, 128.f);
        path.lineTo(128.f, 0.f);

        SkScalar d = 64.f * SK_ScalarSqrt2;
        path.moveTo(128.f - d, 128.f - d);
        path.lineTo(128.f - d, 128.f + d);
        path.lineTo(128.f + d, 128.f + d);
        path.lineTo(128.f + d, 128.f - d);
        canvas->drawPath(path, paint);
        canvas->restore();
    }
    // BR: Text
    {
        canvas->save();
        canvas->translate(256, 256);
        canvas->clipShader(shader, SkClipOp::kDifference);
        for (int y = 0; y < 4; ++y) {
            canvas->drawString("Hello", 32.f, y * 64.f, SkFont(nullptr, 64.f), paint);
        }
        canvas->restore();
    }
}
