#ifndef _RIVE_BLEND_STATE_INSTANCE_HPP_
#define _RIVE_BLEND_STATE_INSTANCE_HPP_

#include <string>
#include <vector>
#include "rive/animation/state_instance.hpp"
#include "rive/animation/blend_state.hpp"
#include "rive/animation/linear_animation_instance.hpp"

namespace rive {
    class AnimationState;

    template <class K, class T> class BlendStateInstance;
    template <class T> class BlendStateAnimationInstance {
        template <class A, class B> friend class BlendStateInstance;

    private:
        const T* m_BlendAnimation;
        LinearAnimationInstance m_AnimationInstance;
        float m_Mix = 0.0f;

    public:
        const T* blendAnimation() const { return m_BlendAnimation; }
        const LinearAnimationInstance* animationInstance() const { return &m_AnimationInstance; }

        BlendStateAnimationInstance(const T* blendAnimation, ArtboardInstance* artboard) :
            m_BlendAnimation(blendAnimation),
            m_AnimationInstance(blendAnimation->animation(), artboard)
        {}

        void mix(float value) { m_Mix = value; }
    };

    template <class K, class T> class BlendStateInstance : public StateInstance {
    protected:
        std::vector<BlendStateAnimationInstance<T>> m_AnimationInstances;
        bool m_KeepGoing = true;

    public:
        BlendStateInstance(const K* blendState, ArtboardInstance* artboard) : StateInstance(blendState) {
            for (auto blendAnimation : blendState->animations()) {
                m_AnimationInstances.emplace_back(
                    BlendStateAnimationInstance<T>(static_cast<T*>(blendAnimation), artboard));
            }
        }

        bool keepGoing() const override { return m_KeepGoing; }

        void advance(float seconds, SMIInput** inputs) override {
            m_KeepGoing = false;
            for (auto& animation : m_AnimationInstances) {
                if (animation.m_AnimationInstance.advance(seconds)) {
                    m_KeepGoing = true;
                }
            }
        }

        void apply(float mix) override {
            for (auto& animation : m_AnimationInstances) {
                float m = mix * animation.m_Mix;
                animation.m_AnimationInstance.apply(m);
            }
        }

        // Find the animationInstance that corresponds to the blendAnimation.
        const LinearAnimationInstance*
        animationInstance(const BlendAnimation* blendAnimation) const {
            for (auto& animation : m_AnimationInstances) {
                if (animation.m_BlendAnimation == blendAnimation) {
                    return animation.animationInstance();
                }
            }
            return nullptr;
        }
    };
} // namespace rive
#endif