/*
 * 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"

namespace skiagm {

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;
}

SkPaint::Style styles[] = {
        SkPaint::kStroke_Style,
        SkPaint::kStrokeAndFill_Style,
        SkPaint::kFill_Style
};
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;


class InversePathsGM : public GM {
public:
    InversePathsGM() {

    }

protected:
    virtual uint32_t onGetFlags() const SK_OVERRIDE {
        return kSkipTiled_Flag;
    }

    virtual SkString onShortName() {
        return SkString("inverse_paths");
    }

    virtual SkISize onISize() {
        return SkISize::Make(800, 900);
    }

    virtual void onDraw(SkCanvas* canvas) {
        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]);

                    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);
            }
        }
    }

private:
    typedef GM INHERITED;
};

DEF_GM( return new InversePathsGM; )
}
