/*
 * 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/SkGradientShader.h"

#include <string.h>

using namespace skiagm;

struct GradData {
    int             fCount;
    const SkColor*  fColors;
    const SkScalar* fPos;
};

constexpr SkColor gColors[] = {
    SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorWHITE,
};

constexpr GradData gGradData[] = {
    { 1, gColors, nullptr },
    { 2, gColors, nullptr },
    { 3, gColors, nullptr },
    { 4, gColors, nullptr },
};

static sk_sp<SkShader> MakeLinear(const SkPoint pts[2], const GradData& data, SkTileMode tm) {
    return SkGradientShader::MakeLinear(pts, data.fColors, data.fPos, data.fCount, tm);
}

static sk_sp<SkShader> MakeRadial(const SkPoint pts[2], const GradData& data, SkTileMode tm) {
    SkPoint center;
    center.set(SkScalarAve(pts[0].fX, pts[1].fX),
               SkScalarAve(pts[0].fY, pts[1].fY));
    return SkGradientShader::MakeRadial(center, center.fX, data.fColors, data.fPos, data.fCount, tm);
}

static sk_sp<SkShader> MakeSweep(const SkPoint pts[2], const GradData& data, SkTileMode) {
    SkPoint center;
    center.set(SkScalarAve(pts[0].fX, pts[1].fX),
               SkScalarAve(pts[0].fY, pts[1].fY));
    return SkGradientShader::MakeSweep(center.fX, center.fY, data.fColors, data.fPos, data.fCount);
}

static sk_sp<SkShader> Make2Radial(const SkPoint pts[2], const GradData& data, SkTileMode tm) {
    SkPoint center0, center1;
    center0.set(SkScalarAve(pts[0].fX, pts[1].fX),
                SkScalarAve(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 SkGradientShader::MakeTwoPointConical(
        center1, (pts[1].fX - pts[0].fX) / 7,
        center0, (pts[1].fX - pts[0].fX) / 2,
        data.fColors, data.fPos, data.fCount, tm);
}

static sk_sp<SkShader> Make2Conical(const SkPoint pts[2], const GradData& data, 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 SkGradientShader::MakeTwoPointConical(center1, radius1,
                                                   center0, radius0,
                                                   data.fColors, data.fPos,
                                                   data.fCount, tm);
}


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

constexpr GradMaker gGradMakers[] = {
    MakeLinear, MakeRadial, MakeSweep, Make2Radial, Make2Conical,
};

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

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

protected:

    SkString onShortName() override {
        return SkString(fDither ? "gradients_no_texture" : "gradients_no_texture_nodither");
    }

    SkISize onISize() 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));
        constexpr uint8_t kAlphas[] = { 0xff, 0x40 };
        for (size_t a = 0; a < SK_ARRAY_COUNT(kAlphas); ++a) {
            for (size_t i = 0; i < SK_ARRAY_COUNT(gGradData); ++i) {
                canvas->save();
                for (size_t j = 0; j < SK_ARRAY_COUNT(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;

    typedef GM INHERITED;
};

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

struct ColorPos {
    SkColor*    fColors;
    SkScalar*   fPos;
    int         fCount;

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

    void construct(const SkColor colors[], const SkScalar pos[], int count) {
        fColors = new SkColor[count];
        memcpy(fColors, colors, count * sizeof(SkColor));
        if (pos) {
            fPos = new SkScalar[count];
            memcpy(fPos, pos, count * sizeof(SkScalar));
            fPos[0] = 0;
            fPos[count - 1] = 1;
        }
        fCount = count;
    }
};

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
    };
    const double percent[] = {
        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 = SK_ARRAY_COUNT(percent);
    SkScalar pos[N];
    for (int i = 0; i < N; ++i) {
        pos[i] = SkDoubleToScalar(percent[i] / 100);
    }
    rec->construct(colors, pos, 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, SK_ARRAY_COUNT(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 = SK_ARRAY_COUNT(colors);
    SkScalar pos[N];
    for (int i = 0; i < N; ++i) {
        pos[i] = SK_Scalar1 * i / (N - 1);
    }
    rec->construct(colors, pos, 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, SK_ARRAY_COUNT(colors));
}

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

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

protected:

    SkString onShortName() override {
        return SkString(fDither ? "gradients_many" : "gradients_many_nodither");
    }

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

    void onDraw(SkCanvas* canvas) override {
        const Proc procs[] = {
            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 < SK_ARRAY_COUNT(procs); ++i) {
            ColorPos rec;
            procs[i](&rec);
            paint.setShader(SkGradientShader::MakeLinear(pts, rec.fColors, rec.fPos, rec.fCount,
                                                         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;

    typedef GM INHERITED;
};

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

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