/*
 * Copyright 2018 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "SkSGColorFilter.h"

#include "SkColorFilter.h"
#include "SkSGColor.h"

namespace sksg {

ColorFilter::ColorFilter(sk_sp<RenderNode> child)
    : INHERITED(std::move(child)) {}

void ColorFilter::onRender(SkCanvas* canvas, const RenderContext* ctx) const {
    const auto local_ctx = ScopedRenderContext(canvas, ctx).modulateColorFilter(fColorFilter);

    this->INHERITED::onRender(canvas, local_ctx);
}

const RenderNode* ColorFilter::onNodeAt(const SkPoint& p) const {
    // TODO: we likely need to do something more sophisticated than delegate to descendants here.
    return this->INHERITED::onNodeAt(p);
}

SkRect ColorFilter::onRevalidate(InvalidationController* ic, const SkMatrix& ctm) {
    SkASSERT(this->hasInval());

    fColorFilter = this->onRevalidateFilter();

    return this->INHERITED::onRevalidate(ic, ctm);
}

sk_sp<ModeColorFilter> ModeColorFilter::Make(sk_sp<RenderNode> child, sk_sp<Color> color,
                                             SkBlendMode mode) {
    return (child && color) ? sk_sp<ModeColorFilter>(new ModeColorFilter(std::move(child),
                                                                         std::move(color), mode))
                            : nullptr;
}

ModeColorFilter::ModeColorFilter(sk_sp<RenderNode> child, sk_sp<Color> color, SkBlendMode mode)
    : INHERITED(std::move(child))
    , fColor(std::move(color))
    , fMode(mode) {
    this->observeInval(fColor);
}

ModeColorFilter::~ModeColorFilter() {
    this->unobserveInval(fColor);
}

sk_sp<SkColorFilter> ModeColorFilter::onRevalidateFilter() {
    fColor->revalidate(nullptr, SkMatrix::I());
    return SkColorFilter::MakeModeFilter(fColor->getColor(), fMode);
}

sk_sp<TintColorFilter> TintColorFilter::Make(sk_sp<RenderNode> child,
                                             sk_sp<Color> c0, sk_sp<Color> c1) {
    return (child && c0 && c1) ? sk_sp<TintColorFilter>(new TintColorFilter(std::move(child),
                                                                            std::move(c0),
                                                                            std::move(c1)))
                               : nullptr;
}

TintColorFilter::TintColorFilter(sk_sp<RenderNode> child, sk_sp<Color> c0, sk_sp<Color> c1)
    : INHERITED(std::move(child))
    , fColor0(std::move(c0))
    , fColor1(std::move(c1)) {
    this->observeInval(fColor0);
    this->observeInval(fColor1);
}

TintColorFilter::~TintColorFilter() {
    this->unobserveInval(fColor0);
    this->unobserveInval(fColor1);
}

sk_sp<SkColorFilter> TintColorFilter::onRevalidateFilter() {
    fColor0->revalidate(nullptr, SkMatrix::I());
    fColor1->revalidate(nullptr, SkMatrix::I());

    if (fWeight <= 0) {
        return nullptr;
    }

    const auto c0 = SkColor4f::FromColor(fColor0->getColor()),
               c1 = SkColor4f::FromColor(fColor1->getColor());

    // luminance coefficients
    static constexpr float kR = 0.2126f,
                           kG = 0.7152f,
                           kB = 0.0722f;

    const auto dR = c1.fR - c0.fR,
               dG = c1.fG - c0.fG,
               dB = c1.fB - c0.fB;

    // First, we need a luminance:
    //
    //   L = [r,g,b] . [kR,kG,kB]
    //
    // We can compute it using a color matrix (result stored in R):
    //
    //   | kR, kG, kB,  0,  0 |    r' = L
    //   |  0,  0,  0,  0,  0 |    g' = 0
    //   |  0,  0,  0,  0,  0 |    b' = 0
    //   |  0,  0,  0,  1,  0 |    a' = a
    //
    // Then we want to interpolate component-wise, based on L:
    //
    //   r' = c0.r + (c1.r - c0.r) * L = c0.r + dR*L
    //   g' = c0.g + (c1.g - c0.g) * L = c0.g + dG*L
    //   b' = c0.b + (c1.b - c0.b) * L = c0.b + dB*L
    //   a' = a
    //
    // This can be expressed as another color matrix (when L is stored in R):
    //
    //  | dR,  0,  0,  0, c0.r |
    //  | dG,  0,  0,  0, c0.g |
    //  | dB,  0,  0,  0, c0.b |
    //  |  0,  0,  0,  1,    0 |
    //
    // Composing these two, we get the total tint matrix:

    const SkScalar tint_matrix[] = {
        dR*kR, dR*kG, dR*kB, 0, c0.fR * 255,
        dG*kR, dG*kG, dG*kB, 0, c0.fG * 255,
        dB*kR, dB*kG, dB*kB, 0, c0.fB * 255,
            0,     0,     0, 1,           0,
    };

    return SkColorFilter::MakeMixer(nullptr,
                                    SkColorFilter::MakeMatrixFilterRowMajor255(tint_matrix),
                                    fWeight);
}

} // namespace sksg
