/*
 * 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/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/SkGradient.h"
#include "tools/ToolUtils.h"
#include "tools/fonts/FontToolUtils.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 SkColor4f COLORS[] = { SkColors::kRed, SkColors::kWhite, SkColors::kBlue,
                                    SkColors::kBlack, SkColors::kGreen };
static const SkScalar POS[] = { 0.0, 0.0, 0.5, 1.0, 1.0 };

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 SkGradient grad(SkTileMode tm) {
    return {{COLORS, POS, tm}, {}};
}

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

    SkFont font(ToolUtils::DefaultPortableTypeface(), 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::DefaultPortableTypeface(), 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 SkShaders::LinearGradient(pts, grad(mode));
}

static sk_sp<SkShader> make_radial(SkTileMode mode) {
    // Radius = 0
    return SkShaders::RadialGradient(CENTER, 0.0, grad(mode));
}

static sk_sp<SkShader> make_sweep(SkTileMode mode) {
    // Start and end angles at 45
    static constexpr SkScalar SWEEP_ANG = 45.0;
    return SkShaders::SweepGradient(CENTER, SWEEP_ANG, SWEEP_ANG, grad(mode));
}

static sk_sp<SkShader> make_sweep_zero_ang(SkTileMode mode) {
    // Start and end angles at 0
    return SkShaders::SweepGradient(CENTER, 0, 0, grad(mode));
}

static sk_sp<SkShader> make_2pt_conic(SkTileMode mode) {
    // Start and end radius = TILE_SIZE, same position
    return SkShaders::TwoPointConicalGradient(CENTER, TILE_SIZE / 2, CENTER, TILE_SIZE / 2,
                                              grad(mode));
}

static sk_sp<SkShader> make_2pt_conic_zero_rad(SkTileMode mode) {
    // Start and end radius = 0, same position
    return SkShaders::TwoPointConicalGradient(CENTER, 0.0, CENTER, 0.0, grad(mode));
}

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

    }

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

    SkISize getISize() 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;)
