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

#pragma once

//golaem motion includes
#include "glmSDKAPI.h"
#include "glmMotionDefinitions.h"
#include <glmAbstractSpecificAnimation.h>

//golaem core includes
#include <glmHierarchicalSkeletonDescription.h>

namespace glm
{
    class SpecificPosture;

    /**
	 * \brief Represent a generic normalized animation
	 *
	 * \author dev@golaem.com
	 *
	 */
    class GLM_SDK_API StreamAnimation : public AbstractSpecificAnimation
    {
    public: //static methods
        GLM_CLASS_STAT_ID( glm::MemoryStatIds::GolaemShared)

    public: //methods
        //************************************************************
        //! @name Constructors and destructor
        //************************************************************
        //@{
        /**
		 * \brief Default constructor
		 */
        StreamAnimation();

        /**
		 * \brief Destructor
		 */
        ~StreamAnimation();
        //@}

        //************************************************************
        //! @name
        //************************************************************
        //@{
        /**
		 * \brief Get the animation delta time between each posture
		 */
        inline Time getDeltaTime() const override;

        /**
		 * \brief Get the skeleton description from the BVH file
		 */
        inline const HierarchicalSkeletonDescription* getSkeletonDescription() const override;

        /**
		 * \brief Get the size of the specific postures array
		 */
        inline int getPosturesCount() const override;

        /**
		 * \brief Get the array of the specific postures representing the animation
		 */
        inline const SpecificPosture* getPostures() const override;

        bool cropMotion(int /*newFirstFrame*/, int /*newLastFrame*/) override { return false; }
        bool editMotion(const EditMotionParameters& /*parameters*/) override { return false; }

        const Array<BlindData>& getBlindDataInfo() const override { return _emptyBlindDataInfo; }
        const PODArray<float>& getBlindData(int) const override { return _emptyFrameBlindData; }
        bool hasGroundNormal() const override { return false; }
        Vector3 getGroundNormalAtFrame(unsigned int /*frameIndex*/, unsigned int /*constraintSequenceIndex*/) const override { return Vector3(0,0,1); }
        //@}

    public: //data
        //************************************************************
        //! @name Datas
        //************************************************************
        //@{
        HierarchicalSkeletonDescription _skeletonDescription;
        Time _animationDeltaTime = 0.033;
        Array<SpecificPosture> _animationPostures;

        Array<BlindData> _emptyBlindDataInfo;
        PODArray<float> _emptyFrameBlindData;

        glm::GlmMap<const HierarchicalBone*, int> _numberOfChannelsPerBone;              //TODO: make a simple array here
        glm::GlmMap<const HierarchicalBone*, glm::Array<glm::GlmString>> _bonesChannels; //TODO: make a simple array here
        //@}
    };

    //------------------------------------------------------------
    inline Time
        StreamAnimation::getDeltaTime() const
    {
        return _animationDeltaTime;
    }

    //------------------------------------------------------------
    inline const HierarchicalSkeletonDescription*
        StreamAnimation::getSkeletonDescription() const
    {
        return &_skeletonDescription;
    }

    //------------------------------------------------------------
    inline int
        StreamAnimation::getPosturesCount() const
    {
        return _animationPostures.sizeInt();
    }

    //------------------------------------------------------------
    inline const SpecificPosture*
        StreamAnimation::getPostures() const
    {
        return _animationPostures.begin();
    }
} // namespace glm
