/*
 * Copyright 2018 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/SkFont.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/core/SkTypes.h"
#include "include/effects/SkGradientShader.h"
#include "tools/ToolUtils.h"

// NOTE: The positions define hardstops for the red and green borders. For the repeating degenerate
// gradients, that means the red and green are never visible, so the average color used should only
// be based off of the white, blue, black blend.
static const SkColor COLORS[] = { SK_ColorRED, SK_ColorWHITE, SK_ColorBLUE,
                                  SK_ColorBLACK, SK_ColorGREEN };
static const SkScalar POS[] = { 0.0, 0.0, 0.5, 1.0, 1.0 };
static const int COLOR_CT = std::size(COLORS);

static const SkTileMode TILE_MODES[] = { SkTileMode::kDecal,
                                         SkTileMode::kRepeat,
                                         SkTileMode::kMirror,
                                         SkTileMode::kClamp };
static const char* TILE_NAMES[] = { "decal", "repeat", "mirror", "clamp" };
static const int TILE_MODE_CT = std::size(TILE_MODES);

static constexpr int TILE_SIZE = 100;
static constexpr int TILE_GAP = 10;

static const SkPoint CENTER = SkPoint::Make(TILE_SIZE / 2, TILE_SIZE / 2);

typedef sk_sp<SkShader> (*GradientFactory)(SkTileMode tm);

static void draw_tile_header(SkCanvas* canvas) {
    canvas->save();

    SkFont font(ToolUtils::create_portable_typeface(), 12);
    for (int i = 0; i < TILE_MODE_CT; ++i) {
        canvas->drawString(TILE_NAMES[i], 0, 0, font, SkPaint());
        canvas->translate(TILE_SIZE + TILE_GAP, 0);
    }

    canvas->restore();

    // Now adjust to start at rows below the header
    canvas->translate(0, 2 * TILE_GAP);
}

static void draw_row(SkCanvas* canvas, const char* desc, GradientFactory factory) {
    canvas->save();

    SkPaint text;
    text.setAntiAlias(true);

    SkFont font(ToolUtils::create_portable_typeface(), 12);

    canvas->translate(0, TILE_GAP);
    canvas->drawString(desc, 0, 0, font, text);
    canvas->translate(0, TILE_GAP);

    SkPaint paint;
    paint.setColor(SK_ColorBLACK);
    paint.setStyle(SkPaint::kStrokeAndFill_Style);
    paint.setStrokeWidth(2.0f);

    for (int i = 0; i < TILE_MODE_CT; ++i) {
        paint.setShader(factory(TILE_MODES[i]));
        canvas->drawRect(SkRect::MakeWH(TILE_SIZE, TILE_SIZE), paint);
        canvas->translate(TILE_SIZE + TILE_GAP, 0);
    }

    canvas->restore();

    // Now adjust to start the next row below this one (1 gap for text and 2 gap for margin)
    canvas->translate(0, 3 * TILE_GAP + TILE_SIZE);
}

static sk_sp<SkShader> make_linear(SkTileMode mode) {
    // Same position
    SkPoint pts[2] = {CENTER, CENTER};
    return SkGradientShader::MakeLinear(pts, COLORS, POS, COLOR_CT, mode);
}

static sk_sp<SkShader> make_radial(SkTileMode mode) {
    // Radius = 0
    return SkGradientShader::MakeRadial(CENTER, 0.0, COLORS, POS, COLOR_CT, mode);
}

static sk_sp<SkShader> make_sweep(SkTileMode mode) {
    // Start and end angles at 45
    static constexpr SkScalar SWEEP_ANG = 45.0;
    return SkGradientShader::MakeSweep(CENTER.fX, CENTER.fY, COLORS, POS, COLOR_CT, mode,
                                       SWEEP_ANG, SWEEP_ANG, 0, nullptr);
}

static sk_sp<SkShader> make_sweep_zero_ang(SkTileMode mode) {
    // Start and end angles at 0
    return SkGradientShader::MakeSweep(CENTER.fX, CENTER.fY, COLORS, POS, COLOR_CT, mode,
                                       0.0, 0.0, 0, nullptr);
}

static sk_sp<SkShader> make_2pt_conic(SkTileMode mode) {
    // Start and end radius = TILE_SIZE, same position
    return SkGradientShader::MakeTwoPointConical(CENTER, TILE_SIZE / 2, CENTER, TILE_SIZE / 2,
                                                 COLORS, POS, COLOR_CT, mode);
}

static sk_sp<SkShader> make_2pt_conic_zero_rad(SkTileMode mode) {
    // Start and end radius = 0, same position
    return SkGradientShader::MakeTwoPointConical(CENTER, 0.0, CENTER, 0.0, COLORS, POS,
                                                 COLOR_CT, mode);
}

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

    }

protected:
    SkString onShortName() override {
        return SkString("degenerate_gradients");
    }

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

    void onDraw(SkCanvas* canvas) override {
        canvas->translate(3 * TILE_GAP, 3 * TILE_GAP);
        draw_tile_header(canvas);

        draw_row(canvas, "linear: empty, blue, blue, green", make_linear);
        draw_row(canvas, "radial:  empty, blue, blue, green", make_radial);
        draw_row(canvas, "sweep-0: empty, blue, blue, green", make_sweep_zero_ang);
        draw_row(canvas, "sweep-45: empty, blue, blue, red 45 degree sector then green",
                 make_sweep);
        draw_row(canvas, "2pt-conic-0: empty, blue, blue, green", make_2pt_conic_zero_rad);
        draw_row(canvas, "2pt-conic-1: empty, blue, blue, full red circle on green",
                 make_2pt_conic);
    }

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

DEF_GM(return new DegenerateGradientGM;)
