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

#pragma once

#include "glmSDKAPI.h"
#include "glmVoxelNavigationMesh3Creator.h"
#include "glmRoadmapCreator.h"
#include "glmVoxelSpatialEnvironmentCreatorParameters.h"
#include "glmAbstractSpatialEnvironmentCreator.h"

struct rcHeightfield;
struct rcConfig;

namespace glm
{
	class SpatialEnvironment;
	class BuildTileVoxelMeshWorkerThread;

	/**
	* \brief Recast data
	*/
	struct RecastData
	{
		glm::Array<rcPolyMeshDetail*> _detailMeshes;

		RecastData();

		~RecastData();

		void cleanup();
	};

	/**
	* \brief RecastGeometry
	*/
	struct RecastGeometry
	{
		float* _verts;
		int _nverts;
		int* _tris;
		int _ntris;

		RecastGeometry();

		~RecastGeometry();

		void cleanup();
	};

	/**
	* \brief VoxelSpatialEnvironmentCreator comments
	*/
	class GLM_SDK_API VoxelSpatialEnvironmentCreator : public AbstractSpatialEnvironmentCreator
	{
		friend class BuildTileVoxelMeshWorkerThread;

	public:

		VoxelSpatialEnvironmentCreator() ;
		virtual ~VoxelSpatialEnvironmentCreator() ;

		/**
		* \name The maximum slope
		*/
		//@{
		Angle getMaximumSlope() const;
		void setMaximumSlope(Angle angle);
		//@}

		/**
		* \name The computation parameters
		*/
		//@{
		const VoxelSpatialEnvironmentCreatorParameters& getParameters() const; 
		VoxelSpatialEnvironmentCreatorParameters& touchParameters();
		//@}

	protected:

		/**
		* \brief Computes the spatial environment
		*/
		virtual GseComputationErrorCode::Value doComputation(bool& cancel);

		/**
		* \brief The navigation mesh computation functor.
		*/
		VoxelNavigationMesh3Creator _computeNavigationMesh;

		/**
		* \brief The roadmap computation functor.
		*/
		RoadmapCreator _computeRoadmap;

		/**
		* \brief Spatial environment creation parameters
		*/
		VoxelSpatialEnvironmentCreatorParameters _parameters;

		/**
		* \brief Maximum slope
		*/
		Angle _maximumSlope;

		/**
		* \brief Data required for the Recast subdivision
		*/
		RecastData _recastData;

		/**
		* \brief Builds the Recast geometry
		*/
		bool buildRecastGeometry(const Geometry3& geometry, RecastGeometry& recastGeom, float bmin[3], float bmax[3], Progress::SP progress);

		/**
		* \brief Computes the Recast subdivision
		*/
		bool computeRecastSubdivision(Progress::SP progress, unsigned int threadCount=0);

	private:

		GLM_DISALLOW_COPY_AND_ASSIGN(VoxelSpatialEnvironmentCreator);

		/**
		* \brief Computes the data for a voxel mesh tile
		*/
		bool buildTileVoxelMesh(const RecastGeometry& recastGeometry, const float* bmin, const float* bmax, const rcConfig& recastConfig, int tileIdx, rcHeightfield* heightField);
		rcPolyMeshDetail* buildTileVoxelMesh(const RecastGeometry& recastGeometry, const float* bmin, const float* bmax, const rcConfig& config, rcHeightfield* heightField) const;

		bool*	_cancel;
	};
}
