#ifndef SQUARENODE_H
#define SQUARENODE_H

#include "GraphNode.h"
#include "SquareArc.h"
#include "Point2D.h"
//#include "Terrain.h"

#include "MemoryManager/debugNew.h"


namespace ground{

	// forward declaration.
	class SquareArc;
	enum GroundType;

	/**
	 * classe gerant un noeud dans un graph de carré.
	 *
	 * Un noeud d'un graph de carré contient une position, une taille et un type de terrain.
	 * la position definie la position centrale du noeud, et la taille definie le nombre de cases formant
	 * les coté du carré.
	 */
	class SquareNode : public GraphNode
	{
	private:
		/**
		 * la position du carré sur la carte
		 */
		Point2D position;
		/**
		 * la taille des cotés du carré.
		 */
		unsigned int size;

		/**
		 * le type du terrain dans le carré.
		 */
		ground::GroundType type;

		/**
		 * vecteur contenant les voisins du noeud.
		 */
		std::vector<GraphArc*> neighbour;

		/**
		 * methode permettant d'ajouter un arc au noeud
		 *
		 * L'arc est simplement ajouter à la liste des noeud. Cette methode est utiliser lors de la
		 * création d'un arc pour le partager entre ses 2 extremités.
		 * @param arc : l'arc a ajouter au noeud.
		 */
		void addArc(SquareArc* arc);

		/**
		 * couleur utilisée pour debuger la graph
		 */
		float debugColor[3];

	public:
		/**
		 * constructeur par defaut
		 */
		SquareNode(void);
		/**
		 * destructeur par defaut.
		 */
		virtual ~SquareNode(void);

		/**
		 * methode permettant de recuperer l'ensemble des arc liant le noeud a ses voisins
		 * @return std::vector<GraphArc*> : le vecteur contenant les arc du noeud
		 */
		std::vector<GraphArc*>&getNeighbours();

		/**
		 * methode permettant de calculer l'heuristique sur ce noeud.
		 * @param previous : le noeud precedent dans l'analyse
		 * @param begin : le noeud de depart du chemin.
		 * @param end : le noeud de fin du chemin.
		 * @return float : l'heuristique du noeud.
		 */
		float heuristic(GraphNode* previous, GraphNode* begin, GraphNode* end);

		/**
		 * methode permettant d'ajouter un voisin au noeud.
		 *
		 * Si le voisin existe deja dans la liste des voisins du noeud, il n'est pas ajouté car
		 * le graph ne supporte pas les multi-arc.
		 * @param newNeighbour : le voisin a ajouter au noeud.
		 * @return SquareArc : pointeur sur le nouvel arc crée. si le voisin existait deja dans la
		 * liste du noeud, la methode retoune NULL
		 */
		SquareArc * addNeighbour(SquareNode * newNeighbour);

		/**
		 * methode permettant de savoir si le noeud a deja le noeud passé dans sa liste de voisins ou pas.
		 * @param node : le noeud pour lequel on souhaite savoir si il appartient à la list des voisins
		 * du noeud courrant.
		 * @return bool : true si le noeud existe deja dans la list des voisins, false sinon.
		 */
		bool haveNeighbour(SquareNode * node);

		/**
		 * methode permettant de supprimer un voisin de la liste du noeud.
		 *
		 * Cette methode ne fait rien si le noeud n'est pas dans la liste des voisins du noeud courrant.
		 * @param node : le noeud à supprimer de la liste des voisins du noeud.
		 */
		void removeNeighbour(SquareNode * node);

		/**
		 * methode permettant de definire la position du carré sur la carte.
		 * @param pos : la position du carré sur la carte.
		 */
		void setPosition(const Point2D& pos);

		/**
		 * methode permettant de recuperer la position du carré sur la carte
		 * @return Point2D : la position du carré sur la carte.
		 */
		Point2D& getPosition();
		
		/**
		 * methode permettant de definir la taille des coté du carré
		 * @param s : la taille des cotés du carré.
		 */
		void setSize(unsigned int s);

		/**
		 * methode permettant de recuperer la taille des coté du carré.
		 * @retuen int : la taille des coté du carré.
		 */
		unsigned int getSize();

		/**
		 * methode permettant de definir le type de terrain dans le carré
		 * @param type : le type de terrain dans le carré
		 */
		void setGroundType(GroundType type);

		/**
		 * methode permettant de recuperer le type de terrain present dans le carré.
		 * @return GroundType : le type du terrain.
		 */
		GroundType getGroundType();

		/**
		 * methode utilisée pour retirer un arc du noeud.
		 *
		 * Cette methode retire simplement l'arc de la liste du noeud sans le detruire. Cette methode
		 * est utilisée lors de la destruction d'un lien entre 2 noeud pour pouvoir supprimer l'arc
		 * des 2 extremités.
		 * @param arc : l'arc a retirer de la liste du noeud.
		 */
		void removeArc(SquareArc* arc);

		/**
		 * methode uilisée pour recuperer la couleur de debug du noeud du graph
		 * @return float * pointeur sur un tableau de 3 float contenant la couleur.
		 */
		float * getDebugColor();

		/**
		 * methode servant à afficher le noeud pour le debuger
		 * @param caseSize: la taille des coté d'une case de la map.
		 */
		void drawDebug(int caseSize);
	};
};// namespace ground

#include "MemoryManager/debugNewOff.h"

#endif
