/*
 * Copyright 2016 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/SkPathEffect.h"
#include "include/core/SkRect.h"
#include "include/core/SkScalar.h"
#include "include/core/SkTypes.h"
#include "include/effects/SkDashPathEffect.h"
#include "include/private/SkTArray.h"
#include "src/core/SkFloatBits.h"

#include <functional>

using namespace skia_private;

constexpr SkScalar kStarts[] = {0.f, 10.f, 30.f, 45.f, 90.f, 165.f, 180.f, 270.f};
constexpr SkScalar kSweeps[] = {1.f, 45.f, 90.f, 130.f, 180.f, 184.f, 300.f, 355.f};
constexpr SkScalar kDiameter = 40.f;
constexpr SkRect kRect = {0.f, 0.f, kDiameter, kDiameter};
constexpr int kW = 1000;
constexpr int kH = 1000;

void draw_arcs(SkCanvas* canvas, std::function<void(SkPaint*)> configureStyle) {
    // Draws grid of arcs with different start/sweep angles in red and their complement arcs in
    // blue.
    auto drawGrid = [canvas, &configureStyle] (SkScalar x, SkScalar y, bool useCenter, bool aa) {
        constexpr SkScalar kPad = 20.f;
        SkPaint p0;
        p0.setColor(SK_ColorRED);
        p0.setAntiAlias(aa);
        // Set a reasonable stroke width that configureStyle can override.
        p0.setStrokeWidth(15.f);
        SkPaint p1 = p0;
        p1.setColor(SK_ColorBLUE);
        // Use alpha so we see magenta on overlap between arc and its complement.
        p0.setAlpha(100);
        p1.setAlpha(100);
        configureStyle(&p0);
        configureStyle(&p1);

        canvas->save();
        canvas->translate(kPad + x, kPad + y);
        for (auto start : kStarts) {
            canvas->save();
            for (auto sweep : kSweeps) {
                canvas->drawArc(kRect, start, sweep, useCenter, p0);
                canvas->drawArc(kRect, start, -(360.f - sweep), useCenter, p1);
                canvas->translate(kRect.width() + kPad, 0.f);
            }
            canvas->restore();
            canvas->translate(0, kRect.height() + kPad);
        }
        canvas->restore();
    };
    // Draw a grids for combo of enabling/disabling aa and using center.
    constexpr SkScalar kGridW = kW / 2.f;
    constexpr SkScalar kGridH = kH / 2.f;
    drawGrid(0.f   , 0.f   , false, false);
    drawGrid(kGridW, 0.f   , true , false);
    drawGrid(0.f   , kGridH, false, true );
    drawGrid(kGridW, kGridH, true , true );
    // Draw separators between the grids.
    SkPaint linePaint;
    linePaint.setAntiAlias(true);
    linePaint.setColor(SK_ColorBLACK);
    canvas->drawLine(kGridW, 0.f   , kGridW,            SkIntToScalar(kH), linePaint);
    canvas->drawLine(0.f   , kGridH, SkIntToScalar(kW), kGridH,            linePaint);
}

#define DEF_ARC_GM(name) DEF_SIMPLE_GM(circular_arcs_##name, canvas, kW, kH)

DEF_ARC_GM(fill) {
    auto setFill = [] (SkPaint*p) { p->setStroke(false); };
    draw_arcs(canvas, setFill);
}

DEF_ARC_GM(hairline) {
    auto setHairline = [] (SkPaint* p) {
        p->setStroke(true);
        p->setStrokeWidth(0.f);
    };
    draw_arcs(canvas, setHairline);
}

DEF_ARC_GM(stroke_butt) {
    auto setStroke = [](SkPaint* p) {
        p->setStroke(true);
        p->setStrokeCap(SkPaint::kButt_Cap);
    };
    draw_arcs(canvas, setStroke);
}

DEF_ARC_GM(stroke_square) {
    auto setStroke = [] (SkPaint* p) {
        p->setStroke(true);
        p->setStrokeCap(SkPaint::kSquare_Cap);
    };
    draw_arcs(canvas, setStroke);
}

DEF_ARC_GM(stroke_round) {
    auto setStroke = [] (SkPaint* p) {
        p->setStroke(true);
        p->setStrokeCap(SkPaint::kRound_Cap);
    };
    draw_arcs(canvas, setStroke);
}

DEF_SIMPLE_GM(circular_arcs_weird, canvas, 1000, 400) {
    constexpr SkScalar kS = 50;
    struct Arc {
        SkRect   fOval;
        SkScalar fStart;
        SkScalar fSweep;
    };
    const Arc noDrawArcs[] = {
        // no sweep
        {SkRect::MakeWH(kS, kS),  0,  0},
        // empty rect in x
        {SkRect::MakeWH(-kS, kS), 0, 90},
        // empty rect in y
        {SkRect::MakeWH(kS, -kS), 0, 90},
        // empty rect in x and y
        {SkRect::MakeWH( 0,   0), 0, 90},
    };
    const Arc arcs[] = {
        // large start
        {SkRect::MakeWH(kS, kS),   810.f,   90.f},
        // large negative start
        {SkRect::MakeWH(kS, kS),  -810.f,   90.f},
        // exactly 360 sweep
        {SkRect::MakeWH(kS, kS),     0.f,  360.f},
        // exactly -360 sweep
        {SkRect::MakeWH(kS, kS),     0.f, -360.f},
        // exactly 540 sweep
        {SkRect::MakeWH(kS, kS),     0.f,  540.f},
        // exactly -540 sweep
        {SkRect::MakeWH(kS, kS),     0.f, -540.f},
        // generic large sweep and large start
        {SkRect::MakeWH(kS, kS),  1125.f,  990.f},
    };
    TArray<SkPaint> paints;
    // fill
    paints.push_back();
    // stroke
    paints.push_back().setStroke(true);
    paints.back().setStrokeWidth(kS / 6.f);
    // hairline
    paints.push_back().setStroke(true);
    paints.back().setStrokeWidth(0.f);
    // stroke and fill
    paints.push_back().setStyle(SkPaint::kStrokeAndFill_Style);
    paints.back().setStrokeWidth(kS / 6.f);
    // dash effect
    paints.push_back().setStroke(true);
    paints.back().setStrokeWidth(kS / 6.f);
    constexpr SkScalar kDashIntervals[] = {kS / 15, 2 * kS / 15};
    paints.back().setPathEffect(SkDashPathEffect::Make(kDashIntervals, 0.f));

    constexpr SkScalar kPad = 20.f;
    canvas->translate(kPad, kPad);
    // This loop should draw nothing.
    for (auto arc : noDrawArcs) {
        for (auto paint : paints) {
            paint.setAntiAlias(true);
            canvas->drawArc(arc.fOval, arc.fStart, arc.fSweep, false, paint);
            canvas->drawArc(arc.fOval, arc.fStart, arc.fSweep, true, paint);
        }
    }

    SkPaint linePaint;
    linePaint.setAntiAlias(true);
    linePaint.setColor(SK_ColorRED);
    SkScalar midX   = std::size(arcs) * (kS + kPad) - kPad/2.f;
    SkScalar height = paints.size() * (kS + kPad);
    canvas->drawLine(midX, -kPad, midX, height, linePaint);

    for (auto paint : paints) {
        paint.setAntiAlias(true);
        canvas->save();
        for (auto arc : arcs) {
            canvas->drawArc(arc.fOval, arc.fStart, arc.fSweep, false, paint);
            canvas->translate(kS + kPad, 0.f);
        }
        for (auto arc : arcs) {
            canvas->drawArc(arc.fOval, arc.fStart, arc.fSweep, true, paint);
            canvas->translate(kS + kPad, 0.f);
        }
        canvas->restore();
        canvas->translate(0, kS + kPad);
    }
}

DEF_SIMPLE_GM(onebadarc, canvas, 100, 100) {
    SkPathBuilder path;
    path.moveTo(SkBits2Float(0x41a00000), SkBits2Float(0x41a00000));  // 20, 20
    path.lineTo(SkBits2Float(0x4208918c), SkBits2Float(0x4208918c));  // 34.1421f, 34.1421f
    path.conicTo(SkBits2Float(0x41a00000), SkBits2Float(0x42412318),  // 20, 48.2843f
            SkBits2Float(0x40bb73a0), SkBits2Float(0x4208918c),       // 5.85786f, 34.1421f
            SkBits2Float(0x3f3504f3));                                // 0.707107f
    path.quadTo(SkBits2Float(0x40bb73a0), SkBits2Float(0x4208918c),   // 5.85786f, 34.1421f
            SkBits2Float(0x40bb73a2), SkBits2Float(0x4208918c));      // 5.85787f, 34.1421f
    path.lineTo(SkBits2Float(0x41a00000), SkBits2Float(0x41a00000));  // 20, 20
    path.close();
    SkPaint p0;
    p0.setColor(SK_ColorRED);
    p0.setStrokeWidth(15.f);
    p0.setStroke(true);
    p0.setAlpha(100);
    canvas->translate(20, 0);
    canvas->drawPath(path.detach(), p0);

    canvas->drawArc(SkRect{60, 0, 100, 40}, 45, 90, true, p0);
}

DEF_SIMPLE_GM(crbug_888453, canvas, 480, 150) {
    // Two GPU path renderers were using a too-large tolerance when chopping connics to quads.
    // This manifested as not-very-round circular arcs at certain radii. All the arcs being drawn
    // here should look like circles.
    SkPaint fill;
    fill.setAntiAlias(true);
    SkPaint hairline = fill;
    hairline.setStroke(true);
    SkPaint stroke = hairline;
    stroke.setStrokeWidth(2.0f);
    int x = 4;
    int y0 = 25, y1 = 75, y2 = 125;
    for (int r = 2; r <= 20; ++r) {
        canvas->drawArc(SkRect::MakeXYWH(x - r, y0 - r, 2 * r, 2 * r), 0, 360, false, fill);
        canvas->drawArc(SkRect::MakeXYWH(x - r, y1 - r, 2 * r, 2 * r), 0, 360, false, hairline);
        canvas->drawArc(SkRect::MakeXYWH(x - r, y2 - r, 2 * r, 2 * r), 0, 360, false, stroke);
        x += 2 * r + 4;
    }
}

DEF_SIMPLE_GM(circular_arc_stroke_matrix, canvas, 820, 1090) {
    static constexpr SkScalar kRadius = 40.f;
    static constexpr SkScalar kStrokeWidth = 5.f;
    static constexpr SkScalar kStart = 89.f;
    static constexpr SkScalar kSweep = 180.f/SK_ScalarPI; // one radian

    TArray<SkMatrix> matrices;
    matrices.push_back().setRotate(kRadius, kRadius, 45.f);
    matrices.push_back(SkMatrix::I());
    matrices.push_back().setAll(-1,  0,  2*kRadius,
                                 0,  1,  0,
                                 0,  0,  1);
    matrices.push_back().setAll( 1,  0,  0,
                                 0, -1,  2*kRadius,
                                 0,  0,  1);
    matrices.push_back().setAll( 1,  0,  0,
                                 0, -1,  2*kRadius,
                                 0,  0,  1);
    matrices.push_back().setAll( 0, -1,  2*kRadius,
                                -1,  0,  2*kRadius,
                                 0,  0,  1);
    matrices.push_back().setAll( 0, -1,  2*kRadius,
                                 1,  0,  0,
                                 0,  0,  1);
    matrices.push_back().setAll( 0,  1,  0,
                                 1,  0,  0,
                                 0,  0,  1);
    matrices.push_back().setAll( 0,  1,  0,
                                -1,  0,  2*kRadius,
                                 0,  0,  1);
    int baseMatrixCnt = matrices.size();


    SkMatrix tinyCW;
    tinyCW.setRotate(0.001f, kRadius, kRadius);
    for (int i = 0; i < baseMatrixCnt; ++i) {
        matrices.push_back().setConcat(matrices[i], tinyCW);
    }
    SkMatrix tinyCCW;
    tinyCCW.setRotate(-0.001f, kRadius, kRadius);
    for (int i = 0; i < baseMatrixCnt; ++i) {
        matrices.push_back().setConcat(matrices[i], tinyCCW);
    }
    SkMatrix cw45;
    cw45.setRotate(45.f, kRadius, kRadius);
    for (int i = 0; i < baseMatrixCnt; ++i) {
        matrices.push_back().setConcat(matrices[i], cw45);
    }

    int x = 0;
    int y = 0;
    static constexpr SkScalar kPad = 2*kStrokeWidth;
    canvas->translate(kPad, kPad);
    auto bounds = SkRect::MakeWH(2*kRadius, 2*kRadius);
    for (auto cap : {SkPaint::kRound_Cap, SkPaint::kButt_Cap, SkPaint::kSquare_Cap}) {
        for (const auto& m : matrices) {
            SkPaint paint;
            paint.setStrokeCap(cap);
            paint.setAntiAlias(true);
            paint.setStroke(true);
            paint.setStrokeWidth(kStrokeWidth);
            canvas->save();
                canvas->translate(x * (2*kRadius + kPad), y * (2*kRadius + kPad));
                canvas->concat(m);
                paint.setColor(SK_ColorRED);
                paint.setAlpha(0x80);
                canvas->drawArc(bounds, kStart, kSweep, false, paint);
                paint.setColor(SK_ColorBLUE);
                paint.setAlpha(0x80);
                canvas->drawArc(bounds, kStart, kSweep - 360.f, false, paint);
            canvas->restore();
            ++x;
            if (x == baseMatrixCnt) {
                x = 0;
                ++y;
            }
        }
    }
}

DEF_SIMPLE_GM(crbug_1472747, canvas, 400, 400) {
    auto addCanvas2dCircleArcTo = [](float cx, float cy, float radius, SkPathBuilder* builder) {
        SkRect oval = SkRect::MakeLTRB(cx - radius, cy - radius, cx + radius, cy + radius);
        // arcTo(oval, 0, 2pi, anticlockwise) gets split to 0->-180,-180->-360
        builder->arcTo(oval, 0.f, -180.f, false);
        builder->arcTo(oval, -180.f, -180.f, false);
    };

    // This manually stroked circle is large enough to trigger pre-chopping in the
    // tessellation path renderers, but uses a non-default winding mode, which
    // originally was not preserved in the chopped path.
    static constexpr float kRadius = 31000.f;
    SkPathBuilder strokedCircle;
    addCanvas2dCircleArcTo(0.f, kRadius + 10.f, kRadius, &strokedCircle); // inner
    addCanvas2dCircleArcTo(0.f, kRadius + 10.f, kRadius + 5.f, &strokedCircle); // outer
    strokedCircle.setFillType(SkPathFillType::kEvenOdd);

    SkPaint fill;
    fill.setAntiAlias(true);
    canvas->drawPath(strokedCircle.detach(), fill);
}

DEF_SIMPLE_GM(bug406747427, canvas, 400, 400) {
    SkPaint paint;
    paint.setAntiAlias(true);
    paint.setStyle(SkPaint::kStroke_Style);
    paint.setStrokeCap(SkPaint::kRound_Cap);
    paint.setColor(SkColorSetARGB(255,255,0,0));
    paint.setStrokeWidth(50);
    SkRect oval = SkRect::MakeXYWH(100, 40, 50, 50);
    canvas->drawArc(oval, 45, 275, false, paint);

    paint.setColor(SkColorSetARGB(255,0,0,255));
    paint.setStrokeWidth(48);
    oval = SkRect::MakeXYWH(100, 140, 50, 50);
    canvas->drawArc(oval, 45, 275, false, paint);

    paint.setColor(SkColorSetARGB(255,0,255,0));
    paint.setStrokeWidth(80);
    oval = SkRect::MakeXYWH(100, 280, 50, 50);
    canvas->drawArc(oval, 45, 275, false, paint);
}
