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

using namespace skiagm;

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

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

static const GradData gGradData[] = {
    { 1, gColors, NULL },
    { 2, gColors, NULL },
    { 3, gColors, NULL },
    { 4, gColors, NULL },
};

static SkShader* MakeLinear(const SkPoint pts[2], const GradData& data, SkShader::TileMode tm) {
    return SkGradientShader::CreateLinear(pts, data.fColors, data.fPos, data.fCount, tm);
}

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

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

static SkShader* Make2Radial(const SkPoint pts[2], const GradData& data, SkShader::TileMode 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::CreateTwoPointConical(
        center1, (pts[1].fX - pts[0].fX) / 7,
        center0, (pts[1].fX - pts[0].fX) / 2,
        data.fColors, data.fPos, data.fCount, tm);
}

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


typedef SkShader* (*GradMaker)(const SkPoint pts[2], const GradData& data, SkShader::TileMode tm);

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

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

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

protected:

    SkString onShortName() override { return SkString("gradients_no_texture"); }
    SkISize onISize() override { return SkISize::Make(640, 615); }

    void onDraw(SkCanvas* canvas) override {
        static const SkPoint kPts[2] = { { 0, 0 },
                                         { SkIntToScalar(50), SkIntToScalar(50) } };
        static const SkShader::TileMode kTM = SkShader::kClamp_TileMode;
        SkRect kRect = { 0, 0, SkIntToScalar(50), SkIntToScalar(50) };
        SkPaint paint;
        paint.setAntiAlias(true);

        canvas->translate(SkIntToScalar(20), SkIntToScalar(20));
        static const 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) {
                    SkShader* shader = gGradMakers[j](kPts, gGradData[i], kTM);
                    paint.setShader(shader)->unref();
                    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:
    typedef GM INHERITED;
};

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

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

    ColorPos() : fColors(NULL), fPos(NULL), fCount(0) {}
    ~ColorPos() {
        SkDELETE_ARRAY(fColors);
        SkDELETE_ARRAY(fPos);
    }

    void construct(const SkColor colors[], const SkScalar pos[], int count) {
        fColors = SkNEW_ARRAY(SkColor, count);
        memcpy(fColors, colors, count * sizeof(SkColor));
        if (pos) {
            fPos = SkNEW_ARRAY(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, NULL, 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);
}

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

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

protected:

    SkString onShortName() override { return SkString("gradients_many"); }
    SkISize onISize() override { return SkISize::Make(850, 100); }

    void onDraw(SkCanvas* canvas) override {
        const Proc procs[] = {
            make0, make1, make2,
        };
        const SkPoint pts[] = {
            { 0, 0 },
            { SkIntToScalar(W), 0 },
        };
        const SkRect r = SkRect::MakeWH(SkIntToScalar(W), 30);

        SkPaint paint;

        canvas->translate(20, 20);

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

        for (size_t i = 0; i < SK_ARRAY_COUNT(procs); ++i) {
            ColorPos rec;
            procs[i](&rec);
            SkShader* s = SkGradientShader::CreateLinear(pts, rec.fColors, rec.fPos, rec.fCount,
                                                         SkShader::kClamp_TileMode);
            paint.setShader(s)->unref();
            canvas->drawRect(r, paint);
            canvas->translate(0, r.height() + 20);
        }
    }

private:
    typedef GM INHERITED;
};

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

DEF_GM( return SkNEW(GradientsNoTextureGM));
DEF_GM( return SkNEW(GradientsManyColorsGM));
