/*
 * Copyright 2011 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/SkMatrix.h"
#include "include/core/SkPaint.h"
#include "include/core/SkPathBuilder.h"
#include "include/core/SkRRect.h"
#include "include/core/SkRect.h"
#include "include/core/SkScalar.h"
#include "include/core/SkSize.h"
#include "include/core/SkString.h"
#include "include/core/SkTypes.h"
#include "include/private/base/SkTArray.h"
#include "src/base/SkRandom.h"

using namespace skia_private;

namespace {

class SkDoOnce {
public:
    SkDoOnce() { fDidOnce = false; }
    // Make noncopyable
    SkDoOnce(SkDoOnce&) = delete;
    SkDoOnce& operator=(SkDoOnce&) = delete;

    bool needToDo() const { return !fDidOnce; }
    bool alreadyDone() const { return fDidOnce; }
    void accomplished() {
        SkASSERT(!fDidOnce);
        fDidOnce = true;
    }

private:
    bool fDidOnce;
};

class ConvexPathsGM : public skiagm::GM {
    SkDoOnce fOnce;

    void onOnceBeforeDraw() override { this->setBGColor(0xFF000000); }

    SkString getName() const override { return SkString("convexpaths"); }

    SkISize getISize() override { return {1200, 1100}; }

    void makePaths() {
        if (fOnce.alreadyDone()) {
            return;
        }
        fOnce.accomplished();

        SkPathBuilder b;
        fPaths.push_back(b.moveTo(0, 0)
                          .quadTo(50, 100, 0, 100)
                          .lineTo(0, 0)
                          .detach());

        fPaths.push_back(b.moveTo(0, 50)
                          .quadTo(50, 0, 100, 50)
                          .quadTo(50, 100, 0, 50)
                          .detach());

        fPaths.push_back(SkPath::Rect({0, 0, 100, 100}, SkPathDirection::kCW));
        fPaths.push_back(SkPath::Rect({0, 0, 100, 100}, SkPathDirection::kCCW));
        fPaths.push_back(SkPath::Circle(50, 50, 50, SkPathDirection::kCW));
        fPaths.push_back(SkPath::Oval(SkRect::MakeXYWH(0, 0, 50, 100), SkPathDirection::kCW));
        fPaths.push_back(SkPath::Oval(SkRect::MakeXYWH(0, 0, 100, 5), SkPathDirection::kCCW));
        fPaths.push_back(SkPath::Oval(SkRect::MakeXYWH(0, 0, 1, 100), SkPathDirection::kCCW));
        fPaths.push_back(SkPath::RRect(SkRRect::MakeRectXY({0, 0, 100, 100}, 40, 20),
                                       SkPathDirection::kCW));

        // large number of points
        static constexpr int kLength = 100;
        static constexpr int kPtsPerSide = (1 << 12);

        b.moveTo(0, 0);
        for (int i = 1; i < kPtsPerSide; ++i) { // skip the first point due to moveTo.
            b.lineTo(kLength * SkIntToScalar(i) / kPtsPerSide, 0);
        }
        for (int i = 0; i < kPtsPerSide; ++i) {
            b.lineTo(kLength, kLength * SkIntToScalar(i) / kPtsPerSide);
        }
        for (int i = kPtsPerSide; i > 0; --i) {
            b.lineTo(kLength * SkIntToScalar(i) / kPtsPerSide, kLength);
        }
        for (int i = kPtsPerSide; i > 0; --i) {
            b.lineTo(0, kLength * SkIntToScalar(i) / kPtsPerSide);
        }
        fPaths.push_back(b.detach());

        // shallow diagonals
        fPaths.push_back(SkPath::Polygon({{{0,0}, {100,1}, {98,100}, {3,96}}}, false));

        fPaths.push_back(b.arcTo(SkRect::MakeXYWH(0, 0, 50, 100), 25, 130, false)
                          .detach());

        // cubics
        fPaths.push_back(b.cubicTo(  1,  1, 10,  90, 0, 100).detach());
        fPaths.push_back(b.cubicTo(100, 50, 20, 100, 0,   0).detach());

        // path that has a cubic with a repeated first control point and
        // a repeated last control point.
        fPaths.push_back(b.moveTo(10, 10)
                          .cubicTo(10, 10, 10, 0, 20, 0)
                          .lineTo(40, 0)
                          .cubicTo(40, 0, 50, 0, 50, 10)
                          .detach());

        // path that has two cubics with repeated middle control points.
        fPaths.push_back(b.moveTo(10, 10)
                          .cubicTo(10, 0, 10, 0, 20, 0)
                          .lineTo(40, 0)
                          .cubicTo(50, 0, 50, 0, 50, 10)
                          .detach());

        // cubic where last three points are almost a line
        fPaths.push_back(b.moveTo(0, 228.0f/8)
                          .cubicTo( 628.0f/ 8,  82.0f/8,
                                   1255.0f/ 8, 141.0f/8,
                                   1883.0f/ 8, 202.0f/8)
                          .detach());

        // flat cubic where the at end point tangents both point outward.
        fPaths.push_back(b.moveTo(10, 0)
                          .cubicTo(0, 1, 30, 1, 20, 0)
                          .detach());

        // flat cubic where initial tangent is in, end tangent out
        fPaths.push_back(b.moveTo(0, 0)
                          .cubicTo(10, 1, 30, 1, 20, 0)
                          .detach());

        // flat cubic where initial tangent is out, end tangent in
        fPaths.push_back(b.moveTo(10, 0)
                          .cubicTo(0, 1, 20, 1, 30, 0)
                          .detach());

        // triangle where one edge is a degenerate quad
        fPaths.push_back(b.moveTo(8.59375f, 45)
                          .quadTo(16.9921875f,   45,
                                  31.25f,        45)
                          .lineTo(100,          100)
                          .lineTo(8.59375f,      45)
                          .detach());

        // triangle where one edge is a quad with a repeated point
        fPaths.push_back(b.moveTo(0, 25)
                          .lineTo(50, 0)
                          .quadTo(50, 50, 50, 50)
                          .detach());

        // triangle where one edge is a cubic with a 2x repeated point
        fPaths.push_back(b.moveTo(0, 25)
                          .lineTo(50, 0)
                          .cubicTo(50, 0, 50, 50, 50, 50)
                          .detach());

        // triangle where one edge is a quad with a nearly repeated point
        fPaths.push_back(b.moveTo(0, 25)
                          .lineTo(50, 0)
                          .quadTo(50, 49.95f, 50, 50)
                          .detach());

        // triangle where one edge is a cubic with a 3x nearly repeated point
        fPaths.push_back(b.moveTo(0, 25)
                          .lineTo(50, 0)
                          .cubicTo(50, 49.95f, 50, 49.97f, 50, 50)
                          .detach());

        // triangle where there is a point degenerate cubic at one corner
        fPaths.push_back(b.moveTo(0, 25)
                          .lineTo(50, 0)
                          .lineTo(50, 50)
                          .cubicTo(50, 50, 50, 50, 50, 50)
                          .detach());

        // point line
        fPaths.push_back(SkPath::Line({50, 50}, {50, 50}));

        // point quad
        fPaths.push_back(b.moveTo(50, 50)
                          .quadTo(50, 50, 50, 50)
                          .detach());

        // point cubic
        fPaths.push_back(b.moveTo(50, 50)
                          .cubicTo(50, 50, 50, 50, 50, 50)
                          .detach());

        // moveTo only paths
        fPaths.push_back(b.moveTo(0, 0)
                          .moveTo(0, 0)
                          .moveTo(1, 1)
                          .moveTo(1, 1)
                          .moveTo(10, 10)
                          .detach());

        fPaths.push_back(b.moveTo(0, 0)
                          .moveTo(0, 0)
                          .detach());

        // line degenerate
        fPaths.push_back(b.lineTo(100, 100).detach());
        fPaths.push_back(b.quadTo(100, 100, 0, 0).detach());
        fPaths.push_back(b.quadTo(100, 100, 50, 50).detach());
        fPaths.push_back(b.quadTo(50, 50, 100, 100).detach());
        fPaths.push_back(b.cubicTo(0, 0, 0, 0, 100, 100).detach());

        // skbug.com/40040207
        SkMatrix m;
        m.setAll(0.1f, 0, -1, 0, 0.115207f, -2.64977f, 0, 0, 1);
        fPaths.push_back(b.moveTo(16.875f, 192.594f)
                          .cubicTo(45.625f, 192.594f, 74.375f, 192.594f, 103.125f, 192.594f)
                          .cubicTo(88.75f, 167.708f, 74.375f, 142.823f, 60, 117.938f)
                          .cubicTo(45.625f, 142.823f, 31.25f, 167.708f, 16.875f, 192.594f)
                          .close()
                          .transform(m)
                          .detach());

        // small circle. This is listed last so that it has device coords far
        // from the origin (small area relative to x,y values).
        fPaths.push_back(SkPath::Circle(0, 0, 1.2f));
    }

    void onDraw(SkCanvas* canvas) override {
        this->makePaths();

        SkPaint paint;
        paint.setAntiAlias(true);
        SkRandom rand;
        canvas->translate(20, 20);

        // As we've added more paths this has gotten pretty big. Scale the whole thing down.
        canvas->scale(2.0f/3, 2.0f/3);

        for (int i = 0; i < fPaths.size(); ++i) {
            canvas->save();
            // position the path, and make it at off-integer coords.
            canvas->translate(200.0f * (i % 5) + 1.0f/10,
                              200.0f * (i / 5) + 9.0f/10);
            SkColor color = rand.nextU();
            color |= 0xff000000;
            paint.setColor(color);
#if 0       // This hitting on 32bit Linux builds for some paths. Temporarily disabling while it is
            // debugged.
            SkASSERT(fPaths[i].isConvex());
#endif
            canvas->drawPath(fPaths[i], paint);
            canvas->restore();
        }
    }

    TArray<SkPath> fPaths;
};
}  // namespace

DEF_GM( return new ConvexPathsGM; )
