#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) :
            m_BlendAnimation(blendAnimation),
            m_AnimationInstance(blendAnimation->animation()) {}

        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) : StateInstance(blendState) {
            for (auto blendAnimation : blendState->animations()) {
                m_AnimationInstances.emplace_back(
                    BlendStateAnimationInstance<T>(
                        static_cast<T*>(blendAnimation)));
            }
        }

        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(Artboard* artboard, float mix) override {
            for (auto& animation : m_AnimationInstances) {
                float m = mix * animation.m_Mix;
                animation.m_AnimationInstance.apply(artboard, 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