/*
 * 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/SkTArray.h"
#include "src/core/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; )
