/*
 * 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/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"

namespace skiagm {

class HairlinesGM : public GM {
protected:


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

    SkISize onISize() override { return SkISize::Make(1250, 1250); }

    void onOnceBeforeDraw() override {
        {
            SkPathBuilder lineAngles;
            enum {
                kNumAngles = 15,
                kRadius = 40,
            };
            for (int i = 0; i < kNumAngles; ++i) {
                SkScalar angle = SK_ScalarPI * SkIntToScalar(i) / kNumAngles;
                SkScalar x = kRadius * SkScalarCos(angle);
                SkScalar y = kRadius * SkScalarSin(angle);
                lineAngles.moveTo(x, y).lineTo(-x, -y);
            }
            fPaths.push_back(lineAngles.detach());
        }

        fPaths.push_back(SkPathBuilder().moveTo(0, -10)
                                        .quadTo(100, 100, -10, 0)
                                        .detach());

        fPaths.push_back(SkPathBuilder().moveTo(0, -5)
                                        .quadTo(100, 100, -5, 0)
                                        .detach());

        fPaths.push_back(SkPathBuilder().moveTo(0, -2)
                                        .quadTo(100, 100, -2, 0)
                                        .detach());

        fPaths.push_back(SkPathBuilder().moveTo(0, -1)
                                        .quadTo(100, 100, -2 + 306.0f / 4, 75)
                                        .detach());

        fPaths.push_back(SkPathBuilder().moveTo(0, -1)
                                        .quadTo(100, 100, -1, 0)
                                        .detach());

        fPaths.push_back(SkPathBuilder().moveTo(0, -0)
                                        .quadTo(100, 100, 0, 0)
                                        .detach());

        fPaths.push_back(SkPathBuilder().moveTo(0, -0)
                                        .quadTo(100, 100, 75, 75)
                                        .detach());

        // Two problem cases for gpu hairline renderer found by shapeops testing. These used
        // to assert that the computed bounding box didn't contain all the vertices.

        fPaths.push_back(SkPathBuilder().moveTo(4, 6)
                                        .cubicTo(5, 6, 5, 4, 4, 0)
                                        .close()
                                        .detach());

        fPaths.push_back(SkPathBuilder().moveTo(5, 1)
                                        .lineTo( 4.32787323f, 1.67212653f)
                                        .cubicTo(2.75223875f, 3.24776125f,
                                                 3.00581908f, 4.51236057f,
                                                 3.7580452f,  4.37367964f)
                                        .cubicTo(4.66472578f, 3.888381f,
                                                 5.f,         2.875f,
                                                 5.f,         1.f)
                                        .close()
                                        .detach());

        // Three paths that show the same bug (missing end caps)

        fPaths.push_back(SkPathBuilder().moveTo(6.5f,5.5f)
                                        .lineTo(3.5f,0.5f)
                                        .moveTo(0.5f,5.5f)
                                        .lineTo(3.5f,0.5f)
                                        .detach());

        // An X (crbug.com/137317)
        fPaths.push_back(SkPathBuilder().moveTo(1, 1)
                                        .lineTo(6, 6)
                                        .moveTo(1, 6)
                                        .lineTo(6, 1)
                                        .detach());

        // A right angle (crbug.com/137465 and crbug.com/256776)
        fPaths.push_back(SkPathBuilder().moveTo(5.5f, 5.5f)
                                        .lineTo(5.5f, 0.5f)
                                        .lineTo(0.5f, 0.5f)
                                        .detach());

        {
            // Arc example to test imperfect truncation bug (crbug.com/295626)
            constexpr SkScalar kRad = SkIntToScalar(2000);
            constexpr SkScalar kStartAngle = 262.59717f;
            constexpr SkScalar kSweepAngle = SkScalarHalf(17.188717f);

            SkPathBuilder bug;

            // Add a circular arc
            SkRect circle = SkRect::MakeLTRB(-kRad, -kRad, kRad, kRad);
            bug.addArc(circle, kStartAngle, kSweepAngle);

            // Now add the chord that should cap the circular arc
            SkPoint p0 = { kRad * SkScalarCos(SkDegreesToRadians(kStartAngle)),
                           kRad * SkScalarSin(SkDegreesToRadians(kStartAngle)) };

            SkPoint p1 = { kRad * SkScalarCos(SkDegreesToRadians(kStartAngle + kSweepAngle)),
                           kRad * SkScalarSin(SkDegreesToRadians(kStartAngle + kSweepAngle)) };

            bug.moveTo(p0);
            bug.lineTo(p1);
            fPaths.push_back(bug.detach());
        }
    }

    void onDraw(SkCanvas* canvas) override {
        constexpr SkAlpha kAlphaValue[] = { 0xFF, 0x40 };
        constexpr SkScalar kWidths[] = { 0, 0.5f, 1.5f };

        enum {
            kMargin = 5,
        };
        int wrapX = 1250 - kMargin;

        SkScalar maxH = 0;
        canvas->translate(SkIntToScalar(kMargin), SkIntToScalar(kMargin));
        canvas->save();

        SkScalar x = SkIntToScalar(kMargin);
        for (int p = 0; p < fPaths.count(); ++p) {
            for (size_t a = 0; a < SK_ARRAY_COUNT(kAlphaValue); ++a) {
                for (int aa = 0; aa < 2; ++aa) {
                    for (size_t w = 0; w < SK_ARRAY_COUNT(kWidths); w++) {
                        const SkRect& bounds = fPaths[p].getBounds();

                        if (x + bounds.width() > wrapX) {
                            canvas->restore();
                            canvas->translate(0, maxH + SkIntToScalar(kMargin));
                            canvas->save();
                            maxH = 0;
                            x = SkIntToScalar(kMargin);
                        }

                        SkPaint paint;
                        paint.setARGB(kAlphaValue[a], 0, 0, 0);
                        paint.setAntiAlias(SkToBool(aa));
                        paint.setStyle(SkPaint::kStroke_Style);
                        paint.setStrokeWidth(kWidths[w]);

                        canvas->save();
                        canvas->translate(-bounds.fLeft, -bounds.fTop);
                        canvas->drawPath(fPaths[p], paint);
                        canvas->restore();

                        maxH = std::max(maxH, bounds.height());

                        SkScalar dx = bounds.width() + SkIntToScalar(kMargin);
                        x += dx;
                        canvas->translate(dx, 0);
                    }
                }
            }
        }
        canvas->restore();
    }

private:
    SkTArray<SkPath> fPaths;
    using INHERITED = GM;
};

static void draw_squarehair_tests(SkCanvas* canvas, SkScalar width, SkPaint::Cap cap, bool aa) {
    SkPaint paint;
    paint.setStrokeCap(cap);
    paint.setStrokeWidth(width);
    paint.setAntiAlias(aa);
    paint.setStyle(SkPaint::kStroke_Style);
    canvas->drawLine(10, 10, 20, 10, paint);
    canvas->drawLine(30, 10, 30, 20, paint);
    canvas->drawLine(40, 10, 50, 20, paint);
    SkPathBuilder path;
    path.moveTo(60, 10);
    path.quadTo(60, 20, 70, 20);
    path.conicTo(70, 10, 80, 10, 0.707f);
    canvas->drawPath(path.detach(), paint);

    path.moveTo(90, 10);
    path.cubicTo(90, 20, 100, 20, 100, 10);
    path.lineTo(110, 10);
    canvas->drawPath(path.detach(), paint);
    canvas->translate(0, 30);
}

DEF_SIMPLE_GM(squarehair, canvas, 240, 360) {
    const bool aliases[] = { false, true };
    const SkScalar widths[] = { 0, 0.999f, 1, 1.001f };
    const SkPaint::Cap caps[] = { SkPaint::kButt_Cap, SkPaint::kSquare_Cap, SkPaint::kRound_Cap };
    for (auto alias : aliases) {
        canvas->save();
        for (auto width : widths) {
            for (auto cap : caps) {
                draw_squarehair_tests(canvas, width, cap, alias);
            }
        }
        canvas->restore();
        canvas->translate(120, 0);
    }
}

// GM to test subdivision of hairlines
static void draw_subdivided_quad(SkCanvas* canvas, int x0, int y0, int x1, int y1, SkColor color) {
    SkPaint paint;
    paint.setStrokeWidth(1);
    paint.setAntiAlias(true);
    paint.setStyle(SkPaint::kStroke_Style);
    paint.setColor(color);

    canvas->drawPath(SkPathBuilder().moveTo(0,0)
                                    .quadTo(SkIntToScalar(x0), SkIntToScalar(y0),
                                            SkIntToScalar(x1), SkIntToScalar(y1))
                                    .detach(),
                     paint);
}

DEF_SIMPLE_GM(hairline_subdiv, canvas, 512, 256) {
    // no subdivisions
    canvas->translate(45, -25);
    draw_subdivided_quad(canvas, 334, 334, 467, 267, SK_ColorBLACK);

    // one subdivision
    canvas->translate(-185, -150);
    draw_subdivided_quad(canvas, 472, 472, 660, 378, SK_ColorRED);

    // two subdivisions
    canvas->translate(-275, -200);
    draw_subdivided_quad(canvas, 668, 668, 934, 535, SK_ColorGREEN);

    // three subdivisions
    canvas->translate(-385, -260);
    draw_subdivided_quad(canvas, 944, 944, 1320, 756, SK_ColorBLUE);
}

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

DEF_GM( return new HairlinesGM; )

}  // namespace skiagm
