/*
 * 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"

typedef SkShader* (*MakeShaderProc)(const SkColor[], int count, const SkSize&);

static SkShader* shader_linear(const SkColor colors[], int count, const SkSize& size) {
    SkPoint pts[] = { { 0, 0 }, { size.width(), size.height() } };
    return SkGradientShader::CreateLinear(pts, colors, NULL, count,
                                          SkShader::kClamp_TileMode);
}

static SkShader* shader_radial(const SkColor colors[], int count, const SkSize& size) {
    SkPoint center = { size.width()/2, size.height()/2 };
    return SkGradientShader::CreateRadial(center, size.width()/2, colors, NULL, count,
                                          SkShader::kClamp_TileMode);
}

static SkShader* shader_conical(const SkColor colors[], int count, const SkSize& size) {
    SkPoint center = { size.width()/2, size.height()/2 };
    return SkGradientShader::CreateTwoPointConical(center, size.width()/64,
                                                   center, size.width()/2,
                                                   colors, NULL, count,
                                                   SkShader::kClamp_TileMode);
}

static SkShader* shader_sweep(const SkColor colors[], int count, const SkSize& size) {
    return SkGradientShader::CreateSweep(size.width()/2, size.height()/2,
                                         colors, NULL, count);
}

class ShallowGradientGM : public skiagm::GM {
public:
    ShallowGradientGM(MakeShaderProc proc, const char name[]) : fProc(proc) {
        fName.printf("shallow_gradient_%s", name);
    }

protected:
    virtual uint32_t onGetFlags() const SK_OVERRIDE {
        if (fName.contains("linear") || fName.contains("radial")) {
            return kSkipTiled_Flag;
        }
        return 0;
    }

    virtual SkString onShortName() SK_OVERRIDE {
        return fName;
    }

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

    virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
        const SkColor colors[] = { 0xFF555555, 0xFF444444 };
        const int colorCount = SK_ARRAY_COUNT(colors);

        SkRect r = { 0, 0, this->width(), this->height() };
        SkSize size = SkSize::Make(r.width(), r.height());

        SkPaint paint;
        paint.setShader(fProc(colors, colorCount, size))->unref();
        canvas->drawRect(r, paint);
    }

private:
    MakeShaderProc fProc;
    SkString fName;

    typedef skiagm::GM INHERITED;
};

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

DEF_GM( return new ShallowGradientGM(shader_linear, "linear"); )
DEF_GM( return new ShallowGradientGM(shader_radial, "radial"); )
DEF_GM( return new ShallowGradientGM(shader_conical, "conical"); )
DEF_GM( return new ShallowGradientGM(shader_sweep, "sweep"); )
