/*
 * 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
 *
 * 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).
 */

#include "gm.h"

#include "SkGradientShader.h"

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

const int NUM_ROWS = 7;
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 onShortName() override {
        return SkString("hardstop_gradients");
    }

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

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

        SkColor colors[] = {
            SK_ColorRED,
            SK_ColorGREEN,
            SK_ColorBLUE,
            SK_ColorYELLOW,
            SK_ColorMAGENTA,
        };

        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* positions[NUM_ROWS] = {
            nullptr,
            nullptr,
            row3,
            row4,
            row5,
            row6,
            row7,
        };

        int numGradientColors[NUM_ROWS] = {
            2,
            3,
            3,
            5,
            4,
            3,
            3,
        };

        SkShader::TileMode tilemodes[NUM_COLS] = {
            SkShader::kClamp_TileMode,
            SkShader::kRepeat_TileMode,
            SkShader::kMirror_TileMode,
        };

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

                auto shader = SkGradientShader::MakeLinear(
                                points,
                                colors,
                                positions[cellRow],
                                numGradientColors[cellRow],
                                tilemodes[cellCol],
                                0,
                                nullptr);

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

private:
    typedef skiagm::GM INHERITED;
};

DEF_GM(return new HardstopGradientShaderGM;)
