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

typedef sk_sp<SkShader> (*MakeShaderProc)(const SkGradient& grad, const SkSize&);

static sk_sp<SkShader> shader_linear(const SkGradient& grad, const SkSize& size) {
    SkPoint pts[] = { { 0, 0 }, { size.width(), size.height() } };
    return SkShaders::LinearGradient(pts, grad);
}

static sk_sp<SkShader> shader_radial(const SkGradient& grad, const SkSize& size) {
    SkPoint center = { size.width()/2, size.height()/2 };
    return SkShaders::RadialGradient(center, size.width()/2, grad);
}

static sk_sp<SkShader> shader_conical(const SkGradient& grad, const SkSize& size) {
    SkPoint center = { size.width()/2, size.height()/2 };
    return SkShaders::TwoPointConicalGradient(center, size.width()/64, center, size.width()/2,
                                              grad);
}

static sk_sp<SkShader> shader_sweep(const SkGradient& grad, const SkSize& size) {
    return SkShaders::SweepGradient({size.width()/2, size.height()/2}, grad);
}

class ShallowGradientGM : public skiagm::GM {
public:
    ShallowGradientGM(MakeShaderProc proc, const char name[], bool dither)
        : fProc(proc), fName(name), fDither(dither) {}

private:
    MakeShaderProc fProc;
    const char* fName;
    bool fDither;

    SkString getName() const override {
        return SkStringPrintf("shallow_gradient_%s%s", fName, fDither ? "" : "_nodither");
    }

    SkISize getISize() override { return {800, 800}; }

    void onDraw(SkCanvas* canvas) override {
        const SkColor4f colors[] = {
            SkColor4f::FromColor(0xFF555555), SkColor4f::FromColor(0xFF444444)
        };
        const SkGradient grad = {{colors, {}, SkTileMode::kClamp}, {}};

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

        SkPaint paint;
        paint.setShader(fProc(grad, size));
        paint.setDither(fDither);
        canvas->drawRect(r, paint);
    }
};

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

#define M(PROC, DITHER) DEF_GM( return new ShallowGradientGM(shader_ ## PROC, #PROC, DITHER); )
M(linear,  true)
M(radial,  true)
M(conical, true)
M(sweep,   true)

M(linear,  false)
M(radial,  false)
M(conical, false)
M(sweep,   false)
#undef M
