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

#pragma once

#include "glmCoreAPI.h"
#include "glmRTTI.h"
#include "glmAssetGroupV2.h"
#include "glmMeshAssetV7.h"
#include "glmGeometryAsset.h"
#include "glmShadingGroup.h"
#include "glmRenderingType.h"
#include "glmGenericSpecificConverterMapping.h"
#include "glmCharacterUserData.h"
#include "glmShaderAsset.h"
#include "glmShaderAttribute.h"
#include "glmClothAsset.h"
#include "glmGolaemCharacterBlindDataOverride.h"
#include "glmGolaemCharacterSkeletonOverride.h"
#include "glmPhysicsOverride.h"
#include "glmGolaemCharacterInterface.h"
#include "glmBoneDisplayConfiguration.h"

#include <glmGolaemCharacterDeclarations.h> // GolaemCharacter declarations

namespace glm
{
    class HierarchicalSkeletonDescriptionV1;

    struct GolaemCharacterV21;

    struct GLM_CORE_API GolaemCharacterV22 : public GolaemCharacterInterface
    {
        GLM_VIRTUAL_RTTI("09b6665b-4380-4858-8c7d-f15d84f6b515", glm::GolaemCharacterV22, addAttributes);

    public:
        GLM_CLASS_STAT_ID( glm::MemoryStatIds::Simulation);

        /// Name of the character
        glm::GlmString _name = "Character";
        int _fileVersion = 22;

        glm::PODArray<int> _mainAssetGroups;
        glm::PODArray<int> _mainShaderAttributes;

        glm::Array<AssetGroupV2> _allAssetGroups;
        glm::Array<MeshAssetV7> _meshAssets;

        glm::GlmMap<short, glm::Array<GeometryAssetV4>> _geometryAssetsPerTags; // short = geometryTag, array<geoAsset> = the list of LODs of this geometryTag

        glm::Array<ShadingGroupV1> _shadingGroups;

        glm::Array<ShaderAttributeV3> _shaderAttributes;

        glm::Array<ShaderAssetV2> _shaderAssets;

        glm::Array<RenderingTypeV4> _renderingTypes;

        GenericSpecificConverterMappingV8 _converterMapping; // animation data
        CharacterUserDataV0 _characterUserData;              // additional user data

        Array<SkeletonOverrideV0> _skeletonOverrides;
        Array<BlindDataOverrideV0> _blindDataOverrides;
		Array<PhysicsOverrideV0> _physicsOverrides;

        Vector3 _perceptionShapeExtents = Vector3(1.f);
        Vector3 _perceptionShapeOffset = Vector3(0.f);

        Array<BoneDisplayConfigurationV0> _skeletonDisplay;

    public:
        GolaemCharacterV22();
        ~GolaemCharacterV22();

        /**
         * \brief V21 backwards compatibility
         * \note V22 adds Mesh asset V7 (LOD and geometryTag names) and geoAsset v4 LODNames
         */
        void createFromV21(const GolaemCharacterV21& characterOlderVersion);

        // Accessors
        const GenericSpecificConverterMappingV8& getConverterMapping() const;
        void setConverterMapping(const GenericSpecificConverterMappingV8& mapping);
        const CharacterUserDataV0& getCharacterUserData() const;
        void setCharacterUserData(const CharacterUserDataV0& userData);

        //// Override Accessors
        //void expandMainShaderAttributes();
        //void setShadingNamespace(const glm::GlmString& shadingNamespace);

        //void updateRelativePaths(const glm::GlmString& filePath);

        //void autoComputePerceptionShape();

        void autoComputeSkeletonDisplay(const PODArray<int>& autoComputeBones);

    private:
        GLM_DISALLOW_COPY_AND_ASSIGN(GolaemCharacterV22);
        static void addAttributes();
    };
} // namespace glm
