/*
 * Copyright 2012 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/SkPath.h"
#include "include/core/SkPathUtils.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/base/SkTemplates.h"

#include <float.h>

using namespace skia_private;

#define STROKE_WIDTH    SkIntToScalar(20)

static void draw_path(SkCanvas* canvas, const SkPath& path, const SkRect& rect,
                      SkPaint::Join join, int doFill) {
    SkPaint paint;
    paint.setAntiAlias(true);
    paint.setStyle(doFill ? SkPaint::kStrokeAndFill_Style : SkPaint::kStroke_Style);

    paint.setColor(SK_ColorGRAY);
    paint.setStrokeWidth(STROKE_WIDTH);
    paint.setStrokeJoin(join);
    canvas->drawRect(rect, paint);

    paint.setStyle(SkPaint::kStroke_Style);
    paint.setStrokeWidth(0);
    paint.setColor(SK_ColorRED);
    canvas->drawPath(path, paint);

    paint.setStrokeWidth(3);
    paint.setStrokeJoin(SkPaint::kMiter_Join);
    canvas->drawPoints(SkCanvas::kPoints_PointMode, path.points(), paint);
}

/*
 *  Test calling SkStroker for rectangles. Cases to cover:
 *
 *  geometry: normal, small (smaller than stroke-width), empty, inverted
 *  joint-type for the corners
 */
class StrokeRectGM : public skiagm::GM {
public:
    StrokeRectGM() {}

protected:
    SkString getName() const override { return SkString("strokerect"); }

    SkISize getISize() override { return SkISize::Make(1400, 740); }

    void onDraw(SkCanvas* canvas) override {
        canvas->drawColor(SK_ColorWHITE);
        canvas->translate(STROKE_WIDTH*3/2, STROKE_WIDTH*3/2);

        SkPaint paint;
        paint.setStyle(SkPaint::kStroke_Style);
        paint.setStrokeWidth(STROKE_WIDTH);

        constexpr SkPaint::Join gJoins[] = {
            SkPaint::kMiter_Join, SkPaint::kRound_Join, SkPaint::kBevel_Join
        };

        constexpr SkScalar W = 80;
        constexpr SkScalar H = 80;
        constexpr SkRect gRects[] = {
            { 0, 0, W, H },
            { W, 0, 0, H },
            { 0, H, W, 0 },
            { 0, 0, STROKE_WIDTH, H },
            { 0, 0, W, STROKE_WIDTH },
            { 0, 0, STROKE_WIDTH/2, STROKE_WIDTH/2 },
            { 0, 0, W, 0 },
            { 0, 0, 0, H },
            { 0, 0, 0, 0 },
            { 0, 0, W, FLT_EPSILON },
            { 0, 0, FLT_EPSILON, H },
            { 0, 0, FLT_EPSILON, FLT_EPSILON },
        };

        for (int doFill = 0; doFill <= 1; ++doFill) {
            for (size_t i = 0; i < std::size(gJoins); ++i) {
                SkPaint::Join join = gJoins[i];
                paint.setStrokeJoin(join);

                SkAutoCanvasRestore acr(canvas, true);
                for (size_t j = 0; j < std::size(gRects); ++j) {
                    const SkRect& r = gRects[j];

                    SkPath fillPath = skpathutils::FillPathWithPaint(SkPath::Rect(r), paint);
                    draw_path(canvas, fillPath, r, join, doFill);

                    canvas->translate(W + 2 * STROKE_WIDTH, 0);
                }
                acr.restore();
                canvas->translate(0, H + 2 * STROKE_WIDTH);
            }
            paint.setStyle(SkPaint::kStrokeAndFill_Style);
        }
    }

private:
    using INHERITED = GM;
};
DEF_GM(return new StrokeRectGM;)

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

/*
 *  Exercise rect-stroking (which is specialized from paths) when the resulting stroke-width is
 *  non-square. See https://bugs.chromium.org/p/skia/issues/detail?id=5408
 */
DEF_SIMPLE_GM(strokerect_anisotropic_5408, canvas, 200, 50) {
    SkPaint p;
    p.setStyle(SkPaint::kStroke_Style);
    p.setStrokeWidth(6);

    canvas->scale(10, 1);
    SkRect r = SkRect::MakeXYWH(5, 20, 10, 10);
    canvas->drawRect(r, p);
}
