/***************************************************************************
*                                                                          *
*  Copyright (C) Golaem S.A.  All Rights Reserved.                         *
*                                                                          *
***************************************************************************/

#pragma once

#include "glmSDKAPI.h"
#include "glmString.h"
#include "glmAnimationReplayMapping.h"

namespace glm
{
    //predeclarations
    class AnimationPlayBN;
    class SynchronizedBlendBN;
    class SimpleBlendBN;
    class BlendBNTrajectorySampler;

    class GLM_SDK_API DelaunayLocomotionInterface
    {
    public: //structures
        struct LocomotionDataPerAnimation
        {
        public:
            AnimationPlayBN* _animationBlendNode;
            int _animationBlendNodeIndex; // index of the corresponding subnode in the syncNode

            glm::GlmString _animationPath;
            float _replayRatio;
            float _linearVelocity; // use entity scale to get correct values when comparing to this, which is based on skeleton at scale 1.f
            float _angularVelocity;
            bool _interpolateBetweenFrames;
            bool _mirrored;
            bool _forceConstantGroundHeightInAnimation;
            int _animationChannel;

            AnimationReplayMapping _theAnimationReplayMapping; // one per anim
            bool _allowBoneToBoneIdentityMappingIfAvailable = true;
        public:
            GLM_CLASS_STAT_ID( glm::MemoryStatIds::Simulation);

            inline LocomotionDataPerAnimation();
            inline ~LocomotionDataPerAnimation();
        };

    public: //methods
        //************************************************************
        //! @name Behavior blend-tree structure
        //************************************************************
        //@{
        virtual const SynchronizedBlendBN* getSynchroBlendNode() const = 0;
        virtual const SimpleBlendBN* getSimpleBlendNode() const = 0; //might be NULL
        virtual const AnimationPlayBN* getAnimationNode(int animationIndex) const = 0;
        virtual const BlendBNTrajectorySampler* getTrajectorySampler() const = 0; //might be NULL
        //@}

        //************************************************************
        //! @name Animations informations
        //************************************************************
        //@{
        virtual int getAnimationsCount() const = 0;
        virtual int getStartingAnimationIndex(int64_t indexInEntityType) const = 0;
        virtual const char* getAnimationPath(int animationIndex) const = 0;
        virtual const LocomotionDataPerAnimation& getAnimationData(int animationIndex) const = 0;
        virtual bool isAnimationInModel(int animationIndex) = 0;
        virtual int getAnimationIndexInChannel(int64_t entityIndex, int animationIndexWithChannel) = 0;
        //@}

        //************************************************************
        //! @name Current state information
        //************************************************************
        //@{
        virtual float getCurrentLinearVelocity(int64_t index) const = 0;
        virtual float getMinLinearVelocity() const = 0;
        virtual float getMaxLinearVelocity() const = 0;

        virtual float getCurrentAngularVelocity(int64_t index) const = 0;
        virtual float getMinAngularVelocity() const = 0;
        virtual float getMaxAngularVelocity() const = 0;
        //@}
    };

    //-------------------------------------------------------------------------
    inline DelaunayLocomotionInterface::LocomotionDataPerAnimation::LocomotionDataPerAnimation()
        : _animationBlendNode(NULL)
        , _animationBlendNodeIndex(-1)
        , _forceConstantGroundHeightInAnimation(false)
        , _animationChannel(-1)
    {
    }

    //-------------------------------------------------------------------------
    inline DelaunayLocomotionInterface::LocomotionDataPerAnimation::~LocomotionDataPerAnimation()
    {
        GLM_DEBUG_ASSERT(_animationBlendNode == NULL);
    }
} // namespace glm