/*
 * Copyright 2016 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/SkImageInfo.h"
#include "include/core/SkMatrix.h"
#include "include/core/SkPaint.h"
#include "include/core/SkPoint.h"
#include "include/core/SkRRect.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/SkTArray.h"
#include "include/utils/SkRandom.h"

namespace skiagm {

/*
 * This is the base class for two GMs that cover various corner cases with primitive Skia shapes
 * (zero radius, near-zero radius, inner shape overlap, etc.) It uses an xfermode of darken to help
 * double-blended and/or dropped pixels stand out.
 */
class ShapesGM : public GM {
protected:
    ShapesGM(const char* name, bool antialias) : fName(name), fAntialias(antialias) {
        if (!antialias) {
            fName.append("_bw");
        }
    }

    SkString onShortName() final { return fName; }
    SkISize onISize() override { return SkISize::Make(500, 500); }

    void onOnceBeforeDraw() override {
        fShapes.push_back().setOval(SkRect::MakeXYWH(-5, 25, 200, 100));
        fRotations.push_back(21);

        fShapes.push_back().setRect(SkRect::MakeXYWH(95, 75, 125, 100));
        fRotations.push_back(94);

        fShapes.push_back().setRectXY(SkRect::MakeXYWH(0, 75, 150, 100), 1e-5f, 1e-5f);
        fRotations.push_back(132);

        fShapes.push_back().setRectXY(SkRect::MakeXYWH(15, -20, 100, 100), 20, 15);
        fRotations.push_back(282);

        fSimpleShapeCount = fShapes.size();

        fShapes.push_back().setNinePatch(SkRect::MakeXYWH(140, -50, 90, 110), 10, 5, 25, 35);
        fRotations.push_back(0);

        fShapes.push_back().setNinePatch(SkRect::MakeXYWH(160, -60, 60, 90), 10, 60, 50, 30);
        fRotations.push_back(-35);

        fShapes.push_back().setNinePatch(SkRect::MakeXYWH(220, -120, 60, 90), 1, 89, 59, 1);
        fRotations.push_back(65);

        SkVector radii[4] = {{4, 6}, {12, 8}, {24, 16}, {32, 48}};
        fShapes.push_back().setRectRadii(SkRect::MakeXYWH(150, -129, 80, 160), radii);
        fRotations.push_back(265);

        SkVector radii2[4] = {{0, 0}, {80, 60}, {0, 0}, {80, 60}};
        fShapes.push_back().setRectRadii(SkRect::MakeXYWH(180, -30, 80, 60), radii2);
        fRotations.push_back(295);

        fPaint.setAntiAlias(fAntialias);
    }

    void onDraw(SkCanvas* canvas) override {
        canvas->clear(SK_ColorWHITE);

        canvas->save();
        canvas->translate(canvas->imageInfo().width() / 2.f, canvas->imageInfo().height() / 2.f);
        this->drawShapes(canvas);
        canvas->restore();
    }

    virtual void drawShapes(SkCanvas* canvas) const = 0;

protected:
    SkString             fName;
    bool                 fAntialias;
    SkPaint              fPaint;
    SkTArray<SkRRect>    fShapes;
    SkTArray<SkScalar>   fRotations;
    int                  fSimpleShapeCount;

private:
    using INHERITED = GM;
};

class SimpleShapesGM : public ShapesGM {
public:
    SimpleShapesGM(bool antialias) : INHERITED("simpleshapes", antialias) {}

private:
    void drawShapes(SkCanvas* canvas) const override {
        SkRandom rand(2);
        for (int i = 0; i < fShapes.size(); i++) {
            SkPaint paint(fPaint);
            paint.setColor(rand.nextU() & ~0x808080);
            paint.setAlphaf(0.5f);  // Use alpha to detect double blends.
            const SkRRect& shape = fShapes[i];
            canvas->save();
            canvas->rotate(fRotations[i]);
            switch (shape.getType()) {
                case SkRRect::kRect_Type:
                    canvas->drawRect(shape.rect(), paint);
                    break;
                case SkRRect::kOval_Type:
                    canvas->drawOval(shape.rect(), paint);
                    break;
                default:
                    canvas->drawRRect(shape, paint);
                    break;
            }
            canvas->restore();
        }
    }

    using INHERITED = ShapesGM;
};

class InnerShapesGM : public ShapesGM {
public:
    InnerShapesGM(bool antialias) : INHERITED("innershapes", antialias) {}

private:
    void drawShapes(SkCanvas* canvas) const override {
        SkRandom rand;
        for (int i = 0; i < fShapes.size(); i++) {
            const SkRRect& outer = fShapes[i];
            const SkRRect& inner = fShapes[(i * 7 + 11) % fSimpleShapeCount];
            float s = 0.95f * std::min(outer.rect().width() / inner.rect().width(),
                                       outer.rect().height() / inner.rect().height());
            SkMatrix innerXform;
            float dx = (rand.nextF() - 0.5f) * (outer.rect().width() - s * inner.rect().width());
            float dy = (rand.nextF() - 0.5f) * (outer.rect().height() - s * inner.rect().height());
            // Fixup inner rects so they don't reach outside the outer rect.
            switch (i) {
                case 0:
                    s *= .85f;
                    break;
                case 8:
                    s *= .4f;
                    dx = dy = 0;
                    break;
                case 5:
                    s *= .75f;
                    dx = dy = 0;
                    break;
                case 6:
                    s *= .65f;
                    dx = -5;
                    dy = 10;
                    break;
            }
            innerXform.setTranslate(outer.rect().centerX() + dx, outer.rect().centerY() + dy);
            if (s < 1) {
                innerXform.preScale(s, s);
            }
            innerXform.preTranslate(-inner.rect().centerX(), -inner.rect().centerY());
            SkRRect xformedInner;
            inner.transform(innerXform, &xformedInner);
            SkPaint paint(fPaint);
            paint.setColor(rand.nextU() & ~0x808080);
            paint.setAlphaf(0.5f);  // Use alpha to detect double blends.
            canvas->save();
            canvas->rotate(fRotations[i]);
            canvas->drawDRRect(outer, xformedInner, paint);
            canvas->restore();
        }
    }

    using INHERITED = ShapesGM;
};

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

DEF_GM( return new SimpleShapesGM(true); )
DEF_GM( return new SimpleShapesGM(false); )
DEF_GM( return new InnerShapesGM(true); )
DEF_GM( return new InnerShapesGM(false); )

}  // namespace skiagm
