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

#pragma once

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

namespace glm
{
	/**
	* \brief This class defines 2D DelaunayQuery
	* 
	* \ingroup delaunay
	*
	* \author Golaem <dev@golaem.com>
	*
	* \param float Manipulated scalar type (\ref Expression, double, float...)
	*/

	class GLM_CORE_API DelaunayQuery2 : public DelaunayQuery
	{
	public:

		GLM_CLASS_STAT_ID( glm::MemoryStatIds::GolaemShared)

		/**
		* \brief constructor
		* \param verticesCount Number of vertices 
		* \param vertices Array of vertices whose Delaunay triangulation is required
		*/
		DelaunayQuery2(const int verticesCount, const Vector2& vertices) ;

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

		/// \name accessors
		/// @{
		/**
		* \returns the query type
		* \return the query type
		*/
		virtual DelaunayQuery::Type::Values getType() const ;

		/**
		* \brief returns the number of vertices in the triangulation
		* \return the number of vertices in the triangulation
		*/
		inline int getVerticesCount() const ;

		/**
		* \brief returns the input vertex array
		* \return the input vertex array
		*/
		inline const Vector2* getVertices () const ;
		//@}

		/// \name Queries about the relation of a point to various geometric objects
		/// @{
		/**
		*
		* \param i 
		* \param v0 
		* \param v1 
		* \return +1, on right of line | -1, on left of line | 0, on the line
		*/
		virtual int toLine (int i, int v0, int v1) const;
		/**
		*
		* \param i 
		* \param v0 
		* \param v1 
		* \return +1, on right of line | -1, on left of line | 0, on the line
		*/
		virtual int toLine (const Vector2& test, int v0, int v1) const;

		/**
		*
		* \param i 
		* \param v0 
		* \param v1 
		* \param v2 
		* \return +1, outside triangle | -1, inside triangle | 0, on triangle
		*/
		virtual int toTriangle (int i, int v0, int v1, int v2) const;

		/**
		*
		* \param i 
		* \param v0 
		* \param v1 
		* \param v2 
		* \return +1, outside triangle | -1, inside triangle | 0, on triangle
		*/
		virtual int toTriangle (const Vector2& test, int v0, int v1, int v2) const;

		/**
		*
		* \param i 
		* \param v0 
		* \param v1 
		* \param v2 
		* \return +1, outside circumcircle of triangle | -1, inside circumcircle of triangle | 0, on circumcircle of triangle
		*/
		virtual int toCircumcircle (int i, int v0, int v1, int v2) const;

		/**
		*
		* \param i 
		* \param v0 
		* \param v1 
		* \param v2 
		* \return +1, outside circumcircle of triangle | -1, inside circumcircle of triangle | 0, on circumcircle of triangle
		*/
		virtual int toCircumcircle (const Vector2& test, int v0, int v1, int v2) const;
		/// @}

		/// \name Helper Functions
		/// @{
		static float dot (float x0, float y0, float x1, float y1) ;
		static float det2 (float x0, float y0, float x1, float y1) ;
		static float det3 (float x0, float y0, float z0, float x1, float y1, float z1, float x2, float y2, float z2) ;
		/// @}

	protected:

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

		/// Input vertices
		const Vector2*	_vertices;			
	} ;

	//-----------------------------------------------------------------------------
	// getVertices
	//-----------------------------------------------------------------------------

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

	//-----------------------------------------------------------------------------
	// getVertices
	//-----------------------------------------------------------------------------

	inline const Vector2* 
		DelaunayQuery2::getVertices () const
	{
		return _vertices;
	}
}

