/*
 * 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/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 "include/private/SkFloatingPoint.h"
#include "include/private/SkTo.h"

#include <array>
#include <cstdint>
#include <string.h>

using namespace skiagm;

struct GradData {
    size_t           fCount;
    const SkColor4f* fColors;
    const float*     fPos;

    SkGradient operator()(SkTileMode tm) const {
        SkSpan<const float> pos;
        if (fPos) {
            pos = {fPos, fCount};
        }
        return {{{fColors, fCount}, pos, tm}, {}};
    }
};

constexpr SkColor4f gColors[] = {
    SkColors::kRed, SkColors::kGreen, SkColors::kBlue, SkColors::kWhite,
};

static constexpr auto gGradData = std::to_array<GradData>({
        GradData{1, gColors, nullptr},
        GradData{2, gColors, nullptr},
        GradData{3, gColors, nullptr},
        GradData{4, gColors, nullptr},
});

static sk_sp<SkShader> MakeLinear(const SkPoint pts[2], const GradData& grad, SkTileMode tm) {
    return SkShaders::LinearGradient(pts, grad(tm));
}

static sk_sp<SkShader> MakeRadial(const SkPoint pts[2], const GradData& grad, SkTileMode tm) {
    SkPoint center;
    center.set(sk_float_midpoint(pts[0].fX, pts[1].fX),
               sk_float_midpoint(pts[0].fY, pts[1].fY));
    return SkShaders::RadialGradient(center, center.fX, grad(tm));
}

static sk_sp<SkShader> MakeSweep(const SkPoint pts[2], const GradData& grad, SkTileMode tm) {
    SkPoint center;
    center.set(sk_float_midpoint(pts[0].fX, pts[1].fX),
               sk_float_midpoint(pts[0].fY, pts[1].fY));
    return SkShaders::SweepGradient(center, grad(tm));
}

static sk_sp<SkShader> Make2Radial(const SkPoint pts[2], const GradData& grad, SkTileMode tm) {
    SkPoint center0, center1;
    center0.set(sk_float_midpoint(pts[0].fX, pts[1].fX),
                sk_float_midpoint(pts[0].fY, pts[1].fY));
    center1.set(SkScalarInterp(pts[0].fX, pts[1].fX, SkIntToScalar(3)/5),
                SkScalarInterp(pts[0].fY, pts[1].fY, SkIntToScalar(1)/4));
    return SkShaders::TwoPointConicalGradient(
        center1, (pts[1].fX - pts[0].fX) / 7,
        center0, (pts[1].fX - pts[0].fX) / 2,
        grad(tm));
}

static sk_sp<SkShader> Make2Conical(const SkPoint pts[2], const GradData& grad, SkTileMode tm) {
    SkPoint center0, center1;
    SkScalar radius0 = (pts[1].fX - pts[0].fX) / 10;
    SkScalar radius1 = (pts[1].fX - pts[0].fX) / 3;
    center0.set(pts[0].fX + radius0, pts[0].fY + radius0);
    center1.set(pts[1].fX - radius1, pts[1].fY - radius1);
    return SkShaders::TwoPointConicalGradient(center1, radius1, center0, radius0, grad(tm));
}


typedef sk_sp<SkShader> (*GradMaker)(const SkPoint pts[2], const GradData& data, SkTileMode tm);

static constexpr auto gGradMakers = std::to_array<GradMaker>({
        MakeLinear,
        MakeRadial,
        MakeSweep,
        Make2Radial,
        Make2Conical,
});

///////////////////////////////////////////////////////////////////////////////

class GradientsNoTextureGM : public GM {
public:
    GradientsNoTextureGM(bool dither) : fDither(dither) {
        this->setBGColor(0xFFDDDDDD);
    }

protected:
    SkString getName() const override {
        return SkString(fDither ? "gradients_no_texture" : "gradients_no_texture_nodither");
    }

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

    void onDraw(SkCanvas* canvas) override {
        constexpr SkPoint kPts[2] = { { 0, 0 },
                                         { SkIntToScalar(50), SkIntToScalar(50) } };
        constexpr SkTileMode kTM = SkTileMode::kClamp;
        SkRect kRect = { 0, 0, SkIntToScalar(50), SkIntToScalar(50) };
        SkPaint paint;
        paint.setAntiAlias(true);
        paint.setDither(fDither);

        canvas->translate(SkIntToScalar(20), SkIntToScalar(20));
        static constexpr auto kAlphas = std::to_array<uint8_t>({0xff, 0x40});
        for (size_t a = 0; a < std::size(kAlphas); ++a) {
            for (size_t i = 0; i < std::size(gGradData); ++i) {
                canvas->save();
                for (size_t j = 0; j < std::size(gGradMakers); ++j) {
                    paint.setShader(gGradMakers[j](kPts, gGradData[i], kTM));
                    paint.setAlpha(kAlphas[a]);
                    canvas->drawRect(kRect, paint);
                    canvas->translate(0, SkIntToScalar(kRect.height() + 20));
                }
                canvas->restore();
                canvas->translate(SkIntToScalar(kRect.width() + 20), 0);
            }
        }
    }

private:
    bool fDither;

    using INHERITED = GM;
};

///////////////////////////////////////////////////////////////////////////////

struct ColorPos {
    SkColor4f* fColors;
    float*     fPos;
    size_t     fCount;

    ColorPos() : fColors(nullptr), fPos(nullptr), fCount(0) {}
    ~ColorPos() {
        delete[] fColors;
        delete[] fPos;
    }

    void construct(const SkColor colors[], const float pos[], int count) {
        fColors = new SkColor4f[count];
        std::transform(colors, colors + count, fColors, SkColor4f::FromColor);
        if (pos) {
            fPos = new float[count];
            std::copy(pos, pos + count, fPos);
            fPos[0] = 0;
            fPos[count - 1] = 1;
        }
        fCount = count;
    }

    SkGradient operator()(SkTileMode tm) const {
        SkSpan<const float> pos;
        if (fPos) {
            pos = {fPos, fCount};
        }
        return {{{fColors, fCount}, pos, tm}, {}};
    }
};

static void make0(ColorPos* rec) {
#if 0
    From http://jsfiddle.net/3fe2a/

background-image: -webkit-linear-gradient(left, #22d1cd 1%, #22d1cd 0.9510157507590116%, #df4b37 2.9510157507590113%, #df4b37 23.695886056604927%, #22d1cd 25.695886056604927%, #22d1cd 25.39321881940624%, #e6de36 27.39321881940624%, #e6de36 31.849399922570655%, #3267ff 33.849399922570655%, #3267ff 44.57735802921938%, #9d47d1 46.57735802921938%, #9d47d1 53.27185850805876%, #3267ff 55.27185850805876%, #3267ff 61.95718972227316%, #5cdd9d 63.95718972227316%, #5cdd9d 69.89166004442%, #3267ff 71.89166004442%, #3267ff 74.45795382765857%, #9d47d1 76.45795382765857%, #9d47d1 82.78364610713776%, #3267ff 84.78364610713776%, #3267ff 94.52743647737229%, #e3d082 96.52743647737229%, #e3d082 96.03934633331295%);
height: 30px;
#endif

    const SkColor colors[] = {
        0xFF22d1cd, 0xFF22d1cd, 0xFFdf4b37, 0xFFdf4b37, 0xFF22d1cd, 0xFF22d1cd, 0xFFe6de36, 0xFFe6de36,
        0xFF3267ff, 0xFF3267ff, 0xFF9d47d1, 0xFF9d47d1, 0xFF3267ff, 0xFF3267ff, 0xFF5cdd9d, 0xFF5cdd9d,
        0xFF3267ff, 0xFF3267ff, 0xFF9d47d1, 0xFF9d47d1, 0xFF3267ff, 0xFF3267ff, 0xFFe3d082, 0xFFe3d082
    };
    static constexpr auto percent = std::to_array<double>({
             1,                  0.9510157507590116, 2.9510157507590113, 23.695886056604927,
            25.695886056604927, 25.39321881940624,  27.39321881940624,   31.849399922570655,
            33.849399922570655, 44.57735802921938,  46.57735802921938,   53.27185850805876,
            55.27185850805876,  61.95718972227316,  63.95718972227316,   69.89166004442,
            71.89166004442,     74.45795382765857,  76.45795382765857,   82.78364610713776,
            84.78364610713776,  94.52743647737229,  96.52743647737229,   96.03934633331295,
    });
    const int N = std::size(percent);
    std::array<SkScalar, N> pos;
    for (int i = 0; i < N; ++i) {
        pos[i] = SkDoubleToScalar(percent[i] / 100);
    }
    rec->construct(colors, pos.data(), N);
}

static void make1(ColorPos* rec) {
    const SkColor colors[] = {
        SK_ColorBLACK, SK_ColorWHITE, SK_ColorBLACK, SK_ColorWHITE,
        SK_ColorBLACK, SK_ColorWHITE, SK_ColorBLACK, SK_ColorWHITE,
        SK_ColorBLACK,
    };
    rec->construct(colors, nullptr, std::size(colors));
}

static void make2(ColorPos* rec) {
    const SkColor colors[] = {
        SK_ColorBLACK, SK_ColorWHITE, SK_ColorBLACK, SK_ColorWHITE,
        SK_ColorBLACK, SK_ColorWHITE, SK_ColorBLACK, SK_ColorWHITE,
        SK_ColorBLACK,
    };
    const int N = std::size(colors);
    std::array<SkScalar, N> pos;
    for (int i = 0; i < N; ++i) {
        pos[i] = SK_Scalar1 * i / (N - 1);
    }
    rec->construct(colors, pos.data(), N);
}

static void make3(ColorPos* rec) {
    const SkColor colors[] = {
        SK_ColorRED, SK_ColorBLUE, SK_ColorBLUE, SK_ColorGREEN, SK_ColorGREEN, SK_ColorBLACK,
    };
    const SkScalar pos[] = {
        0, 0, 0.5f, 0.5, 1, 1,
    };
    rec->construct(colors, pos, std::size(colors));
}

class GradientsManyColorsGM : public GM {
    enum {
        W = 800,
    };
    sk_sp<SkShader> fShader;

    typedef void (*Proc)(ColorPos*);
public:
    GradientsManyColorsGM(bool dither) : fDither(dither) {}

protected:
    SkString getName() const override {
        return SkString(fDither ? "gradients_many" : "gradients_many_nodither");
    }

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

    void onDraw(SkCanvas* canvas) override {
        static constexpr auto procs = std::to_array<Proc>({
                make0,
                make1,
                make2,
                make3,
        });
        const SkPoint pts[] = {
            { 0, 0 },
            { SkIntToScalar(W), 0 },
        };
        const SkRect r = SkRect::MakeWH(SkIntToScalar(W), 30);

        SkPaint paint;
        paint.setDither(fDither);

        canvas->translate(40, 20);

        for (int i = 0; i <= 8; ++i) {
            SkScalar x = r.width() * i / 8;
            canvas->drawLine(x, 0, x, 10000, paint);
        }

        // expand the drawing rect so we exercise clampping in the gradients
        const SkRect drawR = r.makeOutset(20, 0);
        for (size_t i = 0; i < std::size(procs); ++i) {
            ColorPos rec;
            procs[i](&rec);
            paint.setShader(SkShaders::LinearGradient(pts, rec(SkTileMode::kClamp)));
            canvas->drawRect(drawR, paint);

            canvas->save();
            canvas->translate(r.centerX(), r.height() + 4);
            canvas->scale(-1, 1);
            canvas->translate(-r.centerX(), 0);
            canvas->drawRect(drawR, paint);
            canvas->restore();

            canvas->translate(0, r.height() + 2*r.height() + 8);
        }
    }

private:
    bool fDither;

    using INHERITED = GM;
};

///////////////////////////////////////////////////////////////////////////////

DEF_GM(return new GradientsNoTextureGM(true);)
DEF_GM(return new GradientsNoTextureGM(false);)
DEF_GM(return new GradientsManyColorsGM(true);)
DEF_GM(return new GradientsManyColorsGM(false);)
