/*
 * 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/SkMatrix.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/SkTileMode.h"
#include "include/core/SkTypes.h"
#include "include/effects/SkGradientShader.h"

constexpr SkColor gColors[] = {
    SK_ColorRED, SK_ColorYELLOW
};

// These annoying defines are necessary, because the only other alternative
// is to use SkIntToScalar(...) everywhere.
constexpr SkScalar sZero = 0;
constexpr SkScalar sHalf = SK_ScalarHalf;
constexpr SkScalar sOne = SK_Scalar1;

// These arrays define the gradient stop points
// as x1, y1, x2, y2 per gradient to draw.
constexpr SkPoint linearPts[][2] = {
    {{sZero, sZero}, {sOne,  sZero}},
    {{sZero, sZero}, {sZero, sOne}},
    {{sOne,  sZero}, {sZero, sZero}},
    {{sZero, sOne},  {sZero, sZero}},

    {{sZero, sZero}, {sOne,  sOne}},
    {{sOne,  sOne},  {sZero, sZero}},
    {{sOne,  sZero}, {sZero, sOne}},
    {{sZero, sOne},  {sOne,  sZero}}
};

constexpr SkPoint radialPts[][2] = {
    {{sZero, sHalf}, {sOne,  sHalf}},
    {{sHalf, sZero}, {sHalf, sOne}},
    {{sOne,  sHalf}, {sZero, sHalf}},
    {{sHalf, sOne},  {sHalf, sZero}},

    {{sZero, sZero}, {sOne,  sOne}},
    {{sOne,  sOne},  {sZero, sZero}},
    {{sOne,  sZero}, {sZero, sOne}},
    {{sZero, sOne},  {sOne,  sZero}}
};

// These define the pixels allocated to each gradient image.
constexpr SkScalar TESTGRID_X = SkIntToScalar(200);
constexpr SkScalar TESTGRID_Y = SkIntToScalar(200);

constexpr int IMAGES_X = 4;             // number of images per row

static sk_sp<SkShader> make_linear_gradient(const SkPoint pts[2], const SkMatrix& localMatrix) {
    return SkGradientShader::MakeLinear(pts, gColors, nullptr, std::size(gColors),
                                        SkTileMode::kClamp, 0, &localMatrix);
}

static sk_sp<SkShader> make_radial_gradient(const SkPoint pts[2], const SkMatrix& localMatrix) {
    SkPoint center;
    center.set(SkScalarAve(pts[0].fX, pts[1].fX),
               SkScalarAve(pts[0].fY, pts[1].fY));
    float radius = (center - pts[0]).length();
    return SkGradientShader::MakeRadial(center, radius, gColors, nullptr, std::size(gColors),
                                        SkTileMode::kClamp, 0, &localMatrix);
}

static void draw_gradients(SkCanvas* canvas,
                           sk_sp<SkShader> (*makeShader)(const SkPoint[2], const SkMatrix&),
                           const SkPoint ptsArray[][2], int numImages) {
    // Use some nice prime numbers for the rectangle and matrix with
    // different scaling along the x and y axes (which is the bug this
    // test addresses, where incorrect order of operations mixed up the axes)
    SkRect rectGrad = {
        SkIntToScalar(43),  SkIntToScalar(61),
        SkIntToScalar(181), SkIntToScalar(167) };
    SkMatrix shaderMat;
    shaderMat.setScale(rectGrad.width(), rectGrad.height());
    shaderMat.postTranslate(rectGrad.left(), rectGrad.top());

    canvas->save();
    for (int i = 0; i < numImages; i++) {
        // Advance line downwards if necessary.
        if (i % IMAGES_X == 0 && i != 0) {
            canvas->restore();
            canvas->translate(0, TESTGRID_Y);
            canvas->save();
        }

        SkPaint paint;
        paint.setShader(makeShader(*ptsArray, shaderMat));
        canvas->drawRect(rectGrad, paint);

        // Advance to next position.
        canvas->translate(TESTGRID_X, 0);
        ptsArray++;
    }
    canvas->restore();
}

DEF_SIMPLE_GM_BG(gradient_matrix, canvas, 800, 800, 0xFFDDDDDD) {
        draw_gradients(canvas, &make_linear_gradient,
                      linearPts, std::size(linearPts));

        canvas->translate(0, TESTGRID_Y);

        draw_gradients(canvas, &make_radial_gradient,
                      radialPts, std::size(radialPts));
}
