#ifndef GRAPHPATHFINDER_H
#define GRAPHPATHFINDER_H

#include <map>
#include <vector>
#include "GraphNode.h"
#include "Graph.h"

#include "MemoryManager/debugNew.h"


namespace ground{
	/**
	 * classe servant a trouver un chemin entre 2 sommet d'un graph.
	 *
	 * Cette classe sert à accelerer la recherche de chemin par rapport à une simple recherche de chemin sur matrice.
	 * Une fois le chemin trouvé dans le graph, on peut tres facilement calculer soit un masque stancil, soit une increment map
	 * qu'on passe au path finder sur matrice pour ameliorer ses performance lors de la recherche de chemin.
	 * 
	 * On peut aussi utiliser le path finder sur graph une fois pour calculer une increment map qui sera utilisée par l'ensemble
	 * d'un groupe d'unitées.
	 */
	class GraphPathFinder
	{
	private:
		/** 
		 * l'ensemble des noeud en cours de traitement
		 */
		std::multimap<float,GraphNode*> opened;

		/**
		 * booleen permettant de savoir si le noeud a été traité ou pas.
		 */
		bool pathFound;

		/**
		 * le nombre de noeud entierement traité par le pathfinder.
		 */
		int nbNodeTerminated;

		/**
		 * le graph sur lequel s'effectue le pathfinding
		 */
		Graph * graph;

		/** 
		 * methode permettant de recuperer le noeud de cout le plus bas
		 * @return GraphNode : le noeud de plus bas cout de l'ensemble opened.
		 */
		GraphNode* getLowestCostNode();

		/**
		 * methode permettant de supprimer un noeud de l'ensemble opened.
		 * @param nodeToRemove : le noeud a supprimer de l'ensemble.
		 */
		void removeNodefromOpenedList(GraphNode* nodeToRemove);

		/**
		 * methode permettant d'ajouter un noeud a l'ensemble opened
		 * @param node : le noeud à ajouter.
		 */
		void addNodeInOpenedList(GraphNode* node);

		/**
		 * methode permettant de nettoyer l'ensemble opened.
		 */
		void clearOpenedList();

		/**
		 * methode permettant de construire le chemin quand le pathfinder en a trouvé un.
		 * @param begin : le noeud de depart du chemin
		 * @param end : le noeud d'arrivée du chemin.
		 */
		void buildPath(GraphNode* begin, GraphNode* end);
	protected:

		/**
		 * le chemin trouvé par le dernier appel a findPath()
		 */
		std::vector<GraphNode*> path;
	public:
		/**
		 * constructeur par defaut
		 */
		GraphPathFinder(void);

		/**
		 * destructeur par defaut
		 */
		~GraphPathFinder(void);

		/**
		 * methode permettant de savoir si le pathFinder a trouvé un chemin ou pas.
		 * @return bool : true si le dernier appel a findPath() a effectivement trouvé un chemin, false sinon.
		 */
		bool haveFoundPath();

		/**
		 * methode permettant de recuperer le chemin trouvé par le derniere appel a findPath().
		 * @return std::vector<GraphNode*> : le chemin contenant un ensemble de noeud dans le graph.
		 */
		std::vector<GraphNode*>getPath();

		/**
		 * methode permettant de definir la graph sur lequel s'effectue le pathfinding.
		 * @param g : le graph.
		 */
		void setGraph(Graph * g);

		/**
		 * methode permettant de chercher un chemin dans le graph entre 2 noeuds.
		 * @param begin : le noeud de depart du chemin
		 * @param end : le noeud d'arrivée du chemin.
		 */
		void findPath(GraphNode* begin,GraphNode* end);

	};

};// namespace ground

#include "MemoryManager/debugNewOff.h"

#endif
