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

#ifndef SkottieEffects_DEFINED
#define SkottieEffects_DEFINED

#include "modules/skottie/src/SkottiePriv.h"
#include "modules/skottie/src/animator/Animator.h"

class SkMaskFilter;

namespace sksg {
class MaskShaderEffect;
} // namespace sksg

namespace skottie {
namespace internal {

class EffectBuilder final : public SkNoncopyable {
public:
    EffectBuilder(const AnimationBuilder*, const SkSize&);

    sk_sp<sksg::RenderNode> attachEffects(const skjson::ArrayValue&,
                                          sk_sp<sksg::RenderNode>) const;

    sk_sp<sksg::RenderNode> attachStyles(const skjson::ArrayValue&,
                                         sk_sp<sksg::RenderNode>) const;

    static const skjson::Value& GetPropValue(const skjson::ArrayValue& jprops, size_t prop_index);

private:
    using EffectBuilderT = sk_sp<sksg::RenderNode>(EffectBuilder::*)(const skjson::ArrayValue&,
                                                                     sk_sp<sksg::RenderNode>) const;

    sk_sp<sksg::RenderNode> attachDropShadowEffect    (const skjson::ArrayValue&,
                                                       sk_sp<sksg::RenderNode>) const;
    sk_sp<sksg::RenderNode> attachFillEffect          (const skjson::ArrayValue&,
                                                       sk_sp<sksg::RenderNode>) const;
    sk_sp<sksg::RenderNode> attachGaussianBlurEffect  (const skjson::ArrayValue&,
                                                       sk_sp<sksg::RenderNode>) const;
    sk_sp<sksg::RenderNode> attachGradientEffect      (const skjson::ArrayValue&,
                                                       sk_sp<sksg::RenderNode>) const;
    sk_sp<sksg::RenderNode> attachHueSaturationEffect (const skjson::ArrayValue&,
                                                       sk_sp<sksg::RenderNode>) const;
    sk_sp<sksg::RenderNode> attachInvertEffect        (const skjson::ArrayValue&,
                                                       sk_sp<sksg::RenderNode>) const;
    sk_sp<sksg::RenderNode> attachEasyLevelsEffect    (const skjson::ArrayValue&,
                                                       sk_sp<sksg::RenderNode>) const;
    sk_sp<sksg::RenderNode> attachLinearWipeEffect    (const skjson::ArrayValue&,
                                                       sk_sp<sksg::RenderNode>) const;
    sk_sp<sksg::RenderNode> attachMotionTileEffect    (const skjson::ArrayValue&,
                                                       sk_sp<sksg::RenderNode>) const;
    sk_sp<sksg::RenderNode> attachProLevelsEffect     (const skjson::ArrayValue&,
                                                       sk_sp<sksg::RenderNode>) const;
    sk_sp<sksg::RenderNode> attachRadialWipeEffect    (const skjson::ArrayValue&,
                                                       sk_sp<sksg::RenderNode>) const;
    sk_sp<sksg::RenderNode> attachTintEffect          (const skjson::ArrayValue&,
                                                       sk_sp<sksg::RenderNode>) const;
    sk_sp<sksg::RenderNode> attachTransformEffect     (const skjson::ArrayValue&,
                                                       sk_sp<sksg::RenderNode>) const;
    sk_sp<sksg::RenderNode> attachTritoneEffect       (const skjson::ArrayValue&,
                                                       sk_sp<sksg::RenderNode>) const;
    sk_sp<sksg::RenderNode> attachVenetianBlindsEffect(const skjson::ArrayValue&,
                                                       sk_sp<sksg::RenderNode>) const;
    sk_sp<sksg::RenderNode> attachShiftChannelsEffect (const skjson::ArrayValue&,
                                                       sk_sp<sksg::RenderNode>) const;

    sk_sp<sksg::RenderNode> attachDropShadowStyle(const skjson::ObjectValue&,
                                                  sk_sp<sksg::RenderNode>) const;

    EffectBuilderT findBuilder(const skjson::ObjectValue&) const;

    const AnimationBuilder*   fBuilder;
    const SkSize              fLayerSize;
};

// Syntactic sugar/helper.
class EffectBinder {
public:
    EffectBinder(const skjson::ArrayValue& jprops,
                 const AnimationBuilder& abuilder,
                 AnimatablePropertyContainer* acontainer)
        : fProps(jprops)
        , fBuilder(abuilder)
        , fContainer(acontainer) {}

    template <typename T>
    const EffectBinder& bind(size_t prop_index, T& value) const {
        fContainer->bind(fBuilder, EffectBuilder::GetPropValue(fProps, prop_index), value);

        return *this;
    }

private:
    const skjson::ArrayValue&    fProps;
    const AnimationBuilder&      fBuilder;
    AnimatablePropertyContainer* fContainer;
};

/**
 * Base class for mask-shader-related effects.
 */
class MaskShaderEffectBase : public AnimatablePropertyContainer {
public:
    const sk_sp<sksg::MaskShaderEffect>& node() const { return fMaskEffectNode; }

protected:
    MaskShaderEffectBase(sk_sp<sksg::RenderNode>, const SkSize&);

    const SkSize& layerSize() const { return  fLayerSize; }

    struct MaskInfo {
        sk_sp<SkShader> fMaskShader;
        bool            fVisible;
    };
    virtual MaskInfo onMakeMask() const = 0;

private:
    void onSync() final;

    const sk_sp<sksg::MaskShaderEffect> fMaskEffectNode;
    const SkSize                        fLayerSize;
};

} // namespace internal
} // namespace skottie

#endif // SkottieEffects_DEFINED
