/*
 * 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.h"
#include "SkCanvas.h"
#include "SkGraphics.h"
#include "SkRandom.h"
#include "SkLayerDrawLooper.h"
#include "SkBlurMaskFilter.h"

static SkRect inset(const SkRect& r) {
    SkRect rect = r;
    rect.inset(r.width() / 8, r.height() / 8);
    return rect;
}

class PathInteriorGM : public skiagm::GM {
public:
    PathInteriorGM() {
        this->setBGColor(0xFFDDDDDD);
    }

protected:
    SkISize onISize() override {
        return SkISize::Make(770, 770);
    }

    SkString onShortName() override {
        return SkString("pathinterior");
    }

    void show(SkCanvas* canvas, const SkPath& path) {
        SkPaint paint;
        paint.setAntiAlias(true);

        SkRect rect;
#if 0
        bool hasInterior = path.hasRectangularInterior(&rect);
#else
        bool hasInterior = false;
#endif

        paint.setColor(hasInterior ? 0xFF8888FF : SK_ColorGRAY);
        canvas->drawPath(path, paint);
        paint.setStyle(SkPaint::kStroke_Style);
        paint.setColor(SK_ColorRED);
        canvas->drawPath(path, paint);

        if (hasInterior) {
            paint.setStyle(SkPaint::kFill_Style);
            paint.setColor(0x8800FF00);
            canvas->drawRect(rect, paint);
        }
    }

    void onDraw(SkCanvas* canvas) override {
        canvas->translate(8.5f, 8.5f);

        const SkRect rect = { 0, 0, 80, 80 };
        const SkScalar RAD = rect.width()/8;

        int i = 0;
        for (int insetFirst = 0; insetFirst <= 1; ++insetFirst) {
            for (int doEvenOdd = 0; doEvenOdd <= 1; ++doEvenOdd) {
                for (int outerRR = 0; outerRR <= 1; ++outerRR) {
                    for (int innerRR = 0; innerRR <= 1; ++innerRR) {
                        for (int outerCW = 0; outerCW <= 1; ++outerCW) {
                            for (int innerCW = 0; innerCW <= 1; ++innerCW) {
                                SkPath path;
                                path.setFillType(doEvenOdd ? SkPath::kEvenOdd_FillType : SkPath::kWinding_FillType);
                                SkPath::Direction outerDir = outerCW ? SkPath::kCW_Direction : SkPath::kCCW_Direction;
                                SkPath::Direction innerDir = innerCW ? SkPath::kCW_Direction : SkPath::kCCW_Direction;

                                SkRect r = insetFirst ? inset(rect) : rect;
                                if (outerRR) {
                                    path.addRoundRect(r, RAD, RAD, outerDir);
                                } else {
                                    path.addRect(r, outerDir);
                                }
                                r = insetFirst ? rect : inset(rect);
                                if (innerRR) {
                                    path.addRoundRect(r, RAD, RAD, innerDir);
                                } else {
                                    path.addRect(r, innerDir);
                                }

                                SkScalar dx = (i / 8) * rect.width() * 6 / 5;
                                SkScalar dy = (i % 8) * rect.height() * 6 / 5;
                                i++;
                                path.offset(dx, dy);

                                this->show(canvas, path);
                            }
                        }
                    }
                }
            }
        }
    }

private:

    typedef GM INHERITED;
};

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

static skiagm::GM* MyFactory(void*) { return new PathInteriorGM; }
static skiagm::GMRegistry reg(MyFactory);
