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

#pragma once

#include "glmSDKAPI.h"
#include "glmPathDefinitions.h"

#include "glmMap.h"

namespace glm
{
	class SpatialEnvironment;
	class Vector3;
	class RandomNumberGenerator;
	class NavigationMesh3;

	/**
	* \brief Randomize a target in a given environment, starting at a given position, and matching some parameters
	*/
	class GLM_SDK_API TargetRandomizer
	{
	public:

		GLM_CLASS_STAT_ID( glm::MemoryStatIds::Simulation)

		TargetRandomizer();
		virtual	~TargetRandomizer(); 

		/**
		* \brief initialize internal data built from a spatialEnvironment
		*/
		bool initialize( const SpatialEnvironment* environment );

		/**
		* \brief returns a target in reachable area, with a minimum bird-distance
		*/
		bool computeRandomTarget(
			Vector3& foundPosition, 
			Vector3& foundUpVector,
			const Vector3& position, 
			const Vector3& upVector,
			float radius,
			RandomNumberGenerator& rng,
			NavigationMeshCellId startCellId = NavigationMeshCellId(-1) ) const;

		/**
		* \brief deinit random target generator
		*/
		void clean();

		/**
		* \brief is the random target generator initialized
		* \return true if OK
		*/
		inline bool isInitialized() const;

	private:

		struct RandomSurfaceToCellEntry
		{
			float _currentCumulativeSurface;
			NavigationMeshCellId _cellId;
		};

		void computeConnexZonePartition(const NavigationMesh3& navigationMesh, glm::Array< glm::PODArray<NavigationMeshCellId> >& zones, glm::PODArray<bool>& exploredTempBuffer);
		
		//glm::GlmMap< NavigationMeshCellId, int >	_cellToZoneMapping;		//!< for input cellId, find zone
		glm::PODArray<int> _cellToZoneMapping; // we can expect cellIds going from 0 to n, no need for a map.
		glm::PODArray<float> _totalSurfacePerZone;
		glm::Array< glm::PODArray< RandomSurfaceToCellEntry > > _randomSurfaceToCell; //!< for a given zone, pair cumulatedSurface / cellId		

		SpatialEnvironment*						_environment;			//!< the environment given at init time, MUST BE TREATED AS CONST
		bool									_initialized;			//!< is the target randomizer initialized ?
	};


	//-----------------------------------------------------------------------------
	// isInitialized 
	//-----------------------------------------------------------------------------
	inline bool TargetRandomizer::isInitialized() const
	{
		return _initialized;
	}
}

