/*
 * Copyright 2019 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 "AnimTimer.h"
#include "SkCanvas.h"
#include "SkColorFilter.h"
#include "SkGradientShader.h"
#include "SkLumaColorFilter.h"
#include "SkTableColorFilter.h"

// A tint filter maps colors to a given range (gradient), based on the input luminance:
//
//   c' = lerp(lo, hi, luma(c))
//
// TODO: move to public headers/API?
//
static sk_sp<SkColorFilter> MakeTintColorFilter(SkColor lo, SkColor hi) {
    const auto r_lo = SkColorGetR(lo),
    g_lo = SkColorGetG(lo),
    b_lo = SkColorGetB(lo),
    a_lo = SkColorGetA(lo),
    r_hi = SkColorGetR(hi),
    g_hi = SkColorGetG(hi),
    b_hi = SkColorGetB(hi),
    a_hi = SkColorGetA(hi);

    // We map component-wise:
    //
    //   r' = lo.r + (hi.r - lo.r) * luma
    //   g' = lo.g + (hi.g - lo.g) * luma
    //   b' = lo.b + (hi.b - lo.b) * luma
    //   a' = lo.a + (hi.a - lo.a) * luma
    //
    // The input luminance is stored in the alpha channel
    // (and RGB are cleared -- see SkLumaColorFilter). Thus:
    const SkScalar tint_matrix[] = {
        0, 0, 0, (r_hi - r_lo) / 255.0f, SkIntToScalar(r_lo),
        0, 0, 0, (g_hi - g_lo) / 255.0f, SkIntToScalar(g_lo),
        0, 0, 0, (b_hi - b_lo) / 255.0f, SkIntToScalar(b_lo),
        0, 0, 0, (a_hi - a_lo) / 255.0f, SkIntToScalar(a_lo),
    };

    return SkColorFilters::MatrixRowMajor255(tint_matrix)
    ->makeComposed(SkLumaColorFilter::Make());
}

namespace {

class MixerCFGM final : public skiagm::GM {
public:
    MixerCFGM(const SkSize& tileSize, size_t tileCount)
        : fTileSize(tileSize)
        , fTileCount(tileCount) {}

protected:
    SkString onShortName() override {
        return SkString("mixerCF");
    }

    SkISize onISize() override {
        return SkISize::Make(fTileSize.width()  * 1.2f * fTileCount,
                             fTileSize.height() * 1.2f * 3);         // 3 rows
    }

    void onDraw(SkCanvas* canvas) override {
        SkPaint paint;

        const SkColor gradient_colors[] = { SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorRED };
        paint.setShader(SkGradientShader::MakeSweep(fTileSize.width()  / 2,
                                                    fTileSize.height() / 2,
                                                    gradient_colors, nullptr,
                                                    SK_ARRAY_COUNT(gradient_colors)));

        auto cf0 = MakeTintColorFilter(0xff300000, 0xffa00000);  // red tint
        auto cf1 = MakeTintColorFilter(0xff003000, 0xff00a000);  // green tint

        this->mixRow(canvas, paint, nullptr,     cf1);
        this->mixRow(canvas, paint,     cf0, nullptr);
        this->mixRow(canvas, paint,     cf0,     cf1);
    }

private:
    const SkSize fTileSize;
    const size_t fTileCount;

    void mixRow(SkCanvas* canvas, SkPaint& paint,
                sk_sp<SkColorFilter> cf0, sk_sp<SkColorFilter> cf1) {
        canvas->translate(0, fTileSize.height() * 0.1f);
        {
            SkAutoCanvasRestore arc(canvas, true);
            for (size_t i = 0; i < fTileCount; ++i) {
                paint.setColorFilter(
                    SkColorFilters::Lerp(static_cast<float>(i) / (fTileCount - 1), cf0, cf1));
                canvas->translate(fTileSize.width() * 0.1f, 0);
                canvas->drawRect(SkRect::MakeWH(fTileSize.width(), fTileSize.height()), paint);
                canvas->translate(fTileSize.width() * 1.1f, 0);
            }
        }
        canvas->translate(0, fTileSize.height() * 1.1f);
    }

    using INHERITED = skiagm::GM;
};

} // namespace
DEF_GM( return new MixerCFGM(SkSize::Make(200, 250), 5); )

#include "Resources.h"

static sk_sp<SkShader> make_resource_shader(const char path[], int size) {
    auto img = GetResourceAsImage(path);
    if (!img) {
        return nullptr;
    }
    SkRect src = SkRect::MakeIWH(img->width(), img->height());
    SkRect dst = SkRect::MakeIWH(size, size);
    SkMatrix m;
    m.setRectToRect(src, dst, SkMatrix::kFill_ScaleToFit);
    return img->makeShader(&m);
}

static sk_sp<SkShader> make_grad(int size, float t) {
    SkASSERT(t >= 0 && t <= 1);
    unsigned r = SkScalarRoundToInt(t * 255);
    SkColor c = SkColorSetARGB(r, r, 0, 0);

    SkColor colors[] = { 0, c, SK_ColorRED };
    SkPoint pts[] = {{0, 0}, {size*1.0f, size*1.0f}};
    SkScalar pos[] = {0, 1 - t, 1.0f};
    return SkGradientShader::MakeLinear(pts, colors, pos, SK_ARRAY_COUNT(colors),
                                        SkTileMode::kClamp);
}

class ShaderMixerGM final : public skiagm::GM {
    enum { SIZE = 256 };
    float fPos = 0.5f;
    sk_sp<SkShader> fS0, fS1;

public:
    ShaderMixerGM() {}

protected:
    SkString onShortName() override {
        return SkString("mixershader_shadermixer");
    }

    void onOnceBeforeDraw() override {
        fS0 = make_resource_shader("images/mandrill_256.png", SIZE);
        fS1 = make_resource_shader("images/baby_tux.png", SIZE);
    }

    SkISize onISize() override { return {542, 542}; }

    void onDraw(SkCanvas* canvas) override {
        SkRect r = SkRect::MakeIWH(SIZE, SIZE);

        SkPaint paint;

        canvas->translate(10, 10);

        canvas->save();
        paint.setShader(fS0);
        canvas->drawRect(r, paint);
        canvas->translate(SIZE + 10.0f, 0);
        paint.setShader(fS1);
        canvas->drawRect(r, paint);
        canvas->restore();

        auto sh2 = make_grad(SIZE, fPos);

        canvas->translate(0, SIZE + 10.0f);
        paint.setShader(sh2);
        canvas->drawRect(r, paint);

        auto sh = SkShaders::Lerp(sh2, fS0, fS1);
        canvas->translate(SIZE + 10.0f, 0);
        paint.setShader(sh);
        canvas->drawRect(r, paint);
    }

    bool onAnimate(const AnimTimer& timer) override {
        fPos = (sin(timer.secs()) + 1) * 0.5f;
        return true;
    }

private:
    using INHERITED = skiagm::GM;
};
DEF_GM( return new ShaderMixerGM; )
