/*
 * Copyright 2018 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include <string>
#include "include/core/SkCanvas.h"
#include "include/core/SkFont.h"
#include "include/core/SkPath.h"
#include "samplecode/Sample.h"
#include "src/core/SkGeometry.h"
#include "tools/timer/TimeUtils.h"

// This draws an animation where every cubic has a cusp, to test drawing a circle
// at the cusp point. Create a unit square. A cubic with its control points
// at the four corners crossing over itself has a cusp.

// Project the unit square through a random affine matrix.
// Chop the cubic in two. One half of the cubic will have a cusp
// (unless it was chopped exactly at the cusp point).

// Running this looks mostly OK, but will occasionally draw something odd.
// The odd parts don't appear related to the cusp code, but are old stroking
// bugs that have not been fixed, yet.

SkMSec start = 0;
SkMSec curTime;
bool first = true;

// Create a path with one or two cubics, where one has a cusp.
static SkPath cusp(const SkPoint P[4], SkPoint PP[7], bool& split, int speed, SkScalar phase) {
    SkPath path;
    path.moveTo(P[0]);
    SkScalar t = (curTime % speed) / SkIntToFloat(speed);
    t += phase;
    if (t > 1) {
        t -= 1;
    }
    if (0 <= t || t >= 1) {
        path.cubicTo(P[1], P[2], P[3]);
        split = false;
    } else {
        SkChopCubicAt(P, PP, t);
        path.cubicTo(PP[1], PP[2], PP[3]);
        path.cubicTo(PP[4], PP[5], PP[6]);
        split = true;
    }
    return path;
}

// Scale the animation counter to a value that oscillates from -scale to +scale.
static SkScalar linearToLoop(int speed, SkScalar phase, SkScalar scale) {
    SkScalar loop;
    SkScalar linear = (curTime % speed) / SkIntToFloat(speed);  // 0 to 1
    linear += phase;
    if (linear > 1) {
        linear -= 1;
    }
    if (linear < .25) {
        loop = linear * 4;     //  0 to .25  ==> 0 to  1
    } else if (linear < .75) { // .25 to .75 ==> 1 to -1
        loop = (.5 - linear) * 4;
    } else  {                  // .75 to 1   ==> -1 to 0
        loop = (linear - 1) * 4;
    }
    return loop * scale;
}

struct data {
    SkIPoint pt[4];
} dat[] = {
// When the animation looks funny, pause, and paste the last part of the stream in stdout here.
// Enable the 1st #if to play the recorded stream backwards.
// Enable the 2nd #if and replace the second 'i = ##' with the value of datCount that shows the bug.
{{{0x43480000,0x43960000},{0x4318b999,0x4321570b},{0x432f999a,0x435a0a3d},{0x43311fff,0x43734cce},}},
{{{0x43480000,0x43960000},{0x431d1ddf,0x4321ae13},{0x4331ddde,0x435c147c},{0x43334001,0x43719997},}},
{{{0x43480000,0x43960000},{0x43218224,0x43220520},{0x43342223,0x435e1eba},{0x43356001,0x436fe666},}},
{{{0x43480000,0x43960000},{0x4325a445,0x43225708},{0x43364444,0x43600a3c},{0x43376001,0x436e4ccc},}},
{{{0x43480000,0x43960000},{0x432a0889,0x4322ae16},{0x43388889,0x4362147b},{0x43398000,0x436c999b},}},
{{{0x43480000,0x43960000},{0x432e6ccd,0x43230523},{0x433acccd,0x43641eba},{0x433ba000,0x436ae66a},}},
{{{0x43480000,0x43960000},{0x43328eef,0x4323570c},{0x433ceeee,0x43660a3c},{0x433da000,0x43694cd0},}},
{{{0x43480000,0x43960000},{0x4336f333,0x4323ae13},{0x433f3333,0x4368147a},{0x433fc000,0x43679998},}},
{{{0x43480000,0x43960000},{0x433b5777,0x43240520},{0x43417777,0x436a1eb9},{0x4341e000,0x4365e668},}},
{{{0x43480000,0x43960000},{0x433f799a,0x4324570c},{0x4343999a,0x436c0a3e},{0x4343e000,0x43644cce},}},
{{{0x43480000,0x43960000},{0x4343ddde,0x4324ae13},{0x4345dddf,0x436e147c},{0x43460000,0x43629996},}},
{{{0x43480000,0x43960000},{0x43484222,0x4325051e},{0x43482222,0x43701eb9},{0x43481fff,0x4360e666},}},
{{{0x43480000,0x43960000},{0x434c6446,0x43255709},{0x434a4444,0x43720a3e},{0x434a2002,0x435f4ccc},}},
{{{0x43480000,0x43960000},{0x4350c888,0x4325ae16},{0x434c8889,0x4374147c},{0x434c3fff,0x435d999a},}},
{{{0x43480000,0x43960000},{0x43552cce,0x43260521},{0x434ecccd,0x43761eb8},{0x434e6001,0x435be669},}},
{{{0x43480000,0x43960000},{0x43594eee,0x4326570c},{0x4350eeef,0x43780a3d},{0x43505fff,0x435a4ccf},}},
{{{0x43480000,0x43960000},{0x435db334,0x4326ae19},{0x43533333,0x437a147c},{0x43528001,0x4358999e},}},
{{{0x43480000,0x43960000},{0x4361d555,0x43270002},{0x43555555,0x437bfffe},{0x43547fff,0x43570004},}},
{{{0x43480000,0x43960000},{0x4366399a,0x4327570c},{0x4357999a,0x437e0a3f},{0x4356a001,0x43554ccd},}},
{{{0x43480000,0x43960000},{0x436a9ddc,0x4327ae12},{0x4359ddde,0x43800a3e},{0x4358bffe,0x43539996},}},
{{{0x43480000,0x43960000},{0x436f0222,0x4328051c},{0x435c2222,0x43810f5c},{0x435ae000,0x4351e664},}},
};

size_t datCount = SK_ARRAY_COUNT(dat);

class CuspView : public Sample {
public:
    CuspView() {}
protected:
    SkString name() override { return SkString("Cusp"); }

    void onDrawContent(SkCanvas* canvas) override {
        SkPaint p;
        p.setAntiAlias(true);
        p.setStyle(SkPaint::kStroke_Style);
        p.setStrokeWidth(20);
    #if 0   // enable to play through the stream above backwards.
        SkPath path;
        int i;
    #if 0  // disable to draw only one problematic cubic
        i = --datCount;
    #else
        i = 14; // index into dat of  problematic cubic
    #endif
        path.moveTo( SkBits2Float(dat[i].pt[0].fX), SkBits2Float(dat[i].pt[0].fY));
        path.cubicTo(SkBits2Float(dat[i].pt[1].fX), SkBits2Float(dat[i].pt[1].fY),
                     SkBits2Float(dat[i].pt[2].fX), SkBits2Float(dat[i].pt[2].fY),
                     SkBits2Float(dat[i].pt[3].fX), SkBits2Float(dat[i].pt[3].fY));
    #else
        SkPath path;
        SkRect rect;
        rect.setWH(100, 100);
        SkMatrix matrix;
        SkScalar vals[9];
        vals[0] = linearToLoop(3000, 0, 1);
        vals[1] = linearToLoop(4000, .25, 1.25);
        vals[2] = 200;
        vals[3] = linearToLoop(5000, .5, 1.5);
        vals[4] = linearToLoop(7000, .75, 1.75);
        vals[5] = 300;
        vals[6] = 0;
        vals[7] = 0;
        vals[8] = 1;
        matrix.set9(vals);
        SkPoint pts[4], pp[7];
        matrix.mapRectToQuad(pts, rect);
        std::swap(pts[1], pts[2]);
        bool split;
        path = cusp(pts, pp, split, 8000, .125);
        auto debugOutCubic = [](const SkPoint* pts) {
            return false; // comment out to capture stream of cusp'd cubics in stdout
            SkDebugf("{{");
            for (int i = 0; i < 4; ++i) {
                SkDebugf("{0x%08x,0x%08x},", SkFloat2Bits(pts[i].fX), SkFloat2Bits(pts[i].fY));
            }
            SkDebugf("}},\n");
        };
        if (split) {
            debugOutCubic(&pp[0]);
            debugOutCubic(&pp[4]);
        } else {
            debugOutCubic(&pts[0]);
        }
    #endif
        canvas->drawPath(path, p);
        // draw time to make it easier to guess when the bad cubic was drawn
        std::string timeStr = std::to_string((float) (curTime - start) / 1000.f);
        canvas->drawSimpleText(timeStr.c_str(), timeStr.size(), SkTextEncoding::kUTF8, 20, 20, SkFont(), SkPaint());
        SkDebugf("");
    }

    bool onAnimate(double nanos) override {
        curTime = TimeUtils::NanosToMSec(nanos);
        if (!start) {
            start = curTime;
        }
        return true;
    }

private:

    typedef Sample INHERITED;
};

DEF_SAMPLE( return new CuspView(); )
