/***************************************************************************
*                                                                          *
*  Copyright (C) Golaem S.A.  All Rights Reserved.                         *
*                                                                          *
***************************************************************************/
#if defined(GLM_EXPORT_ALEMBIC)

#pragma once

#include "glmString.h"
#include "glmMap.h"

#include "glmCrowdIOAPI.h"
#include "glmAlembic.h"
#include "glmMutex.h"

namespace glm
{
	class Log;

	namespace crowdio
	{
		class AlembicCharacter;
		class AlembicSkeleton;

		class GLM_CROWDIO_API AlembicScene
		{
		public:
			AlembicScene();

			virtual ~AlembicScene();

			/**
			* \brief Cleans the Alembic scene
			*/
			bool cleanScene();

			/**
			* \brief Adds the character to the list of characters
			* \param character The character to add
			*/
            AlembicCharacter* createCharacter(const glm::GlmString& name);

			/**
			* \brief Adds the skeleton to the list of characters
			* \param character The skeleton to add
			*/
			AlembicSkeleton* createSkeleton(const glm::GlmString&, size_t, size_t, size_t, const glm::Array<GlmString>&, const glm::Array<GlmString>&);

			/**
			* \brief Exports the Alembic scene
			* \param filePath The path of the output file
			* \param frameRate The frame rate of the scene
			* \param startFrame The frame to start the export
			* \param log The log to write to
			*/
			bool exportScene(const glm::GlmString& filePath, float frameRate, int startFrame, bool groupFurPerAsset);

			bool startIncrementalSceneExport(const glm::GlmString& filePath, float frameRate, int startFrame, bool groupFurPerAsset);
			void exportCharactersIncremental();
			void exportSkeletonsIncremental(); // not const, compute BBox
			void endIncrementalSceneExport();

		private:

			Alembic::AbcGeom::OXform createXFormFor(GlmString assetGroupName, Alembic::AbcGeom::OXform& xformChar, GlmMap< GlmString, Alembic::AbcGeom::OXform>& assetGroupToXform, bool& newTransform);

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

			/// The collection of Alembic Character
			glm::GlmMap<glm::GlmString, AlembicCharacter*> _characters;

			/// The collection of Alembic Skeleton
			glm::GlmMap<glm::GlmString, AlembicSkeleton*> _skeletons;

			Alembic::AbcGeom::OArchive* _incrementalArchive;
			Alembic::AbcGeom::TimeSamplingPtr _incrementalSampling;
			bool _incrementalGroupFurPerAsset;

			glm::SpinLock _skeletonsLock;
			glm::SpinLock _charactersLock;
			//@}
		};
	}
}

#endif // GLM_EXPORT_ALEMBIC
