/*
 * 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/gm.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkColor.h"
#include "include/core/SkPaint.h"
#include "include/core/SkPathBuilder.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 "src/base/SkRandom.h"

namespace skiagm {

// Test out various combinations of nested rects, ovals and rrects.
class NestedGM : public GM {
public:
    NestedGM(bool doAA, bool flipped) : fDoAA(doAA), fFlipped(flipped) {
        this->setBGColor(0xFFDDDDDD);
    }

protected:
    SkString getName() const override {
        SkString name("nested");
        if (fFlipped) {
            name.append("_flipY");
        }
        if (fDoAA) {
            name.append("_aa");
        } else {
            name.append("_bw");
        }
        return name;
    }

    SkISize getISize() override { return SkISize::Make(kImageWidth, kImageHeight); }

    enum Shapes {
        kRect_Shape = 0,
        kRRect_Shape,
        kOval_Shape,
        kShapeCount
    };

    static void AddShape(SkPathBuilder* b, const SkRect& rect, Shapes shape, SkPathDirection dir) {
        switch (shape) {
            case kRect_Shape:
                b->addRect(rect, dir);
                break;
            case kRRect_Shape: {
                SkRRect rr;
                rr.setRectXY(rect, 5, 5);
                b->addRRect(rr, dir);
                break;
                }
            case kOval_Shape:
                b->addOval(rect, dir);
                break;
            default:
                break;
        }
    }

    void onDraw(SkCanvas* canvas) override {

        SkPaint shapePaint;
        shapePaint.setColor(SK_ColorBLACK);
        shapePaint.setAntiAlias(fDoAA);

        SkRect outerRect = SkRect::MakeWH(40, 40);

        SkRect innerRects[] = {
            { 10, 10, 30, 30 },     // small
            { .5f, 18, 4.5f, 22 }   // smaller and offset to left
        };

        // draw a background pattern to make transparency errors more apparent
        SkRandom rand;

        for (int y = 0; y < kImageHeight; y += 10) {
            for (int x = 0; x < kImageWidth; x += 10) {
                SkRect r = SkRect::MakeXYWH(SkIntToScalar(x),
                                            SkIntToScalar(y),
                                            10, 10);
                SkPaint p;
                p.setColor(rand.nextU() | 0xFF000000);
                canvas->drawRect(r, p);
            }
        }

        SkScalar xOff = 2, yOff = 2;
        for (int outerShape = 0; outerShape < kShapeCount; ++outerShape) {
            for (int innerShape = 0; innerShape < kShapeCount; ++innerShape) {
                for (size_t innerRect = 0; innerRect < std::size(innerRects); ++innerRect) {
                    SkPathBuilder builder;

                    AddShape(&builder, outerRect, (Shapes) outerShape, SkPathDirection::kCW);
                    AddShape(&builder, innerRects[innerRect], (Shapes) innerShape,
                             SkPathDirection::kCCW);

                    canvas->save();
                    if (fFlipped) {
                        canvas->scale(1.0f, -1.0f);
                        canvas->translate(xOff, -yOff - 40.0f);
                    } else {
                        canvas->translate(xOff, yOff);
                    }

                    canvas->drawPath(builder.detach(), shapePaint);
                    canvas->restore();

                    xOff += 45;
                }
            }

            xOff = 2;
            yOff += 45;
        }

    }

private:
    inline static constexpr int kImageWidth = 269;
    inline static constexpr int kImageHeight = 134;

    bool fDoAA;
    bool fFlipped;

    using INHERITED = GM;
};

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

DEF_GM( return new NestedGM(/* doAA = */ true,  /* flipped = */ false); )
DEF_GM( return new NestedGM(/* doAA = */ false, /* flipped = */ false); )
DEF_GM( return new NestedGM(/* doAA = */ true,  /* flipped = */ true); )
DEF_GM( return new NestedGM(/* doAA = */ false, /* flipped = */ true); )

DEF_SIMPLE_GM(nested_hairline_square, canvas, 64, 64) {
    // See crbug.com/1234194 - This should draw 1 row of 3 stroked squares, with a second 0.5px
    // shifted row of squares below it.
    auto drawEllipses = [&]() {
        canvas->save();
        // Originally the SVG string "M5,14H0V9h5V14Z M1,13h3v-3H1V13Z" but that just specifies a
        // 5px wide square outside a 3px wide square.
        SkPath square;
        square.addRect(SkRect::MakeLTRB(0.f, 9.f, 5.f, 14.f));
        square.addRect(SkRect::MakeLTRB(1.f, 10.f, 4.f, 13.f), SkPathDirection::kCCW);

        // From the bug, SVG viewbox was (0, 0, 24, 24), so the above coordinates are relative to
        // that, but the svg was then the child of a div that was 16x16, so it's scaled down. This
        // converts the 1px wide nested rects into subpixel nested rects.
        canvas->scale(16.f / 24.f, 16.f / 24.f);

        SkPaint paint;
        paint.setColor(SkColorSetARGB(255, 70, 70, 70));
        paint.setAntiAlias(true);

        // The original SVG drew 3 separate paths, but these were just translations of the original
        // path baked into a path string.
        canvas->drawPath(square, paint);
        canvas->translate(10.f, 0.f);
        canvas->drawPath(square, paint);
        canvas->translate(10.f, 0.f);
        canvas->drawPath(square, paint);

        canvas->restore();
    };

    drawEllipses();
    canvas->translate(0.5f, 16.f);
    drawEllipses();
}

}  // namespace skiagm
