/*
 * 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/SkNoncopyable.h"
#include "include/private/base/SkTArray.h"
#include "include/utils/SkRandom.h"

namespace {

class SkDoOnce : SkNoncopyable {
public:
    SkDoOnce() { fDidOnce = false; }

    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 onShortName() override { return SkString("convexpaths"); }


    SkISize onISize() 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
        enum {
            kLength = 100,
            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/8928
        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()
                          .detach());
        SkMatrix m;
        m.setAll(0.1f, 0, -1, 0, 0.115207f, -2.64977f, 0, 0, 1);
        fPaths.back().transform(m);

        // 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();
        }
    }

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

DEF_GM( return new ConvexPathsGM; )
