/*
 * Copyright 2018 Google LLC
 *
 * 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/SkBlendMode.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkColor.h"
#include "include/core/SkFont.h"
#include "include/core/SkMatrix.h"
#include "include/core/SkPaint.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/SkTypeface.h"
#include "include/core/SkTypes.h"
#include "include/effects/SkGradient.h"
#include "include/gpu/ganesh/GrRecordingContext.h"
#include "include/private/gpu/ganesh/GrTypesPriv.h"
#include "src/core/SkCanvasPriv.h"
#include "src/gpu/ganesh/GrCanvas.h"
#include "src/gpu/ganesh/GrPaint.h"
#include "src/gpu/ganesh/SkGr.h"
#include "src/gpu/ganesh/SurfaceDrawContext.h"
#include "tools/ToolUtils.h"
#include "tools/fonts/FontToolUtils.h"

#include <array>
#include <utility>

static constexpr SkScalar kTileWidth = 40;
static constexpr SkScalar kTileHeight = 30;

static constexpr int kRowCount = 4;
static constexpr int kColCount = 3;

static void draw_text(SkCanvas* canvas, const char* text) {
    SkFont font(ToolUtils::DefaultPortableTypeface(), 12);
    canvas->drawString(text, 0, 0, font, SkPaint());
}

static void draw_gradient_tiles(SkCanvas* canvas, bool alignGradients) {
    // Always draw the same gradient
    static constexpr SkPoint pts[] = { {0.f, 0.f}, {0.25f * kTileWidth, 0.25f * kTileHeight} };
    static constexpr SkColor4f colors[] = { SkColors::kBlue, SkColors::kWhite };

    auto sdc = skgpu::ganesh::TopDeviceSurfaceDrawContext(canvas);

    auto gradient = SkShaders::LinearGradient(pts, {{colors, {}, SkTileMode::kMirror}, {}});
    SkPaint paint;
    paint.setShader(gradient);

    for (int i = 0; i < kRowCount; ++i) {
        for (int j = 0; j < kColCount; ++j) {
            SkRect tile = SkRect::MakeWH(kTileWidth, kTileHeight);
            if (alignGradients) {
                tile.offset(j * kTileWidth, i * kTileHeight);
            } else {
                canvas->save();
                canvas->translate(j * kTileWidth, i * kTileHeight);
            }

            unsigned aa = SkCanvas::kNone_QuadAAFlags;
            if (i == 0) {
                aa |= SkCanvas::kTop_QuadAAFlag;
            }
            if (i == kRowCount - 1) {
                aa |= SkCanvas::kBottom_QuadAAFlag;
            }
            if (j == 0) {
                aa |= SkCanvas::kLeft_QuadAAFlag;
            }
            if (j == kColCount - 1) {
                aa |= SkCanvas::kRight_QuadAAFlag;
            }

            if (sdc) {
                // Use non-public API to leverage general GrPaint capabilities
                const SkMatrix& view = canvas->getTotalMatrix();
                SkSurfaceProps props;
                GrPaint grPaint;
                SkPaintToGrPaint(sdc, paint, view, &grPaint);
                sdc->fillRectWithEdgeAA(nullptr, std::move(grPaint),
                                        static_cast<GrQuadAAFlags>(aa), view, tile);
            } else {
                // Fallback to solid color on raster backend since the public API only has color
                SkColor color = alignGradients ? SK_ColorBLUE
                                               : (i * kColCount + j) % 2 == 0 ? SK_ColorBLUE
                                                                              : SK_ColorWHITE;
                canvas->experimental_DrawEdgeAAQuad(
                        tile, nullptr, static_cast<SkCanvas::QuadAAFlags>(aa), color,
                        SkBlendMode::kSrcOver);
            }

            if (!alignGradients) {
                // Pop off the matrix translation when drawing unaligned
                canvas->restore();
            }
        }
    }
}

static void draw_color_tiles(SkCanvas* canvas, bool multicolor) {
    for (int i = 0; i < kRowCount; ++i) {
        for (int j = 0; j < kColCount; ++j) {
            SkRect tile = SkRect::MakeXYWH(j * kTileWidth, i * kTileHeight, kTileWidth, kTileHeight);

            SkColor4f color;
            if (multicolor) {
                color = {(i + 1.f) / kRowCount, (j + 1.f) / kColCount, .4f, 1.f};
            } else {
                color = {.2f, .8f, .3f, 1.f};
            }

            unsigned aa = SkCanvas::kNone_QuadAAFlags;
            if (i == 0) {
                aa |= SkCanvas::kTop_QuadAAFlag;
            }
            if (i == kRowCount - 1) {
                aa |= SkCanvas::kBottom_QuadAAFlag;
            }
            if (j == 0) {
                aa |= SkCanvas::kLeft_QuadAAFlag;
            }
            if (j == kColCount - 1) {
                aa |= SkCanvas::kRight_QuadAAFlag;
            }

            canvas->experimental_DrawEdgeAAQuad(
                    tile, nullptr, static_cast<SkCanvas::QuadAAFlags>(aa), color.toSkColor(),
                    SkBlendMode::kSrcOver);
        }
    }
}

static void draw_tile_boundaries(SkCanvas* canvas, const SkMatrix& local) {
    // Draw grid of red lines at interior tile boundaries.
    static constexpr SkScalar kLineOutset = 10.f;
    SkPaint paint;
    paint.setAntiAlias(true);
    paint.setColor(SK_ColorRED);
    paint.setStyle(SkPaint::kStroke_Style);
    paint.setStrokeWidth(0.f);
    for (int x = 1; x < kColCount; ++x) {
        SkPoint pts[] = {{x * kTileWidth, 0}, {x * kTileWidth, kRowCount * kTileHeight}};
        local.mapPoints(pts);
        SkVector v = pts[1] - pts[0];
        v.setLength(v.length() + kLineOutset);
        canvas->drawLine(pts[1] - v, pts[0] + v, paint);
    }
    for (int y = 1; y < kRowCount; ++y) {
        SkPoint pts[] = {{0, y * kTileHeight}, {kTileWidth * kColCount, y * kTileHeight}};
        local.mapPoints(pts);
        SkVector v = pts[1] - pts[0];
        v.setLength(v.length() + kLineOutset);
        canvas->drawLine(pts[1] - v, pts[0] + v, paint);
    }
}

// Tile renderers (column variation)
typedef void (*TileRenderer)(SkCanvas*);
static constexpr auto kTileSets = std::to_array<TileRenderer>({
        TileRenderer([](SkCanvas* canvas) { draw_gradient_tiles(canvas, /* aligned */ false); }),
        TileRenderer([](SkCanvas* canvas) { draw_gradient_tiles(canvas, /* aligned */ true); }),
        TileRenderer([](SkCanvas* canvas) { draw_color_tiles(canvas, /* multicolor */ false); }),
        TileRenderer([](SkCanvas* canvas) { draw_color_tiles(canvas, /* multicolor */ true); }),
});
static constexpr auto kTileSetNames = std::to_array<const char*>({
        "Local",
        "Aligned",
        "Green",
        "Multicolor",
});
static_assert(std::size(kTileSets) == std::size(kTileSetNames), "Count mismatch");

namespace skiagm {

class DrawQuadSetGM : public GM {
private:
    SkString getName() const override { return SkString("draw_quad_set"); }
    SkISize getISize() override { return SkISize::Make(800, 800); }

    void onDraw(SkCanvas* canvas) override {
        std::array<SkMatrix, 5> rowMatrices;
        // Identity
        rowMatrices[0].setIdentity();
        // Translate/scale
        rowMatrices[1].setTranslate(5.5f, 20.25f);
        rowMatrices[1].postScale(.9f, .7f);
        // Rotation
        rowMatrices[2].setRotate(20.0f);
        rowMatrices[2].preTranslate(15.f, -20.f);
        // Skew
        rowMatrices[3].setSkew(.5f, .25f);
        rowMatrices[3].preTranslate(-30.f, 0.f);
        // Perspective
        const std::array<SkPoint, 4> src = SkRect::MakeWH(kColCount * kTileWidth,
                                                          kRowCount * kTileHeight).toQuad();
        SkPoint dst[4] = {{0, 0},
                          {kColCount * kTileWidth + 10.f, 15.f},
                          {kColCount * kTileWidth - 28.f, kRowCount * kTileHeight + 40.f},
                          {25.f, kRowCount * kTileHeight - 15.f}};
        SkAssertResult(rowMatrices[4].setPolyToPoly(src, dst));
        rowMatrices[4].preTranslate(0.f, +10.f);
        static constexpr auto matrixNames = std::to_array<const char*>({
                "Identity",
                "T+S",
                "Rotate",
                "Skew",
                "Perspective",
        });
        static_assert(std::size(matrixNames) == std::size(rowMatrices), "Count mismatch");

        // Print a column header
        canvas->save();
        canvas->translate(110.f, 20.f);
        for (size_t j = 0; j < std::size(kTileSetNames); ++j) {
            draw_text(canvas, kTileSetNames[j]);
            canvas->translate(kColCount * kTileWidth + 30.f, 0.f);
        }
        canvas->restore();
        canvas->translate(0.f, 40.f);

        // Render all tile variations
        for (size_t i = 0; i < std::size(rowMatrices); ++i) {
            canvas->save();
            canvas->translate(10.f, 0.5f * kRowCount * kTileHeight);
            draw_text(canvas, matrixNames[i]);

            canvas->translate(100.f, -0.5f * kRowCount * kTileHeight);
            for (size_t j = 0; j < std::size(kTileSets); ++j) {
                canvas->save();
                draw_tile_boundaries(canvas, rowMatrices[i]);

                canvas->concat(rowMatrices[i]);
                kTileSets[j](canvas);
                // Undo the local transformation
                canvas->restore();
                // And advance to the next column
                canvas->translate(kColCount * kTileWidth + 30.f, 0.f);
            }
            // Reset back to the left edge
            canvas->restore();
            // And advance to the next row
            canvas->translate(0.f, kRowCount * kTileHeight + 20.f);
        }
    }
};

DEF_GM(return new DrawQuadSetGM();)

} // namespace skiagm
