/*
 * 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 <array>
#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);

    static constexpr auto kCaps = std::to_array<SkPaint::Cap>({
            SkPaint::kSquare_Cap,
            SkPaint::kButt_Cap,
            SkPaint::kRound_Cap,
    });

    static constexpr auto kLengths = std::to_array<float>({
            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
