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

#include "modules/skottie/src/effects/Effects.h"

#include "include/effects/SkRuntimeEffect.h"
#include "include/private/SkTPin.h"
#include "modules/skottie/src/Adapter.h"
#include "modules/skottie/src/SkottieJson.h"
#include "modules/skottie/src/SkottieValue.h"
#include "modules/sksg/include/SkSGColorFilter.h"

namespace skottie::internal {

#ifdef SK_ENABLE_SKSL

namespace  {

// The B&W effect allows controlling individual luminance contribution of
// primary and secondary colors.
//
// The implementation relies on computing primary/secondary relative weights
// for the input color on the hue hexagon, and modulating based on weight
// coefficients.
//
// Note:
//   - at least one of (dr,dg,db) is 0
//   - at least two of (wr,wg,wb) and two of (wy,wc,wm) are 0
//  => we are effectively selecting the color hue sextant without explicit branching
//
// (inspired by https://github.com/RoyiAvital/StackExchangeCodes/blob/master/SignalProcessing/Q688/ApplyBlackWhiteFilter.m)

static sk_sp<SkRuntimeEffect> make_effect() {
    static constexpr char BLACK_AND_WHITE_EFFECT[] = R"(
        uniform half kR, kY, kG, kC, kB, kM;

        half4 main(half4 c) {
            half m = min(min(c.r, c.g), c.b),

                dr = c.r - m,
                dg = c.g - m,
                db = c.b - m,

                // secondaries weights
                wy = min(dr,dg),
                wc = min(dg,db),
                wm = min(db,dr),

                // primaries weights
                wr = dr - wy - wm,
                wg = dg - wy - wc,
                wb = db - wc - wm,

                // final luminance
                l = m + kR*wr + kY*wy + kG*wg + kC*wc + kB*wb + kM*wm;

            return half4(l, l, l, c.a);
        }
    )";

    static const SkRuntimeEffect* effect =
            SkRuntimeEffect::MakeForColorFilter(SkString(BLACK_AND_WHITE_EFFECT)).effect.release();
    SkASSERT(effect);

    return sk_ref_sp(effect);
}

class BlackAndWhiteAdapter final : public DiscardableAdapterBase<BlackAndWhiteAdapter,
                                                                 sksg::ExternalColorFilter> {
public:
    BlackAndWhiteAdapter(const skjson::ArrayValue& jprops,
                         const AnimationBuilder& abuilder,
                         sk_sp<sksg::RenderNode> layer)
        : INHERITED(sksg::ExternalColorFilter::Make(std::move(layer)))
        , fEffect(make_effect())
    {
        SkASSERT(fEffect);

        enum : size_t {
                kReds_Index = 0,
             kYellows_Index = 1,
              kGreens_Index = 2,
               kCyans_Index = 3,
               kBlues_Index = 4,
            kMagentas_Index = 5,
            // TODO
            //    kTint_Index = 6,
            // kTintColorIndex = 7,
        };

        EffectBinder(jprops, abuilder, this)
            .bind(    kReds_Index, fCoeffs[0])
            .bind( kYellows_Index, fCoeffs[1])
            .bind(  kGreens_Index, fCoeffs[2])
            .bind(   kCyans_Index, fCoeffs[3])
            .bind(   kBlues_Index, fCoeffs[4])
            .bind(kMagentas_Index, fCoeffs[5]);
    }

private:
    void onSync() override {
        struct {
            float normalized_coeffs[6];
        } coeffs = {
            (fCoeffs[0] ) / 100,
            (fCoeffs[1] ) / 100,
            (fCoeffs[2] ) / 100,
            (fCoeffs[3] ) / 100,
            (fCoeffs[4] ) / 100,
            (fCoeffs[5] ) / 100,
        };

        this->node()->setColorFilter(
                fEffect->makeColorFilter(SkData::MakeWithCopy(&coeffs, sizeof(coeffs))));
    }

    const sk_sp<SkRuntimeEffect> fEffect;

    ScalarValue                  fCoeffs[6];

    using INHERITED = DiscardableAdapterBase<BlackAndWhiteAdapter, sksg::ExternalColorFilter>;
};

} // namespace

#endif  // SK_ENABLE_SKSL

sk_sp<sksg::RenderNode> EffectBuilder::attachBlackAndWhiteEffect(
        const skjson::ArrayValue& jprops, sk_sp<sksg::RenderNode> layer) const {
#ifdef SK_ENABLE_SKSL
    return fBuilder->attachDiscardableAdapter<BlackAndWhiteAdapter>(jprops,
                                                                    *fBuilder,
                                                                    std::move(layer));
#else
    // TODO(skia:12197)
    return layer;
#endif
}

} // namespace skottie::internal
