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

#pragma once

#include "glmAbstractGround.h"
#include "glmPlane3.h"

namespace glm
{
	/**
	* \brief Planar ground definition.
	*
	* \ingroup ground
	*
	* \author Golaem <dev@golaem.com>
	*/
	class GLM_SDK_API PlanarGround : public AbstractGround
	{
	public:

		GLM_CLASS_STAT_ID( glm::MemoryStatIds::GolaemShared)

		/**
		* \name Construction/Destruction
		*/
		//@{
		PlanarGround();
		PlanarGround(const Plane3& plane);
		virtual ~PlanarGround();
		//@}

		/**
		* \name Projection retrieval
		*/
		//@{
		virtual bool computeProjection(const Vector3& position, const Vector3& upVector, Vector3& groundPosition, Vector3& groundNormal, float height, GroundCellId& groundCellId, int genericBoneIndex = -1, const void * userPtr = NULL) const override;
		//@}

		/**
		* \name init/update/finish
		*/
		//@{
		virtual void init();
		virtual void update(Time dt);
		virtual void finish();
		//@}

		/**
		* \name Debug geometry
		*/
		//@{
		void computeGeometry(glm::Array<Triangle3>& triangles, glm::Array<Segment3>& normals, const Matrix4& callerMatrixInverse) const;
		//@}

		/**
		* \name Plane
		*/
		//@{
		const Plane3& getPlane() const;
		Plane3& touchPlane();
		void setPlane(const Plane3& plane);
		//@}
	public:
		/**
		*  \name Debug geometry parameters.
		*/
		//@{
		static Vector2 debugGeometryFrom;
		static Vector2 debugGeometryTo;
		static Vector2 debugGeometryStep;
		//@}
	private:

		GLM_DISALLOW_COPY_AND_ASSIGN( PlanarGround ) ;

		Plane3 _plane;
	};

	//*****************************************************************************
	// PlanarGround inline definitions
	//*****************************************************************************

	//-----------------------------------------------------------------------------
	// getPlane
	//-----------------------------------------------------------------------------
	inline const Plane3& PlanarGround::getPlane() const
	{
		return _plane;
	}

	//-----------------------------------------------------------------------------
	// touchPlane
	//-----------------------------------------------------------------------------
	inline Plane3& PlanarGround::touchPlane()
	{
		return _plane;
	}

	//-----------------------------------------------------------------------------
	// setPlane
	//-----------------------------------------------------------------------------
	inline void PlanarGround::setPlane(const Plane3& plane)
	{
		_plane = plane;
	}
}

