/*
 * 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.h"
#include "SkCanvas.h"
#include "SkPath.h"
#include "SkDashPathEffect.h"

static SkPath generate_square(SkScalar cx, SkScalar cy, SkScalar w) {
    SkRect rect = SkRect::MakeXYWH(cx - w / 2, cy - w / 2, w, w);
    SkPath path;
    path.addRect(rect);
    return path;
}

static SkPath generate_rect_line(SkScalar cx, SkScalar cy, SkScalar l) {
    SkRect rect = SkRect::MakeXYWH(cx - l / 2, cy, l, 0);
    SkPath path;
    path.addRect(rect);
    return path;
}

static SkPath generate_circle(SkScalar cx, SkScalar cy, SkScalar d) {
    SkPath path;
    path.addCircle(cx, cy, d/2, SkPath::kCW_Direction);
    return path;
}

static SkPath generate_line(SkScalar cx, SkScalar cy, SkScalar l) {
    SkPath path;
    path.moveTo(cx - l / 2, cy);
    path.lineTo(cx + l / 2, cy);
    return path;
}

namespace {
struct Style {
    Style(SkPaint::Style paintStyle, sk_sp<SkPathEffect> pe = sk_sp<SkPathEffect>())
        : fPaintStyle(paintStyle)
        , fPathEffect(std::move(pe)) {}
    SkPaint::Style      fPaintStyle;
    sk_sp<SkPathEffect> fPathEffect;
};

sk_sp<SkPathEffect> make_dash() {
    constexpr SkScalar kIntervals[] = { 4.f, 3.f };
    return SkDashPathEffect::Make(kIntervals, SK_ARRAY_COUNT(kIntervals), 0);
}

Style styles[] {
    {SkPaint::kStroke_Style},
    {SkPaint::kStrokeAndFill_Style},
    {SkPaint::kFill_Style},
    {SkPaint::kStroke_Style, make_dash()},
};

SkScalar pathSizes[] = {
        40,
        10,
        0
};
SkScalar strokeWidths[] = {
        10,
        0
};
SkPath ((*paths[])(SkScalar, SkScalar, SkScalar)) = {
        generate_square,
        generate_rect_line,
        generate_circle,
        generate_line
};

const SkScalar slideWidth = 90, slideHeight = 90;
const SkScalar slideBoundary = 5;

}  // namespace

DEF_SIMPLE_GM(inverse_paths, canvas, 800, 1200) {
    SkScalar cx = slideWidth / 2 + slideBoundary;
    SkScalar cy = slideHeight / 2 + slideBoundary;
    SkScalar dx = slideWidth + 2 * slideBoundary;
    SkScalar dy = slideHeight + 2 * slideBoundary;

    SkRect clipRect = SkRect::MakeLTRB(slideBoundary, slideBoundary,
                                       slideBoundary + slideWidth,
                                       slideBoundary + slideHeight);
    SkPaint clipPaint;
    clipPaint.setStyle(SkPaint::kStroke_Style);
    clipPaint.setStrokeWidth(SkIntToScalar(2));

    SkPaint outlinePaint;
    outlinePaint.setColor(0x40000000);
    outlinePaint.setStyle(SkPaint::kStroke_Style);
    outlinePaint.setStrokeWidth(SkIntToScalar(0));

    for (size_t styleIndex = 0; styleIndex < SK_ARRAY_COUNT(styles);
            styleIndex++) {
        for (size_t sizeIndex = 0; sizeIndex < SK_ARRAY_COUNT(pathSizes);
                sizeIndex++) {
            SkScalar size = pathSizes[sizeIndex];

            canvas->save();

            for (size_t widthIndex = 0;
                    widthIndex < SK_ARRAY_COUNT(strokeWidths);
                    widthIndex++) {
                SkPaint paint;
                paint.setColor(0xff007000);
                paint.setStrokeWidth(strokeWidths[widthIndex]);
                paint.setStyle(styles[styleIndex].fPaintStyle);
                paint.setPathEffect(styles[styleIndex].fPathEffect);

                for (size_t pathIndex = 0;
                        pathIndex < SK_ARRAY_COUNT(paths);
                        pathIndex++) {
                    canvas->drawRect(clipRect, clipPaint);

                    canvas->save();
                    canvas->clipRect(clipRect);

                    SkPath path = paths[pathIndex](cx, cy, size);
                    path.setFillType(SkPath::kInverseWinding_FillType);
                    canvas->drawPath(path, paint);

                    path.setFillType(SkPath::kWinding_FillType);
                    canvas->drawPath(path, outlinePaint);

                    canvas->restore();
                    canvas->translate(dx, 0);
                }
            }
            canvas->restore();
            canvas->translate(0, dy);
        }
    }
}
