/*
 * Copyright 2013 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/SkPathBuilder.h"
#include "include/core/SkPoint.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 "include/utils/SkRandom.h"

namespace skiagm {

// This GM tests a grab-bag of convex and concave polygons. They are triangles,
// trapezoid, diamond, polygons with lots of edges, several concave polygons...
// But rectangles are excluded.
class PolygonsGM: public GM {
public:
    PolygonsGM() {}

protected:

    SkString onShortName() override {
        return SkString("polygons");
    }

    SkISize onISize() override {
        int width = kNumPolygons * kCellSize + 40;
        int height = (kNumJoins * kNumStrokeWidths + kNumExtraStyles) * kCellSize + 40;
        return SkISize::Make(width, height);
    }

    // Construct all polygons
    void onOnceBeforeDraw() override {
        SkPoint p0[] = {{0, 0}, {60, 0}, {90, 40}};  // triangle
        SkPoint p1[] = {{0, 0}, {0, 40}, {60, 40}, {40, 0}};  // trapezoid
        SkPoint p2[] = {{0, 0}, {40, 40}, {80, 40}, {40, 0}};  // diamond
        SkPoint p3[] = {{10, 0}, {50, 0}, {60, 10}, {60, 30}, {50, 40},
                        {10, 40}, {0, 30}, {0, 10}};  // octagon
        SkPoint p4[32];  // circle-like polygons with 32-edges.
        SkPoint p5[] = {{0, 0}, {20, 20}, {0, 40}, {60, 20}};  // concave polygon with 4 edges
        SkPoint p6[] = {{0, 40}, {0, 30}, {15, 30}, {15, 20}, {30, 20},
                        {30, 10}, {45, 10}, {45, 0}, {60, 0}, {60, 40}};  // stairs-like polygon
        SkPoint p7[] = {{0, 20}, {20, 20}, {30, 0}, {40, 20}, {60, 20},
                        {45, 30}, {55, 50}, {30, 40}, {5, 50}, {15, 30}};  // five-point stars

        for (size_t i = 0; i < std::size(p4); ++i) {
            SkScalar angle = 2 * SK_ScalarPI * i / std::size(p4);
            p4[i].set(20 * SkScalarCos(angle) + 20, 20 * SkScalarSin(angle) + 20);
        }

        struct Polygons {
            SkPoint* fPoints;
            size_t fPointNum;
        } pgs[] = {
            { p0, std::size(p0) },
            { p1, std::size(p1) },
            { p2, std::size(p2) },
            { p3, std::size(p3) },
            { p4, std::size(p4) },
            { p5, std::size(p5) },
            { p6, std::size(p6) },
            { p7, std::size(p7) }
        };

        SkASSERT(std::size(pgs) == kNumPolygons);
        for (size_t pgIndex = 0; pgIndex < std::size(pgs); ++pgIndex) {
            SkPathBuilder b;
            b.moveTo(pgs[pgIndex].fPoints[0].fX,
                     pgs[pgIndex].fPoints[0].fY);
            for (size_t ptIndex = 1; ptIndex < pgs[pgIndex].fPointNum; ++ptIndex) {
                b.lineTo(pgs[pgIndex].fPoints[ptIndex].fX,
                         pgs[pgIndex].fPoints[ptIndex].fY);
            }
            b.close();
            fPolygons.push_back(b.detach());
        }
    }

    // Set the location for the current test on the canvas
    static void SetLocation(SkCanvas* canvas, int counter, int lineNum) {
        SkScalar x = SK_Scalar1 * kCellSize * (counter % lineNum) + 30 + SK_Scalar1 / 4;
        SkScalar y = SK_Scalar1 * kCellSize * (counter / lineNum) + 30 + 3 * SK_Scalar1 / 4;
        canvas->translate(x, y);
    }

    static void SetColorAndAlpha(SkPaint* paint, SkRandom* rand) {
        SkColor color = rand->nextU();
        color |= 0xff000000;
        paint->setColor(color);
        if (40 == paint->getStrokeWidth()) {
            paint->setAlpha(0xA0);
        }
    }

    void onDraw(SkCanvas* canvas) override {
        // Stroke widths are:
        // 0(may use hairline rendering), 10(common case for stroke-style)
        // 40(>= geometry width/height, make the contour filled in fact)
        constexpr int kStrokeWidths[] = {0, 10, 40};
        SkASSERT(kNumStrokeWidths == std::size(kStrokeWidths));

        constexpr SkPaint::Join kJoins[] = {
            SkPaint::kMiter_Join, SkPaint::kRound_Join, SkPaint::kBevel_Join
        };
        SkASSERT(kNumJoins == std::size(kJoins));

        int counter = 0;
        SkPaint paint;
        paint.setAntiAlias(true);

        SkRandom rand;
        // For stroke style painter
        paint.setStyle(SkPaint::kStroke_Style);
        for (int join = 0; join < kNumJoins; ++join) {
            for (int width = 0; width < kNumStrokeWidths; ++width) {
                for (int i = 0; i < fPolygons.size(); ++i) {
                    canvas->save();
                    SetLocation(canvas, counter, fPolygons.size());

                    SetColorAndAlpha(&paint, &rand);
                    paint.setStrokeJoin(kJoins[join]);
                    paint.setStrokeWidth(SkIntToScalar(kStrokeWidths[width]));

                    canvas->drawPath(fPolygons[i], paint);
                    canvas->restore();
                    ++counter;
                }
            }
        }

        // For stroke-and-fill style painter and fill style painter
        constexpr SkPaint::Style kStyles[] = {
            SkPaint::kStrokeAndFill_Style, SkPaint::kFill_Style
        };
        SkASSERT(kNumExtraStyles == std::size(kStyles));

        paint.setStrokeJoin(SkPaint::kMiter_Join);
        paint.setStrokeWidth(SkIntToScalar(20));
        for (int style = 0; style < kNumExtraStyles; ++style) {
            paint.setStyle(kStyles[style]);
            for (int i = 0; i < fPolygons.size(); ++i) {
                canvas->save();
                SetLocation(canvas, counter, fPolygons.size());
                SetColorAndAlpha(&paint, &rand);
                canvas->drawPath(fPolygons[i], paint);
                canvas->restore();
                ++counter;
            }
        }
    }

private:
    inline static constexpr int kNumPolygons = 8;
    inline static constexpr int kCellSize = 100;
    inline static constexpr int kNumExtraStyles = 2;
    inline static constexpr int kNumStrokeWidths = 3;
    inline static constexpr int kNumJoins = 3;

    SkTArray<SkPath> fPolygons;
    using INHERITED = GM;
};

//////////////////////////////////////////////////////////////////////////////

DEF_GM(return new PolygonsGM;)

// see crbug.com/1197461
DEF_SIMPLE_GM(conjoined_polygons, canvas, 400, 400) {
    SkPathBuilder b;
    b.moveTo(0.f, 120.f);
    b.lineTo(0.f, 0.f);
    b.lineTo(50.f, 330.f);
    b.lineTo(90.f, 0.f);
    b.lineTo(340.f, 0.f);
    b.lineTo(90.f, 330.f);
    b.lineTo(50.f, 330.f);
    b.close();

    SkPaint paint;
    paint.setAntiAlias(true);
    canvas->drawPath(b.detach(), paint);
}

}  // namespace skiagm
