/*
 * Copyright 2012 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/SkColor.h"
#include "include/core/SkPaint.h"
#include "include/core/SkPath.h"
#include "include/core/SkPathEffect.h"
#include "include/core/SkScalar.h"
#include "include/core/SkSize.h"
#include "include/core/SkString.h"
#include "include/core/SkTypes.h"
#include "include/effects/SkDashPathEffect.h"
#include "include/effects/SkTrimPathEffect.h"
#include "include/private/SkTArray.h"
#include "include/utils/SkParsePath.h"
#include "tools/timer/TimeUtils.h"

#include <math.h>
#include <utility>

/*
 *  Inspired by http://code.google.com/p/chromium/issues/detail?id=112145
 */
static void flower(SkCanvas* canvas, const SkPath& path, SkScalar intervals[2],
                   SkPaint::Join join) {
    SkPaint paint;
    paint.setAntiAlias(true);
    paint.setStroke(true);
    paint.setStrokeJoin(join);
    paint.setStrokeWidth(42);
    canvas->drawPath(path, paint);

    paint.setColor(SK_ColorRED);
    paint.setStrokeWidth(21);
    paint.setPathEffect(SkDashPathEffect::Make(intervals, 2, 0));
    canvas->drawPath(path, paint);

    paint.setColor(SK_ColorGREEN);
    paint.setPathEffect(nullptr);
    paint.setStrokeWidth(0);
    canvas->drawPath(path, paint);
}

DEF_SIMPLE_GM(dashcubics, canvas, 865, 750) {
        SkPath path;
        const char* d = "M 337,98 C 250,141 250,212 250,212 C 250,212 250,212 250,212"
        "C 250,212 250,212 250,212 C 250,212 250,141 163,98 C 156,195 217,231 217,231"
        "C 217,231 217,231 217,231 C 217,231 217,231 217,231 C 217,231 156,195 75,250"
        "C 156,305 217,269 217,269 C 217,269 217,269 217,269 C 217,269 217,269 217,269"
        "C 217,269 156,305 163,402 C 250,359 250,288 250,288 C 250,288 250,288 250,288"
        "C 250,288 250,288 250,288 C 250,288 250,359 338,402 C 345,305 283,269 283,269"
        "C 283,269 283,269 283,269 C 283,269 283,269 283,269 C 283,269 345,305 425,250"
        "C 344,195 283,231 283,231 C 283,231 283,231 283,231 C 283,231 283,231 283,231"
        "C 283,231 344,195 338,98";

        SkParsePath::FromSVGString(d, &path);
            canvas->translate(-35.f, -55.f);
        for (int x = 0; x < 2; ++x) {
            for (int y = 0; y < 2; ++y) {
                canvas->save();
                canvas->translate(x * 430.f, y * 355.f);
                SkScalar intervals[] = { 5 + (x ? 0 : 0.0001f + 0.0001f), 10 };
                flower(canvas, path, intervals, y ? SkPaint::kDefault_Join : SkPaint::kRound_Join);
                canvas->restore();
            }
        }
}

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

    void onOnceBeforeDraw() override {
        SkAssertResult(SkParsePath::FromSVGString(
            "M   0,100 C  10, 50 190, 50 200,100"
            "M 200,100 C 210,150 390,150 400,100"
            "M 400,100 C 390, 50 210, 50 200,100"
            "M 200,100 C 190,150  10,150   0,100",
            &fPaths.push_back()));

        SkAssertResult(SkParsePath::FromSVGString(
            "M   0, 75 L 200, 75"
            "M 200, 91 L 200, 91"
            "M 200,108 L 200,108"
            "M 200,125 L 400,125",
            &fPaths.push_back()));

        SkAssertResult(SkParsePath::FromSVGString(
            "M   0,100 L  50, 50"
            "M  50, 50 L 150,150"
            "M 150,150 L 250, 50"
            "M 250, 50 L 350,150"
            "M 350,150 L 400,100",
            &fPaths.push_back()));

    }

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

    SkISize onISize() override {
        return SkISize::Make(1400, 1000);
    }

    void onDraw(SkCanvas* canvas) override {
        static constexpr SkSize kCellSize = { 440, 150 };
        static constexpr SkScalar kOffsets[][2] = {
            { -0.33f, -0.66f },
            {  0    ,  1    },
            {  0    ,  0.25f},
            {  0.25f,  0.75f},
            {  0.75f,  1    },
            {  1    ,  0.75f},
        };

        SkPaint hairlinePaint;
        hairlinePaint.setAntiAlias(true);
        hairlinePaint.setStroke(true);
        hairlinePaint.setStrokeCap(SkPaint::kRound_Cap);
        hairlinePaint.setStrokeWidth(2);
        SkPaint normalPaint = hairlinePaint;
        normalPaint.setStrokeWidth(10);
        normalPaint.setColor(0x8000ff00);
        SkPaint invertedPaint = normalPaint;
        invertedPaint.setColor(0x80ff0000);

        for (const auto& offset : kOffsets) {
            auto start = offset[0] + fOffset,
                 stop  = offset[1] + fOffset;

            auto normalMode   = SkTrimPathEffect::Mode::kNormal,
                 invertedMode = SkTrimPathEffect::Mode::kInverted;
            if (fOffset) {
                start -= SkScalarFloorToScalar(start);
                stop  -= SkScalarFloorToScalar(stop);
                if (start > stop) {
                    using std::swap;
                    swap(start, stop);
                    swap(normalMode, invertedMode);
                }
            }

            normalPaint.setPathEffect(SkTrimPathEffect::Make(start, stop, normalMode));
            invertedPaint.setPathEffect(SkTrimPathEffect::Make(start, stop, invertedMode));

            {
                SkAutoCanvasRestore acr(canvas, true);
                for (const auto& path : fPaths) {
                    canvas->drawPath(path, normalPaint);
                    canvas->drawPath(path, invertedPaint);
                    canvas->drawPath(path, hairlinePaint);
                    canvas->translate(kCellSize.width(), 0);
                }
            }

            canvas->translate(0, kCellSize.height());
        }
    }

    bool onAnimate(double nanos) override {
        fOffset = TimeUtils::NanosToMSec(nanos) / 2000.0f;
        fOffset -= floorf(fOffset);
        return true;
    }

private:
    SkTArray<SkPath> fPaths;
    SkScalar         fOffset = 0;

    using INHERITED = skiagm::GM;
};
DEF_GM(return new TrimGM;)

