/*
 * Copyright 2011 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/SkMatrix.h"
#include "include/core/SkPaint.h"
#include "include/core/SkPathBuilder.h"
#include "include/core/SkPoint.h"
#include "include/core/SkRect.h"
#include "include/core/SkScalar.h"
#include "include/core/SkShader.h"
#include "include/core/SkSize.h"
#include "include/core/SkString.h"
#include "include/core/SkTileMode.h"
#include "include/core/SkTypes.h"
#include "include/effects/SkGradient.h"

namespace skiagm {

class FillTypePerspGM : public GM {
    SkPath fPath;
public:
    FillTypePerspGM() {}

    void makePath() {
        if (fPath.isEmpty()) {
            const SkScalar radius = SkIntToScalar(45);
            fPath = SkPathBuilder().addCircle(SkIntToScalar(50), SkIntToScalar(50), radius)
                                   .addCircle(SkIntToScalar(100), SkIntToScalar(100), radius)
                                   .detach();
        }
    }

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

    SkISize getISize() override { return SkISize::Make(835, 840); }

    void showPath(SkCanvas* canvas, int x, int y, SkPathFillType ft,
                  SkScalar scale, const SkPaint& paint) {
        const SkRect r = { 0, 0, SkIntToScalar(150), SkIntToScalar(150) };

        canvas->save();
        canvas->translate(SkIntToScalar(x), SkIntToScalar(y));
        canvas->clipRect(r);
        canvas->drawColor(SK_ColorWHITE);
        fPath.setFillType(ft);
        canvas->translate(r.centerX(), r.centerY());
        canvas->scale(scale, scale);
        canvas->translate(-r.centerX(), -r.centerY());
        canvas->drawPath(fPath, paint);
        canvas->restore();
    }

    void showFour(SkCanvas* canvas, SkScalar scale, bool aa) {
        SkPaint paint;
        SkPoint center = SkPoint::Make(SkIntToScalar(100), SkIntToScalar(100));
        SkColor4f colors[] = {SkColors::kBlue, SkColors::kRed, SkColors::kGreen};
        SkScalar pos[] = {0, SK_ScalarHalf, SK_Scalar1};
        paint.setShader(SkShaders::RadialGradient(center, 100,
                                                  {{colors, pos, SkTileMode::kClamp}, {}}));
        paint.setAntiAlias(aa);

        showPath(canvas,   0,   0, SkPathFillType::kWinding,
                 scale, paint);
        showPath(canvas, 200,   0, SkPathFillType::kEvenOdd,
                 scale, paint);
        showPath(canvas,  00, 200, SkPathFillType::kInverseWinding,
                 scale, paint);
        showPath(canvas, 200, 200, SkPathFillType::kInverseEvenOdd,
                 scale, paint);
    }

    void onDraw(SkCanvas* canvas) override {
        this->makePath();

        // do perspective drawPaint as the background;
        SkPaint bkgnrd;
        SkPoint center = SkPoint::Make(SkIntToScalar(100),
                                       SkIntToScalar(100));
        SkColor4f colors[] = {SkColors::kBlack, SkColors::kCyan,
                            SkColors::kYellow, SkColors::kWhite};
        SkScalar pos[] = {0, SK_ScalarHalf / 2,
                          3 * SK_ScalarHalf / 2, SK_Scalar1};
        bkgnrd.setShader(SkShaders::RadialGradient(center, 1000,
                                                   {{colors, pos, SkTileMode::kClamp}, {}}));
        canvas->save();
            canvas->translate(SkIntToScalar(100), SkIntToScalar(100));
            SkMatrix mat;
            mat.reset();
            mat.setPerspY(SK_Scalar1 / 1000);
            canvas->concat(mat);
            canvas->drawPaint(bkgnrd);
        canvas->restore();

        // draw the paths in perspective
        SkMatrix persp;
        persp.reset();
        persp.setPerspX(-SK_Scalar1 / 1800);
        persp.setPerspY(SK_Scalar1 / 500);
        canvas->concat(persp);

        canvas->translate(SkIntToScalar(20), SkIntToScalar(20));
        const SkScalar scale = SkIntToScalar(5)/4;

        showFour(canvas, SK_Scalar1, false);
        canvas->translate(SkIntToScalar(450), 0);
        showFour(canvas, scale, false);

        canvas->translate(SkIntToScalar(-450), SkIntToScalar(450));
        showFour(canvas, SK_Scalar1, true);
        canvas->translate(SkIntToScalar(450), 0);
        showFour(canvas, scale, true);
    }

private:
    using INHERITED = GM;
};

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

DEF_GM( return new FillTypePerspGM; )

}  // namespace skiagm
