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

#pragma once

#include "glmSDKAPI.h"
#include "glmNavigationMesh3.h"
#include "glmProgress.h"

namespace glm
{
	/** 
	* \brief An abstract class defining navigation mesh 3 creators.
	*
	* \ingroup NavMesh3
	*
	* \author Golaem <dev@golaem.com>
	*/
	class GLM_SDK_API AbstractNavigationMesh3Creator
	{
	public:
		/**
		* \brief Constructor
		*/
		AbstractNavigationMesh3Creator();

		/**
		* \brief Destructor
		*/
		virtual ~AbstractNavigationMesh3Creator();

		/**
		* \brief Create a new prismatic subdivision.
		*/
		NavigationMesh3 * operator()(bool& cancel);

		/**
		* \brief Returns the process progress
		* \return the process progress
		*/
		const Progress::SP getProgress() const;

		/**
		* \brief Returns a reference to the process progress
		* \return a reference to the process progress
		*/
		Progress::SP touchProgress();

		/**
		* \brief The navigation mesh that is created.
		*/
		NavigationMesh3 * _navigationMesh;

	protected:

		/**
		* \brief The method to implement to perform computations.
		*/
		virtual bool doComputation(bool& cancel) = 0;

		/**
		* \name Navigation mesh accesses
		*/
		//@{
		const glm::Array< std::pair<SemanticObjectTypeValue,bool> > & getEdgesSemanticObjects() const;
		glm::Array< std::pair<SemanticObjectTypeValue,bool> > & touchEdgesSemanticObjects();

		const glm::PODArray<SemanticObjectTypeValue> & getCellsSemanticObjects() const;
		glm::PODArray<SemanticObjectTypeValue> & touchCellsSemanticObjects();
		glm::Array< glm::PODArray<unsigned int> >& touchEdgeSemanticTypeCountPerZone();

		const glm::Array<int>& getCellConnexZones() const;
		glm::Array<int>& touchCellConnexZones();

		const glm::Array<int>& getEdgeValidity() const;
		glm::Array<int>& touchEdgeValidity();

		NavigationMeshCellId getFreeCellId() const;
		NavigationMeshEdgeId getFreeEdgeId() const;

		const glm::Array<StaticArray<NavigationMeshEdgeId, 3, false> > & getCellsEdges() const;
		glm::Array<StaticArray<NavigationMeshEdgeId, 3, false> > & touchCellsEdges();

		const glm::Array<StaticArray<NavigationMeshCellId, 2> > & getEdgesCells() const;
		glm::Array< StaticArray<NavigationMeshCellId, 2> > & touchEdgesCells();

		const glm::Array<Segment3 > & getEdgesSegments3() const;
		glm::Array< Segment3 > & touchEdgesSegments3();

		const glm::Array< Triangle3 > & getCellsTriangles3() const;
		glm::Array< Triangle3 > & touchCellsTriangles3();

		const glm::PODArrayOfArray<NavigationMeshCellId> & getCellsToOverlappingCells() const;
		glm::PODArrayOfArray<NavigationMeshCellId> & touchCellsToOverlappingCells();

		const Vector2& getBoundingBoxLowerBound() const;
		Vector2& touchBoundingBoxLowerBound();

		const Vector2& getBoundingBoxUpperBound() const;
		Vector2& touchBoundingBoxUpperBound();
		//@}

		/**
		* \brief This process progress.
		*/
		Progress::SP _progress;
	};
}
