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

#pragma once

#include "glmCore.h"
#include "glmString.h"
#include "glmArray.h"
#include "glmList.h"
#include "glmMap.h"

#include "glmCrowdIOAPI.h"

namespace glm
{
namespace crowdio
{
class CrowdGcgCharacter;

struct GCGCharacterLoadInfo
{
    glm::GlmString filePath;
    glm::GlmString skeletonRootName;
};

class GLM_CROWDIO_API CrowdGcgStorage
{
  public:
    CrowdGcgStorage();

    virtual ~CrowdGcgStorage();

    /**
	* \brief Loads and returns the FBX Character associated to the given filePath (or NULL if the character associated to the file path was never preloaded)
	* \param filePath File path of the character to search for
	* \warning The character must be preloaded (using preLoadCharacter) before calling this function
	*/
    CrowdGcgCharacter* getCharacter(const glm::GlmString& filePath, const glm::Array<glm::GlmString>& dirmap, bool& newCharacter);

    /**
	* \brief Returns the file names of the characters that have been preloaded
	*/
    void getUsedCharacterFiles(glm::Array<glm::GlmString>& characterFiles) const;

    /**
	* \brief Returns the maximum number of loaded characters
	*/
    unsigned int getMaxLoadedCharactersCount() const;

    /**
	* \brief Sets the maximum number of loaded characters
	*/
    void setMaxLoadedCharactersCount(unsigned int count);

    /**
	* \brief Returns the loaded characters
	*/
    const glm::GlmList<CrowdGcgCharacter*>& getLoadedCharacters() const;
    //@}

    /**
	* \brief Preloads a FBX character. Does nothing if the character already exists.
	* \param filePath The file path of the FBX file containing the character
	* \param skeletonRootName The name of the characters' skeleton root in the FBX file
	* \param[in] triangulate If true, all the meshes are triangulated
	*/
    void preLoadCharacter(const glm::GlmString& filePath, const glm::GlmString& skeletonRootName);

    /**
	* \brief Unloads a character to save memory space
	* The character must first be preloaded
	* Calling getCharacter automatically reloads it
	*/
    void unloadCharacter(CrowdGcgCharacter* character);

    /**
	* \brief Unloads the character associated to the file and removes the file (the character is no longer preloaded)
	*/
    void removeFile(const glm::GlmString& filePath);

    /**
	* \brief Unloads all characters
	*/
    void clear();

  protected:
    //************************************************************
    /*! @name Data Members
	*/
    //*********************************************************
    //@{

    /// The imported characters
    glm::GlmMap<glm::GlmString, CrowdGcgCharacter*> _importedCharacters;

    /// The loaded characters
    glm::GlmList<CrowdGcgCharacter*> _loadedCharacters;

    /// The maximum number of loaded characters
    unsigned int _maxLoadedCharactersCount;

    /// The character reload infos, indexed by character id
    glm::GlmMap<glm::GlmString, GCGCharacterLoadInfo> _importedCharactersLoadInfos;
    //@}
};
} // namespace crowdio
} // namespace glm
