/*
 * Copyright 2016 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

/*
 * This GM presents a variety of different gradients with different
 * tile modes. Each entry in the table is a rectangle with a linear
 * gradient that spans from its left edge to its right edge. The rows
 * in the table represent different color/position configurations,
 * while the columns in the table represent different tile modes. In
 * order to highlight the differences between tile modes, the gradient
 * starts and ends at 30 pixel inset from either side of the rectangle.
 *
 *                              | Clamp         Repeat          Mirror
 * _____________________________|___________________________________________
 * 2-color                      | rect00        rect01          rect02
 * 3-color even                 | rect10        rect11          rect12
 * 3-color texture              | rect20        rect21          rect22
 * 5-color hard stop            | rect30        rect31          rect32
 * 4-color hard stop centered   | rect40        rect41          rect42
 * 3-color hard stop 001        | rect50        rect51          rect52
 * 3-color hard stop 011        | rect60        rect61          rect62
 * 4-color hard stop off-center | rect70        rect71          rect72
 *
 * The first three rows are cases covered by pre-hard-stop code; simple
 * 2-color gradients, 3-color gradients with the middle color centered,
 * and general gradients that are rendered from a texture atlas.
 *
 * The next four rows all deal with hard stop gradients. The fourth row
 * is a generic hard stop gradient, while the three subsequent rows deal
 * with special cases of hard stop gradients; centered hard stop gradients
 * (with t-values 0, 0.5, 0.5, 1), and two edge cases (with t-values
 * 0, 0, 1 and 0, 1, 1). The final row has a single off-center hard stop.
 */

#include "gm/gm.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkColor.h"
#include "include/core/SkPaint.h"
#include "include/core/SkPoint.h"
#include "include/core/SkRect.h"
#include "include/core/SkRefCnt.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/effects/SkGradient.h"

#include <array>

const int WIDTH  = 500;
const int HEIGHT = 500;

const int NUM_ROWS = 8;
const int NUM_COLS = 3;

const int CELL_WIDTH  = WIDTH  / NUM_COLS;
const int CELL_HEIGHT = HEIGHT / NUM_ROWS;

const int PAD_WIDTH  = 3;
const int PAD_HEIGHT = 3;

const int RECT_WIDTH  = CELL_WIDTH  - (2 * PAD_WIDTH);
const int RECT_HEIGHT = CELL_HEIGHT - (2 * PAD_HEIGHT);

static void shade_rect(SkCanvas* canvas, sk_sp<SkShader> shader, int cellRow, int cellCol) {
    SkPaint paint;
    paint.setShader(shader);

    SkRect rect = SkRect::MakeXYWH(SkIntToScalar(cellCol * CELL_WIDTH  + PAD_WIDTH),
                                   SkIntToScalar(cellRow * CELL_HEIGHT + PAD_HEIGHT),
                                   SkIntToScalar(RECT_WIDTH),
                                   SkIntToScalar(RECT_HEIGHT));

    canvas->drawRect(rect, paint);
}

static void create_gradient_points(int cellRow, int cellCol, SkPoint points[2]) {
    const int X_OFFSET = 30;

    auto x0 = SkIntToScalar(cellCol     * CELL_WIDTH  + PAD_WIDTH  + X_OFFSET);
    auto x1 = SkIntToScalar((cellCol+1) * CELL_WIDTH  - PAD_WIDTH  - X_OFFSET);
    auto y  = SkIntToScalar(cellRow     * CELL_HEIGHT + PAD_HEIGHT + RECT_HEIGHT/2);

    points[0] = SkPoint::Make(x0, y);
    points[1] = SkPoint::Make(x1, y);
}

class HardstopGradientShaderGM : public skiagm::GM {
public:
    HardstopGradientShaderGM() {

    }

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

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

    void onDraw(SkCanvas* canvas) override {
        SkPoint points[2];

        SkColor4f colors[] = {
            SkColors::kRed,
            SkColors::kGreen,
            SkColors::kBlue,
            SkColors::kYellow,
            SkColors::kMagenta,
        };

        SkScalar row3[] = {0.00f, 0.25f, 1.00f};
        SkScalar row4[] = {0.00f, 0.25f, 0.50f, 0.50f, 1.00f};
        SkScalar row5[] = {0.00f, 0.50f, 0.50f, 1.00f};
        SkScalar row6[] = {0.00f, 0.00f, 1.00f};
        SkScalar row7[] = {0.00f, 1.00f, 1.00f};
        SkScalar row8[] = {0.00f, 0.30f, 0.30f, 1.00f};

        std::array<SkScalar*, NUM_ROWS> positions = {
                nullptr,
                nullptr,
                row3,
                row4,
                row5,
                row6,
                row7,
                row8,
        };

        std::array<int, NUM_ROWS> numGradientColors = {
                2,
                3,
                3,
                5,
                4,
                3,
                3,
                4,
        };

        std::array<SkTileMode, NUM_COLS> tilemodes = {
                SkTileMode::kClamp,
                SkTileMode::kRepeat,
                SkTileMode::kMirror,
        };

        for (int cellRow = 0; cellRow < NUM_ROWS; cellRow++) {
            for (int cellCol = 0; cellCol < NUM_COLS; cellCol++) {
                create_gradient_points(cellRow, cellCol, points);

                size_t n = numGradientColors[cellRow];
                SkSpan<const float> pos;
                if (positions[cellRow]) {
                    pos = {positions[cellRow], n};
                }
                auto shader = SkShaders::LinearGradient(
                                points, {{{colors, n}, pos, tilemodes[cellCol]}, {}});

                shade_rect(canvas, shader, cellRow, cellCol);
            }
        }
    }

private:
    using INHERITED = skiagm::GM;
};

DEF_GM(return new HardstopGradientShaderGM;)
