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

#include "include/core/SkData.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkString.h"
#include "include/effects/SkRuntimeEffect.h"
#include "include/private/base/SkAssert.h"
#include "modules/skottie/src/Adapter.h"
#include "modules/skottie/src/SkottiePriv.h"
#include "modules/skottie/src/SkottieValue.h"
#include "modules/skottie/src/effects/Effects.h"
#include "modules/sksg/include/SkSGColorFilter.h"
#include "modules/sksg/include/SkSGRenderNode.h"

#include <cstddef>
#include <utility>

namespace skjson {
class ArrayValue;
}

namespace skottie::internal {
namespace {

// Convert to black & white, based on input luminance and a threshold uniform.
static constexpr char gThresholdSkSL[] =
    "uniform half t;"

    "half4 main(half4 color) {"
        "half4 c = unpremul(color);"

        "half lum = dot(c.rgb, half3(0.2126, 0.7152, 0.0722)),"
              "bw = step(t, lum);"

        "return bw.xxx1 * c.a;"
    "}"
;

static sk_sp<SkRuntimeEffect> threshold_effect() {
    static const SkRuntimeEffect* effect =
        SkRuntimeEffect::MakeForColorFilter(SkString(gThresholdSkSL), {}).effect.release();
    SkASSERT(effect);

    return sk_ref_sp(effect);
}

class ThresholdAdapter final : public DiscardableAdapterBase<ThresholdAdapter,
                                                             sksg::ExternalColorFilter> {
public:
    ThresholdAdapter(const skjson::ArrayValue& jprops,
                     sk_sp<sksg::RenderNode> layer,
                     const AnimationBuilder& abuilder)
        : INHERITED(sksg::ExternalColorFilter::Make(std::move(layer)))
    {
        enum : size_t {
            kLevel_Index = 0,
        };

        EffectBinder(jprops, abuilder, this).bind(kLevel_Index, fLevel);
    }

private:
    void onSync() override {
        auto cf =
                threshold_effect()->makeColorFilter(SkData::MakeWithCopy(&fLevel, sizeof(fLevel)));

        this->node()->setColorFilter(std::move(cf));
    }

    ScalarValue fLevel = 0;

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

} // namespace

sk_sp<sksg::RenderNode> EffectBuilder::attachThresholdEffect(const skjson::ArrayValue& jprops,
                                                             sk_sp<sksg::RenderNode> layer) const {
    return fBuilder->attachDiscardableAdapter<ThresholdAdapter>(jprops,
                                                                std::move(layer),
                                                                *fBuilder);
}

} // namespace skottie::internal
