// 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"
REG_FIDDLE(ChromeMDRefreshTab, 256, 256, false, 0) {
SkPath GetBorderPath(float scale,
                     bool unscale_at_end,
                     bool extend_to_top,
                     float endcap_width,
                     const SkISize& size) {
    //  const float top = scale - 1;
    const float right = size.fWidth * scale;
    const float bottom = size.fHeight * scale;
    const float scaled_endcap_radius = (endcap_width / 2) * scale;

    SkPathBuilder path;
    path.moveTo(0, bottom - 1);
    // bottom left
    path.arcTo({scaled_endcap_radius - 1, scaled_endcap_radius - 1}, 90, SkPathBuilder::kSmall_ArcSize,
               SkPathDirection::kCCW, {scaled_endcap_radius - 1,
               bottom - 1 - scaled_endcap_radius});
    // path.rLineTo(0, -1);
    // path.rCubicTo(0.75 * scale, 0, 1.625 * scale, -0.5 * scale, 2 * scale,
    //               -1.5 * scale);
    path.lineTo(scaled_endcap_radius - 1, scaled_endcap_radius + 1);
    // path.lineTo((endcap_width - 2) * scale, top + 1.5 * scale);
    // top left
    path.arcTo({scaled_endcap_radius + 1, scaled_endcap_radius + 1}, 90, SkPathBuilder::kSmall_ArcSize,
               SkPathDirection::kCW, {scaled_endcap_radius * 2, -1});

    // if (extend_to_top) {
    // Create the vertical extension by extending the side diagonals until
    // they reach the top of the bounds.
    //  const float dy = 2.5 * scale - 1;
    //  const float dx = Tab::GetInverseDiagonalSlope() * dy;
    //  path.rLineTo(dx, -dy);
    //  path.lineTo(right - (endcap_width - 2) * scale - dx, 0);
    //  path.rLineTo(dx, dy);
    //} else {
    //  path.rCubicTo(0.375 * scale, -scale, 1.25 * scale, -1.5 * scale, 2 * scale,
    //                -1.5 * scale);
    //  path.lineTo(right - endcap_width * scale, top);
    //  path.rCubicTo(0.75 * scale, 0, 1.625 * scale, 0.5 * scale, 2 * scale,
    //                1.5 * scale);
    //}
    path.lineTo(right - scaled_endcap_radius * 2, -1);
    // path.lineTo(right - 2 * scale, bottom - 1 - 1.5 * scale);

    // top right
    path.arcTo({scaled_endcap_radius + 1, scaled_endcap_radius + 1}, 90, SkPathBuilder::kSmall_ArcSize,
               SkPathDirection::kCW, {right - scaled_endcap_radius + 1,
               scaled_endcap_radius + 1});
    // path.arcTo(SkRect::MakeLTRB(right - 2 * scale, bottom - 1 - 1.5 * scale,
    //    right - 2 * scale + 4, bottom - 1 - 1.5 * scale + 4), 90, 90, true);
    // path.rCubicTo(0.375 * scale, scale, 1.25 * scale, 1.5 * scale, 2 * scale,
    //              1.5 * scale);

    path.lineTo(right - scaled_endcap_radius + 1, bottom - 1 - scaled_endcap_radius);
    // path.rLineTo(0, 1);

    // bottom right
    path.arcTo({scaled_endcap_radius - 1, scaled_endcap_radius - 1}, 90, SkPathBuilder::kSmall_ArcSize,
               SkPathDirection::kCCW, {right, bottom - 1});
    path.close();

    if (unscale_at_end && (scale != 1)) path.transform(SkMatrix::Scale(1.f / scale,
                                                                       1.f / scale));

    return path.detach();
}

SkPath GetInteriorPath(
        float scale, const SkISize& size, float endcap_width, float horizontal_inset = 0) {
    const float right = size.fWidth * scale;
    // The bottom of the tab needs to be pixel-aligned or else when we call
    // ClipPath with anti-aliasing enabled it can cause artifacts.
    const float bottom = std::ceil(size.fHeight * scale);

    // const float scaled_horizontal_inset = horizontal_inset * scale;

    const float scaled_endcap_radius = (endcap_width / 2) * scale;

    // Construct the interior path by intersecting paths representing the left
    // and right halves of the tab.  Compared to computing the full path at once,
    // this makes it easier to avoid overdraw in the top center near minimum
    // width, and to implement cases where |horizontal_inset| != 0.
    SkPathBuilder right_path;

    right_path.moveTo(right, bottom);
    // right_path.moveTo(right - 1 - scaled_horizontal_inset, bottom);

    right_path.arcTo({scaled_endcap_radius, scaled_endcap_radius}, 90, SkPathBuilder::kSmall_ArcSize,
                     SkPathDirection::kCW, {right - scaled_endcap_radius,
                     bottom - scaled_endcap_radius});
    // right_path.rCubicTo(-0.75 * scale, 0, -1.625 * scale, -0.5 * scale,
    // -2 * scale, -1.5 * scale);

    right_path.lineTo(right - scaled_endcap_radius, scaled_endcap_radius);
    // right_path.lineTo(
    //    right - 1 - scaled_horizontal_inset - (endcap_width - 2) * scale,
    //    2.5 * scale);

    right_path.arcTo({scaled_endcap_radius, scaled_endcap_radius}, 90, SkPathBuilder::kSmall_ArcSize,
                     SkPathDirection::kCCW, {right - scaled_endcap_radius * 2, 0});
    // right_path.rCubicTo(-0.375 * scale, -1 * scale, -1.25 * scale, -1.5 * scale,
    //                    -2 * scale, -1.5 * scale);

    right_path.lineTo(0, 0);
    right_path.lineTo(0, bottom);
    right_path.close();

    SkPathBuilder left_path;
    // const float scaled_endcap_width = 1 + endcap_width * scale;
    left_path.moveTo(scaled_endcap_radius * 2, 0);
    // left_path.moveTo(scaled_endcap_width + scaled_horizontal_inset, scale);

    left_path.arcTo({scaled_endcap_radius, scaled_endcap_radius}, 90, SkPathBuilder::kSmall_ArcSize,
                    SkPathDirection::kCCW, {scaled_endcap_radius, scaled_endcap_radius});
    // left_path.rCubicTo(-0.75 * scale, 0, -1.625 * scale, 0.5 * scale, -2 * scale,
    //                   1.5 * scale);

    left_path.lineTo(scaled_endcap_radius, bottom - scaled_endcap_radius);
    // left_path.lineTo(1 + scaled_horizontal_inset + 2 * scale,
    //                 bottom - 1.5 * scale);

    left_path.arcTo({scaled_endcap_radius, scaled_endcap_radius}, 90, SkPathBuilder::kSmall_ArcSize,
                    SkPathDirection::kCW, {0, bottom});
    // left_path.rCubicTo(-0.375 * scale, scale, -1.25 * scale, 1.5 * scale,
    //                   -2 * scale, 1.5 * scale);

    left_path.lineTo(right, bottom);
    left_path.lineTo(right, 0);
    left_path.close();

    return Op(left_path.detach(), right_path.detach(),
              SkPathOp::kIntersect_SkPathOp).value_or(SkPath());
}

void draw(SkCanvas* canvas) {
    SkPaint p;
    p.setColor(SK_ColorRED);
    p.setAntiAlias(true);
    p.setStyle(SkPaint::kStroke_Style);
    p.setStrokeWidth(1);
    SkPath path = GetInteriorPath(1.f, SkISize::Make(250, 36), 16);
    path = path.makeTransform(SkMatrix::Translate(0, 30));
    canvas->drawPath(path, p);

    p.setColor(SK_ColorBLUE);
    SkPath border_path = GetBorderPath(1.f, false, false, 16, SkISize::Make(250, 36));
    border_path = border_path.makeTransform(SkMatrix::Translate(0, 30));
    canvas->drawPath(border_path, p);

    //  canvas->drawLine(20, 20, 100, 100, p);
}
}  // END FIDDLE
