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

#pragma once

#include <glmCoreAPI.h>
#include "glmDelaunayQuery.h"

namespace glm
{
	/**
	* \brief Base class for Delaunay triangulation algorithm
	* 
	* \ingroup delaunay
	* \author Golaem <dev@golaem.com>
	*
	* \param float Manipulated scalar type (\ref Expression, double, float...)
	*/

	class GLM_CORE_API Delaunay
	{
	public:

		GLM_CLASS_STAT_ID( glm::MemoryStatIds::GolaemShared)

		/**
		* \brief destructor
		*/
		virtual ~Delaunay() ;


		/// \name Member Accessors
		/// @{
		/**
		* \brief get accessor to the query type
		* \return the query type
		*/
		inline int getQueryType() const ;

		/**
		* \get accessor to the vertices count
		* \return the number of vertices
		*/
		inline int getVerticesCount() const ;

		/**
		* \brief get accessor to the tolerance used for determining the intrinsic dimension of the input set of vertices
		* \return the tolerance used for determining the intrinsic dimension of the input set of vertices
		*/
		inline float getEpsilon() const ;

		/**
		* \brief returns the dimension of the triangulation
		* \return the dimension between 0 and n where n is the dimension of the space of the input points 
		*/
		inline int getDimension() const ;

		/**
		* \brief returns the number of simplices in the triangulation
		* \return the number of simples in the triangulation
		*/
		inline int getSimplicesCount() const ;

		/**
		* \brief returns the indices of the vertices of the simplicies of the triangulation
		* \return an array with getNumSimplices() tuples of getDimension()+1 elements and representing a simplex
		*/
		inline const int* getIndices() const ;

		/**
		* \brief returns the indices of the adjacent simplicies of the simplicies of the triangulation
		* \return an array with getSimplicesCount() tuples of getDimension()+1 elements and representing the getDimension()+1 adjacent simplicies of a simplex
		*/
		inline const int* getAdjacencies() const ;
		/// @}

	protected:

		/**
		* \brief constructor 
		* \param verticesCount number of vertices 
		* \param epsilon tolerance used for determining the intrinsic dimension of the input set of vertices
		* \param queryType wanted precision (see DelaunayQuery::Type doxygen for more information)
		* \return 
		*/
		Delaunay( const int verticesCount, const float epsilon, const DelaunayQuery::Type::Values queryType ) ;

		/// type of query, depending of the wanted precision (see DelaunayQuery::Type doxygen for more information)
		DelaunayQuery::Type::Values	_queryType ;

		/// number of vertices in the triangulation
		int	_verticesCount ;

		/// dimension of the triangulation
		int	_dimension ;

		/// number of simplices in the triangulation
		int	_simplicesCount ;

		/// array with getNumSimplices() tuples of getDimension()+1 elements and representing a simplex
		int* _indices ;

		/// array with getNumSimplices() tuples of getDimension()+1 elements and representing the getDimension()+1 adjacent simplicies of a simplex
		int* _adjacencies ;					

		/// tolerance used for determining the intrinsic dimension of the input set of vertices
		float _epsilon ;
	} ;

	//-----------------------------------------------------------------------------
	// getQueryType
	//-----------------------------------------------------------------------------

	inline int 
		Delaunay::getQueryType() const
	{
		return _queryType;
	}

	//-----------------------------------------------------------------------------
	// getVerticesCount
	//-----------------------------------------------------------------------------

	inline int 
		Delaunay::getVerticesCount() const
	{
		return _verticesCount;
	}

	//-----------------------------------------------------------------------------
	// getEpsilon
	//-----------------------------------------------------------------------------

	inline float 
		Delaunay::getEpsilon() const
	{
		return _epsilon;
	}

	//-----------------------------------------------------------------------------
	// getDimension
	//-----------------------------------------------------------------------------

	inline int 
		Delaunay::getDimension() const
	{
		return _dimension;
	}

	//-----------------------------------------------------------------------------
	// getSimplicesCount
	//-----------------------------------------------------------------------------

	inline int 
		Delaunay::getSimplicesCount() const
	{
		return _simplicesCount;
	}

	//-----------------------------------------------------------------------------
	// getIndices
	//-----------------------------------------------------------------------------

	inline const int* 
		Delaunay::getIndices() const
	{
		return _indices;
	}

	//-----------------------------------------------------------------------------
	// getAdjacencies
	//-----------------------------------------------------------------------------

	inline const int* 
		Delaunay::getAdjacencies() const
	{
		return _adjacencies;
	}
}

