// Copyright 2020 Google LLC
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#include "tools/fiddle/examples.h"

#include <array>

REG_FIDDLE(SKIA_LOGO_pride, 816, 464, false, 0) {
void draw(SkCanvas* canvas) {
    canvas->scale(4.0f, 4.0f);
    constexpr SkColor background = SK_ColorWHITE;
    constexpr SkColor lettering = 0xFF292929;
    const SkColor4f lineColors[2] = {
            SkColor4f::FromColor(0x30565656), SkColor4f::FromColor(0xFF565656)};

    // Colors from https://www.flagcolorcodes.com/progress-pride and https://www.flagcolorcodes.com/intersex
    constexpr auto rainbow = std::to_array<SkColor>({
            0xFFE40303,
            0xFFFF8C00,
            0xFFFFED00,
            0xFF008026,
            0xFF004CFF,
            0xFF732982,
    });
    constexpr auto progress = std::to_array<SkColor>({
            0xFFFFD800,
            0xFFFFFFFF,
            0xFFFFAFC8,
            0xFF74D7EE,
            0xFF613915,
            0xFF000000,
    });
    constexpr SkColor iViolet = 0xFF7902AA;

    SkPathBuilder s, k, a, triangle;
    SkPaint p;
    p.setAntiAlias(true);

    canvas->clear(background);
    canvas->scale(0.363f, 0.363f);

    float leftX = 310.f;
    constexpr float kIWidth = 50.f;
    constexpr float deltaWidth = kIWidth / std::size(rainbow);

    for (size_t i = 0; i < std::size(rainbow); ++i) {
        p.setColor(rainbow[i]);
        canvas->drawRect({leftX, 82.25f, leftX + deltaWidth, 249.2}, p);
        leftX += deltaWidth;
    }

    float triHeight = deltaWidth * (std::size(progress) + 1);

    canvas->save();
    canvas->clipRect({310.f, 82.25, 360.f, 249.2f}, SkClipOp::kIntersect, false);
    for (int i = std::size(progress)-1; i >= 0; --i) {
        p.setColor(progress[i]);
        SkPathBuilder t;
        t.moveTo(335.f, 82.25f + triHeight);
        t.rLineTo(200.f, -200.f);
        t.rLineTo(-400.f, 0.f);
        t.rLineTo(200.f, 200.f);
        canvas->drawPath(t.detach(), p);
        triHeight -= deltaWidth;
    }
    {
      SkPaint c;
      c.setColor(iViolet);
      c.setStroke(SkPaint::Style::kStroke_Style);
      c.setStrokeWidth(1.5f);
      c.setAntiAlias(true);

      canvas->drawCircle({335.f, 88.5f}, deltaWidth * 0.6f, c);
    }

    canvas->restore();

    p.setColor(lettering);
    canvas->drawCircle(335.355, 45.965, 29.25, p);

    s.moveTo(34.63, 100.63);
    s.cubicTo(44.38, 88.57, 59.87, 82.86, 74.88, 81.2);
    s.cubicTo(97.4, 78.5, 120.27, 83.25, 140.87, 92.37);
    s.lineTo(127.12, 127.14);
    s.cubicTo(113.55, 121.16, 99.04, 115.9, 83.98, 116.56);
    s.cubicTo(78.86, 116.75, 72.88, 118.54, 70.71, 123.69);
    s.cubicTo(68.62, 128.43, 71.52, 133.68, 75.58, 136.27);
    s.cubicTo(91.49, 146.66, 110.67, 151.38, 125.46, 163.6);
    s.cubicTo(132.35, 169.11, 137.33, 176.9, 139.36, 185.49);
    s.cubicTo(142.55, 199.14, 140.94, 214.31, 133.13, 226.17);
    s.cubicTo(126.23, 236.96, 114.82, 244.16, 102.75, 247.89);
    s.cubicTo(87.95, 252.51, 72.16, 252.21, 56.88, 250.78);
    s.cubicTo(45.54, 249.72, 34.64, 246.05, 24.32, 241.36);
    s.lineTo(24.25, 201.1);
    s.cubicTo(38.23, 208.15, 53.37, 213.15, 68.98, 214.75);
    s.cubicTo(75.42, 215.25, 82.17, 215.63, 88.31, 213.27);
    s.cubicTo(92.84, 211.53, 96.4, 206.93, 95.86, 201.93);
    s.cubicTo(95.64, 196.77, 91.1, 193.38, 87.03, 190.99);
    s.cubicTo(71.96, 182.67, 54.94, 177.66, 41.5, 166.57);
    s.cubicTo(33.19, 159.73, 27.51, 149.8, 26.1, 139.11);
    s.cubicTo(24.09, 125.88, 25.91, 111.25, 34.63, 100.63);
    canvas->drawPath(s.detach(), p);

    k.moveTo(160.82, 82.85);
    k.lineTo(206.05, 82.85);
    k.lineTo(206.05, 155.15);
    k.lineTo(254.83, 82.84);
    k.lineTo(304.01, 82.85);
    k.lineTo(251.52, 157.27);
    k.lineTo(303.09, 249.42);
    k.lineTo(252.28, 249.4);
    k.lineTo(219.18, 185.75);
    k.lineTo(206.23, 193.45);
    k.lineTo(206.05, 249.42);
    k.lineTo(160.82, 249.42);
    k.lineTo(160.82, 82.85);
    canvas->drawPath(k.detach(), p);

    a.moveTo(426.45, 218.16);
    a.lineTo(480.705, 218.16);
    a.lineTo(489.31, 249.4);
    a.lineTo(538.54, 249.42);
    a.lineTo(483.56, 82.18);
    a.lineTo(423.43, 82.17);
    a.lineTo(369.13, 249.42);
    a.lineTo(418.5, 249.47);
    a.lineTo(453.75, 109.83);
    a.lineTo(471.77, 181.28);
    a.lineTo(430.5, 181.28);
    canvas->drawPath(a.detach(), p);

    triangle.moveTo(362.64, 257.32);
    triangle.lineTo(335.292, 293.392);
    triangle.lineTo(307.8, 257.48);
    triangle.lineTo(362.64, 257.32);
    p.setColor(lettering);
    canvas->drawPath(triangle.detach(), p);

    constexpr SkPoint pts[2] = {{160, 290}, {341, 290}};
    p.setShader(SkShaders::LinearGradient(pts, {{lineColors, {}, SkTileMode::kClamp}, {}}));
    SkRRect rrect;
    rrect.setRectXY({138, 291, 341, 300}, 25.0, 5.0);
    canvas->drawRRect(rrect, p);
}
}  // END FIDDLE
