/*
 * Copyright 2016 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/SkBlurTypes.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkColor.h"
#include "include/core/SkMaskFilter.h"
#include "include/core/SkMatrix.h"
#include "include/core/SkPaint.h"
#include "include/core/SkPath.h"
#include "include/core/SkPathEffect.h"
#include "include/core/SkPathUtils.h"
#include "include/core/SkPoint.h"
#include "include/core/SkRect.h"
#include "include/core/SkScalar.h"
#include "include/core/SkShader.h"
#include "include/core/SkSize.h"
#include "include/core/SkString.h"
#include "include/core/SkTileMode.h"
#include "include/core/SkTypes.h"
#include "include/effects/SkDashPathEffect.h"
#include "include/effects/SkGradient.h"
#include "include/private/SkTArray.h"
#include "include/private/SkTemplates.h"
#include "tools/ToolUtils.h"

#include <initializer_list>

using namespace skia_private;

constexpr int kNumColumns = 6;
constexpr int kNumRows = 8;
constexpr int kRadius = 40;  // radius of the snowflake
constexpr int kPad = 5;      // padding on both sides of the snowflake
constexpr int kNumSpokes = 6;
constexpr SkScalar kStrokeWidth = 5.0f;

static void draw_line(SkCanvas* canvas, const SkPoint& p0, const SkPoint& p1,
                      const SkPaint& paint, bool useDrawPath) {
    if (useDrawPath) {
        canvas->drawPath(SkPath::Line(p0, p1), paint);
    } else {
        canvas->drawLine(p0, p1, paint);
    }
}

static void draw_fins(SkCanvas* canvas, const SkPoint& offset, float angle, const SkPaint& paint,
                      bool useDrawPath) {
    SkScalar cos, sin;

    // first fin
    sin = SkScalarSin(angle + (SK_ScalarPI/4));
    cos = SkScalarCos(angle + (SK_ScalarPI/4));
    sin *= kRadius / 2.0f;
    cos *= kRadius / 2.0f;

    draw_line(canvas, offset, offset + SkPoint{cos, sin}, paint, useDrawPath);

    // second fin
    sin = SkScalarSin(angle - (SK_ScalarPI/4));
    cos = SkScalarCos(angle - (SK_ScalarPI/4));
    sin *= kRadius / 2.0f;
    cos *= kRadius / 2.0f;

    draw_line(canvas, offset, offset + SkPoint{cos, sin}, paint, useDrawPath);
}

// draw a snowflake centered at the origin
static void draw_snowflake(SkCanvas* canvas, const SkPaint& paint, bool useDrawPath) {

    canvas->clipRect(SkRect::MakeLTRB(-kRadius-kPad, -kRadius-kPad, kRadius+kPad, kRadius+kPad));

    SkScalar sin, cos, angle = 0.0f;
    for (int i = 0; i < kNumSpokes/2; ++i, angle += SK_ScalarPI/(kNumSpokes/2)) {
        sin = SkScalarSin(angle);
        cos = SkScalarCos(angle);
        sin *= kRadius;
        cos *= kRadius;

        // main spoke
        draw_line(canvas, {-cos, -sin}, {cos, sin}, paint, useDrawPath);

        // fins on positive side
        const SkPoint posOffset = SkPoint::Make(0.5f * cos, 0.5f * sin);
        draw_fins(canvas, posOffset, angle, paint, useDrawPath);

        // fins on negative side
        const SkPoint negOffset = SkPoint::Make(-0.5f * cos, -0.5f * sin);
        draw_fins(canvas, negOffset, angle+SK_ScalarPI, paint, useDrawPath);
    }
}

static void draw_row(SkCanvas* canvas, const SkPaint& paint, const SkMatrix& localMatrix,
                     bool useDrawPath) {
    canvas->translate(kRadius+kPad, 0.0f);

    for (auto cap : { SkPaint::kButt_Cap, SkPaint::kRound_Cap, SkPaint::kSquare_Cap }) {
        for (auto isAA : { true, false }) {
            SkPaint tmp(paint);
            tmp.setStrokeWidth(kStrokeWidth);
            tmp.setStyle(SkPaint::kStroke_Style);
            tmp.setStrokeCap(cap);
            tmp.setAntiAlias(isAA);

            int saveCount = canvas->save();
            canvas->concat(localMatrix);
            draw_snowflake(canvas, tmp, useDrawPath);
            canvas->restoreToCount(saveCount);

            canvas->translate(2*(kRadius+kPad), 0.0f);
        }
    }
}

namespace skiagm {

// This GM exercises the special case of a stroked lines.
// Various shaders are applied to ensure the coordinate spaces work out right.
class StrokedLinesGM : public GM {
public:
    StrokedLinesGM(bool useDrawPath) : fUseDrawPath(useDrawPath) {
        this->setBGColor(ToolUtils::color_to_565(0xFF1A65D7));
    }

protected:
    SkString getName() const override {
        // To preserve history, useDrawPath==true has no suffix.
        SkString name{"strokedlines"};
        if (!fUseDrawPath) {
            name.append("_drawPoints");
        }
        return name;
    }

    SkISize getISize() override {
        return SkISize::Make(kNumColumns * (2*kRadius+2*kPad), kNumRows * (2*kRadius+2*kPad));
    }

    void onOnceBeforeDraw() override {
        // paints
        {
            // basic white
            SkPaint p;
            p.setColor(SK_ColorWHITE);
            fPaints.push_back(p);
        }
        {
            // gradient
            SkColor4f colors[] = { SkColors::kRed, SkColors::kGreen };
            SkPoint pts[] = { {-kRadius-kPad, -kRadius-kPad }, { kRadius+kPad, kRadius+kPad } };

            SkPaint p;
            p.setShader(SkShaders::LinearGradient(pts, {{colors, {}, SkTileMode::kClamp}, {}}));

            fPaints.push_back(p);
        }
        {
            // dashing
            SkScalar intervals[] = { kStrokeWidth, kStrokeWidth };
            SkPaint p;
            p.setColor(SK_ColorWHITE);
            p.setPathEffect(SkDashPathEffect::Make(intervals, kStrokeWidth));

            fPaints.push_back(p);
        }
        {
            // Bitmap shader
            SkBitmap bm;
            bm.allocN32Pixels(2, 2);
            *bm.getAddr32(0, 0) = *bm.getAddr32(1, 1) = 0xFFFFFFFF;
            *bm.getAddr32(1, 0) = *bm.getAddr32(0, 1) = 0x0;

            SkMatrix m;
            m.setRotate(12.0f);
            m.preScale(3.0f, 3.0f);

            SkPaint p;
            p.setShader(bm.makeShader(SkTileMode::kRepeat, SkTileMode::kRepeat,
                                      SkSamplingOptions(), m));
            fPaints.push_back(p);
        }
        {
            // blur
            SkPaint p;
            p.setColor(SK_ColorWHITE);
            p.setMaskFilter(SkMaskFilter::MakeBlur(kOuter_SkBlurStyle, 3.0f));
            fPaints.push_back(p);
        }

        // matrices
        {
            // rotation
            SkMatrix m;
            m.setRotate(12.0f);

            fMatrices.push_back(m);
        }
        {
            // skew
            SkMatrix m;
            m.setSkew(0.3f, 0.5f);

            fMatrices.push_back(m);
        }
        {
            // perspective
            SkMatrix m;
            m.reset();
            m.setPerspX(-SK_Scalar1 / 300);
            m.setPerspY(SK_Scalar1 / 300);

            fMatrices.push_back(m);
        }

        SkASSERT(kNumRows == fPaints.size() + fMatrices.size());
    }

    void onDraw(SkCanvas* canvas) override {
        canvas->translate(0, kRadius+kPad);

        for (int i = 0; i < fPaints.size(); ++i) {
            int saveCount = canvas->save();
            draw_row(canvas, fPaints[i], SkMatrix::I(), fUseDrawPath);
            canvas->restoreToCount(saveCount);

            canvas->translate(0, 2*(kRadius+kPad));
        }

        for (int i = 0; i < fMatrices.size(); ++i) {
            int saveCount = canvas->save();
            draw_row(canvas, fPaints[0], fMatrices[i], fUseDrawPath);
            canvas->restoreToCount(saveCount);

            canvas->translate(0, 2*(kRadius+kPad));
        }
    }

private:
    TArray<SkPaint> fPaints;
    TArray<SkMatrix> fMatrices;

    const bool fUseDrawPath;

    using INHERITED = GM;
};

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

DEF_GM(return new StrokedLinesGM(true);)
DEF_GM(return new StrokedLinesGM(false);)

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

static constexpr float kStrokeWidth = 20.f;

static void draw_path(SkCanvas* canvas, const SkPoint& p0, const SkPoint& p1, SkPaint::Cap cap) {
    // Add a gradient *not* aligned with the line's points to show local coords are tracked properly
    constexpr SkRect kRect {-kStrokeWidth, -kStrokeWidth, 2*kStrokeWidth, 4*kStrokeWidth};
    constexpr SkPoint kPts[] {{kRect.fLeft, kRect.fTop}, {kRect.fRight, kRect.fBottom}};
    constexpr SkColor4f kColors[] {SkColors::kRed, SkColors::kGreen, SkColors::kBlue};
    constexpr SkScalar kStops[] {0.f, 0.75f, 1.f};
    sk_sp<SkShader> shader = SkShaders::LinearGradient(kPts,
                                                       {{kColors, kStops, SkTileMode::kClamp}, {}});

    SkPaint paint;
    paint.setAntiAlias(true);
    paint.setStyle(SkPaint::kStroke_Style);

    paint.setShader(std::move(shader));
    paint.setStrokeWidth(kStrokeWidth);
    paint.setStrokeCap(cap);
    canvas->drawLine(p0, p1, paint);

    // Show outline and control points
    SkPath fillPath = skpathutils::FillPathWithPaint(SkPath::Line(p0, p1), paint);

    paint.setStyle(SkPaint::kStroke_Style);
    paint.setStrokeWidth(0);
    paint.setShader(nullptr);
    paint.setColor(SK_ColorRED);
    canvas->drawPath(fillPath, paint);

    paint.setStrokeWidth(3);
    paint.setStrokeCap(SkPaint::kSquare_Cap);
    canvas->drawPoints(SkCanvas::kPoints_PointMode, fillPath.points(), paint);
}

DEF_SIMPLE_GM(strokedline_caps, canvas, 1400, 740) {
    canvas->translate(kStrokeWidth*3/2, kStrokeWidth*3/2);

    constexpr SkPaint::Cap kCaps[] = {
        SkPaint::kSquare_Cap, SkPaint::kButt_Cap, SkPaint::kRound_Cap
    };

    constexpr float kLengths[] = {
        4*kStrokeWidth, kStrokeWidth, kStrokeWidth/2, kStrokeWidth/4
    };

    for (size_t i = 0; i < std::size(kCaps); ++i) {
        SkAutoCanvasRestore acr(canvas, true);

        auto drawLine = [&](float x0, float y0, float x1, float y1) {
            draw_path(canvas, {x0, y0}, {x1, y1}, kCaps[i]);
            canvas->translate(std::max(x0, x1) + 2 * kStrokeWidth, 0);
        };

        for (size_t j = 0; j < std::size(kLengths); ++j) {
            float l = kLengths[j];

            drawLine(0.f, 0.f, l, l);
            drawLine(l, l, 0.f, 0.f);
            drawLine(l/2, 0, l/2, l);
            drawLine(0, l/2, l, l/2);
        }

        drawLine(kStrokeWidth/2, kStrokeWidth/2, kStrokeWidth/2, kStrokeWidth/2);

        acr.restore();
        canvas->translate(0, kLengths[0] + 2 * kStrokeWidth);
    }
}

}  // namespace skiagm
