/*
 * 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.h"
#include "SkAnimTimer.h"
#include "SkPath.h"
#include "SkDashPathEffect.h"

int dash1[] = { 1, 1 };
int dash2[] = { 1, 3 };
int dash3[] = { 1, 1, 3, 3 };
int dash4[] = { 1, 3, 2, 4 };

struct DashExample {
    int* pattern;
    int length;
} dashExamples[] = {
    { dash1, SK_ARRAY_COUNT(dash1) },
    { dash2, SK_ARRAY_COUNT(dash2) },
    { dash3, SK_ARRAY_COUNT(dash3) },
    { dash4, SK_ARRAY_COUNT(dash4) }
};


class DashCircleGM : public skiagm::GM {
public:
    DashCircleGM() : fRotation(0) { }

protected:
    SkString onShortName() override { return SkString("dashcircle"); }

    SkISize onISize() override { return SkISize::Make(900, 1200); }

    void onDraw(SkCanvas* canvas) override {
        SkPaint refPaint;
        refPaint.setAntiAlias(true);
        refPaint.setColor(0xFFbf3f7f);
        refPaint.setStyle(SkPaint::kStroke_Style);
        refPaint.setStrokeWidth(1);
        const SkScalar radius = 125;
        SkRect oval = SkRect::MakeLTRB(-radius - 20, -radius - 20, radius + 20, radius + 20);
        SkPath circle;
        circle.addCircle(0, 0, radius);
        SkScalar circumference = radius * SK_ScalarPI * 2;
        int wedges[] = { 6, 12, 36 };
        canvas->translate(radius+20, radius+20);
        for (int wedge : wedges) {
            SkScalar arcLength = 360.f / wedge;
            canvas->save();
            for (const DashExample& dashExample : dashExamples) {
                SkPath refPath;
                int dashUnits = 0;
                for (int index = 0; index < dashExample.length; ++index) {
                    dashUnits += dashExample.pattern[index];
                }
                SkScalar unitLength = arcLength / dashUnits;
                SkScalar angle = 0;
                for (int index = 0; index < wedge; ++index) {
                    for (int i2 = 0; i2 < dashExample.length; i2 += 2) {
                        SkScalar span = dashExample.pattern[i2] * unitLength;
                        refPath.moveTo(0, 0);
                        refPath.arcTo(oval, angle, span, false);
                        refPath.close();
                        angle += span + (dashExample.pattern[i2 + 1]) * unitLength;
                    }
                }
                canvas->save();
                canvas->rotate(fRotation);
                canvas->drawPath(refPath, refPaint);
                canvas->restore();
                SkPaint p;
                p.setAntiAlias(true);
                p.setStyle(SkPaint::kStroke_Style);
                p.setStrokeWidth(10);
                SkScalar intervals[4];
                int intervalCount = dashExample.length;
                SkScalar dashLength = circumference / wedge / dashUnits;
                for (int index = 0; index < dashExample.length; ++index) {
                    intervals[index] = dashExample.pattern[index] * dashLength;
                }
                p.setPathEffect(SkDashPathEffect::Make(intervals, intervalCount, 0));
                canvas->save();
                canvas->rotate(fRotation);
                canvas->drawPath(circle, p);
                canvas->restore();
                canvas->translate(0, radius * 2 + 50);
            }
            canvas->restore();
            canvas->translate(radius * 2 + 50, 0);
        }
    }

    bool onAnimate(const SkAnimTimer& timer) override {
        constexpr SkScalar kDesiredDurationSecs = 100.0f;

        fRotation = timer.scaled(360.0f/kDesiredDurationSecs, 360.0f);
        return true;
    }

private:
    SkScalar fRotation;

    typedef GM INHERITED;
};

DEF_GM(return new DashCircleGM; )

class DashCircle2GM : public skiagm::GM {
public:
    DashCircle2GM() {}

protected:
    SkString onShortName() override { return SkString("dashcircle2"); }

    SkISize onISize() override { return SkISize::Make(635, 900); }

    void onDraw(SkCanvas* canvas) override {
        // These intervals are defined relative to tau.
        static constexpr SkScalar kIntervals[][2]{
                {0.333f, 0.333f},
                {0.015f, 0.015f},
                {0.01f , 0.09f },
                {0.097f, 0.003f},
                {0.02f , 0.04f },
                {0.1f  , 0.2f  },
                {0.25f , 0.25f },
                {0.6f  , 0.7f  }, // adds to > 1
                {1.2f  , 0.8f  }, // on is > 1
                {0.1f  , 1.1f  }, // off is > 1*/
        };

        static constexpr int kN = SK_ARRAY_COUNT(kIntervals);
        static constexpr SkScalar kRadius = 20.f;
        static constexpr SkScalar kStrokeWidth = 15.f;
        static constexpr SkScalar kPad = 5.f;
        static constexpr SkRect kCircle = {-kRadius, -kRadius, kRadius, kRadius};

        static constexpr SkScalar kThinRadius = kRadius * 1.5;
        static constexpr SkRect kThinCircle = {-kThinRadius, -kThinRadius,
                                                kThinRadius,  kThinRadius};
        static constexpr SkScalar kThinStrokeWidth = 0.4f;

        sk_sp<SkPathEffect> deffects[SK_ARRAY_COUNT(kIntervals)];
        sk_sp<SkPathEffect> thinDEffects[SK_ARRAY_COUNT(kIntervals)];
        for (int i = 0; i < kN; ++i) {
            static constexpr SkScalar kTau = 2 * SK_ScalarPI;
            static constexpr SkScalar kCircumference = kRadius * kTau;
            SkScalar scaledIntervals[2] = {kCircumference * kIntervals[i][0],
                                           kCircumference * kIntervals[i][1]};
            deffects[i] = SkDashPathEffect::Make(
                    scaledIntervals, 2, kCircumference * fPhaseDegrees * kTau / 360.f);
            static constexpr SkScalar kThinCircumference = kThinRadius * kTau;
            scaledIntervals[0] = kThinCircumference * kIntervals[i][0];
            scaledIntervals[1] = kThinCircumference * kIntervals[i][1];
            thinDEffects[i] = SkDashPathEffect::Make(
                    scaledIntervals, 2, kThinCircumference * fPhaseDegrees * kTau / 360.f);
        }

        SkMatrix rotate;
        rotate.setRotate(25.f);
        static const SkMatrix kMatrices[]{
                SkMatrix::I(),
                SkMatrix::MakeScale(1.2f),
                SkMatrix::MakeAll(1, 0, 0, 0, -1, 0, 0, 0, 1),  // y flipper
                SkMatrix::MakeAll(-1, 0, 0, 0, 1, 0, 0, 0, 1),  // x flipper
                SkMatrix::MakeScale(0.7f),
                rotate,
                SkMatrix::Concat(
                        SkMatrix::Concat(SkMatrix::MakeAll(-1, 0, 0, 0, 1, 0, 0, 0, 1), rotate),
                        rotate)
        };

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

        // Compute the union of bounds of all of our test cases.
        SkRect bounds = SkRect::MakeEmpty();
        static const SkRect kBounds = kThinCircle.makeOutset(kThinStrokeWidth / 2.f,
                                                             kThinStrokeWidth / 2.f);
        for (const auto& m : kMatrices) {
            SkRect devBounds;
            m.mapRect(&devBounds, kBounds);
            bounds.join(devBounds);
        }

        canvas->save();
        canvas->translate(-bounds.fLeft + kPad, -bounds.fTop + kPad);
        for (size_t i = 0; i < SK_ARRAY_COUNT(deffects); ++i) {
            canvas->save();
            for (const auto& m : kMatrices) {
                canvas->save();
                canvas->concat(m);

                paint.setPathEffect(deffects[i]);
                paint.setStrokeWidth(kStrokeWidth);
                canvas->drawOval(kCircle, paint);

                paint.setPathEffect(thinDEffects[i]);
                paint.setStrokeWidth(kThinStrokeWidth);
                canvas->drawOval(kThinCircle, paint);

                canvas->restore();
                canvas->translate(bounds.width() + kPad, 0);
            }
            canvas->restore();
            canvas->translate(0, bounds.height() + kPad);
        }
        canvas->restore();
    }

protected:
    bool onAnimate(const SkAnimTimer& timer) override {
        fPhaseDegrees = timer.secs();
        return true;
    }

    // Init with a non-zero phase for when run as a non-animating GM.
    SkScalar fPhaseDegrees = 12.f;
};

DEF_GM(return new DashCircle2GM;)

DEF_SIMPLE_GM(maddash, canvas, 1600, 1600) {
    canvas->drawRect({0, 0, 1600, 1600}, SkPaint());
    SkPaint p;
    p.setColor(SK_ColorRED);
    p.setAntiAlias(true);
    p.setStyle(SkPaint::kStroke_Style);
    p.setStrokeWidth(380);

    SkScalar intvls[] = { 2.5, 10 /* 1200 */ };
    p.setPathEffect(SkDashPathEffect::Make(intvls, 2, 0));

    canvas->drawCircle(400, 400, 200, p);

    SkPath path;
    path.moveTo(800, 400);
    path.quadTo(1000, 400, 1000, 600);
    path.quadTo(1000, 800, 800, 800);
    path.quadTo(600, 800, 600, 600);
    path.quadTo(600, 400, 800, 400);
    path.close();
    canvas->translate(350, 150);
    p.setStrokeWidth(320);
    canvas->drawPath(path, p);

    path.reset();
    path.moveTo(800, 400);
    path.cubicTo(900, 400, 1000, 500, 1000, 600);
    path.cubicTo(1000, 700, 900, 800, 800, 800);
    path.cubicTo(700, 800, 600, 700, 600, 600);
    path.cubicTo(600, 500, 700, 400, 800, 400);
    path.close();
    canvas->translate(-550, 500);
    p.setStrokeWidth(300);
    canvas->drawPath(path, p);
}
