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

#pragma once

#include "glmRTTI.h"
#include "glmCoreAPI.h"
#include "glmString.h"

#include <glmGolaemCharacterDeclarations.h> // GolaemCharacter declarations

#define GLM_SPECIFICPOSTURE_PERBONE_BLINDDATA_COUNT 8

namespace glm
{
    struct BlindDataV0;

    struct GLM_CORE_API BlindDataV1
    {
        GLM_RTTI("1d928022-9075-483d-b5c8-c3deb3ed29d0", glm::BlindDataV1, addAttributes)

    public:
        /**
		* \brief Type describing what the blind data is
		*/
        struct Type
        {
        public:
            enum Value
            {
                BLENDSHAPE = 0,
                BLIND,
                SPECIFIC_ANIMATION,
                END
            };
        };

        GLM_CLASS_STAT_ID( glm::MemoryStatIds::GolaemShared)

        glm::GlmString _groupName; // mostly for blind data of type BLENDSHAPE
        glm::GlmString _name;
        BlindDataV1::Type::Value _type;
        unsigned int _floatCount;

        unsigned int _firstValueIndex; // not serialize, initialized at real time

        bool operator==(const BlindDataV1& other) const;

        /**
		* \brief Helpers with SPECIFIC_ANIMATION blind data
		*/
        static void addSpecificAnimationBlindDataInfo(glm::Array<BlindDataV1>& outBlindData, const glm::GlmString& boneName);
        static void transformValuesToBlindData(glm::PODArray<float>& outBlindData, size_t firstBlindDataIndex, const Vector3& inLocalPos, const Quaternion& inLocalOri, float inWeight);
        static void blindDataToTransformValues(Vector3& outLocalPos, Quaternion& outLocalOri, float& outWeight, const glm::PODArray<float>& blindData, size_t firstBlindDataIndex);

        static void specificAnimationBlindDataClear(glm::PODArray<float>& blindDataSet, size_t blindDataIndex);
        static void specificAnimationBlindDataAdd(glm::PODArray<float>& firstBlindDataSet, size_t firstBlindDataIndex, const glm::PODArray<float>& secondBlindDataSet, size_t secondBlindDataIndex, float weight);
        static void specificAnimationBlindDataBlend(glm::PODArray<float>& firstBlindDataSet, size_t firstBlindDataIndex, const glm::PODArray<float>& secondBlindDataSet, size_t secondBlindDataIndex, float weight);

        void createfromPreviousVersion(const BlindDataV0& previousVersion);

    private:
        static void addAttributes();
        void setTypeUInt(unsigned int type);
        unsigned int getTypeUInt() const;
    };
} // namespace glm
