#ifndef SQUAREARC_H
#define SQUAREARC_H

#include "GraphArc.h"
#include "SquareNode.h"

#include "MemoryManager/debugNew.h"


namespace ground{

	// forward declaration
	class SquareNode;

	/**
	 * Classe representant un arc dans un graph de carré.
	 *
	 * Cette classe est composé de 2 noeud representant les extremitée de l'arc. Ils sont appelé
	 * première extremitée et seconde extremitée, mais il n'y a pas de relation d'ordre entre eux
	 * (c.a.d qu'il peuvent etre utilisé dans les deux sens : on pêut inverser les extremitée sans
	 * changer le comportement de la classe.)
	 *
	 * La classe utilise aussi 2 facteur pour ponderer le cout final de l'arc. Ses 2 fecteurs represente 
	 * la ponderation de chacune des extremitée dans le calcule du cout de l'arc.
	 *
	 * Ainsi, le calcule du cout de l'arc est le suivant :
	 * coutFinal = facteurPremier * CoutPremierNoeud + facteurSecond * coutSecondNoeud
	 */
	class SquareArc : public ground::GraphArc
	{
	private:
		/**
		 * la premiere extremitée de l'arc
		 */
		SquareNode * first;
		/**
		 * la seconde extremitée de l'arc
		 */
		SquareNode * second;
		/**
		 * le facteur de la zone de la premiere extremitée.
		 * ca represente le taux d'influence du premier noeud sur le poid final de l'arc.
		 * on a donc PoidFinal = firstFactor * CoutPremiereCase + secondFactor * coutSecondeCase
		 * et firstFactor + secondFactor = 1
		 */
		float firstFactor;
		/**
		 * le facteur de la zone de la seconde extremitée.
		 * ca represente le taux d'influence du premier noeud sur le poid final de l'arc.
		 * on a donc PoidFinal = firstFactor * CoutPremiereCase + secondFactor * coutSecondeCase
		 * et firstFactor + secondFactor = 1
		 */
		float secondFactor;
		
		/**
		 * la distance entre les 2 centre des extremitée de l'arc.
		 */
		float length;
	public:
		/**
		 * constructeur par defaut
		 */
		SquareArc(void);
		/**
		 * constructeur qui crée un arc a partir de ses deux extremitées
		 * @param first : le noeud representant la premiere extremitée de l'arc
		 * @param second : le noeud representant la seconde extremitée de l'arc.
		 */
		SquareArc(SquareNode * first,SquareNode * second);

		/**
		 * destructeur par defaut.
		 */
		virtual ~SquareArc(void);

		/**
		 * methode permettant de recuperer la premiere extremitée de l'arc.
		 * @return GraphNode : le noeud representant la premiere extremitée du graph
		 */
		GraphNode & getFirtNode();

		/**
		 * methode permettant de recuperer la seconde extremitée de l'arc.
		 * @return GraphNode : le noeud representant la seconde extremitée du graph
		 */
		GraphNode & getSecondNode();

		/**
		 * methode permettant de recuperer le cout de l'arc entre les 2 noeuds en connaissant
		 * celui d'ou on vient.
		 * @param origin : noeud du graph dont on vient dans l'analyse du graph. doit imperativement
		 * etre une des extremitée de l'arc.
		 * @return float : le cout de parcourt de l'arc.
		 */
		float getCostFrom(GraphNode& origin);

		/**
		 * methode permettant de definir le noeud representant la premiere extremitée de l'arc.
		 * @param node : le noeud qui va representer la premiere extremitée du noeud.
		 */
		void setFirt(SquareNode * node);

		/**
		 * methode pemettant de definir le noeud qui va representer la seconde extremitée de l'arc.
		 * @param node : le noeud qui representera la seconde extremitée de l'arc.
		 */
		void setSecond(SquareNode * node);

		/**
		 * methode permettant de recuperer le facteur de la premiere extremitée de l'arc.
		 * @return float : le facteur de la premiere extremitée.
		 */
		float getFirstFactor()const;

		/**
		 * methode permettant de recuperer le facteur de la seconde extremitée de l'arc.
		 * @return float : le facteur de la seconde extremitée.
		 */
		float getSecondFactor()const;

		/**
		 * methode utiliser pour calculer les facteurs propres a chaques extremité de l'arc.
		 */
		void computeFactors();

		/**
		 * methode utilisé pour detacher l'arc des 2 noeud a ses extremitée.
		 */
		void detachExtremity();

		/**
		 * methode permettant de recuperer l'autre extremitée de l'arc si on connait une des extremitée.
		 *
		 * si le noeud passé en parametre n'est pas une des extremitée de l'arc, la methode retourne NULL
		 * @param extremity : l'extremitée de l'arc connu. on souhaite recuperer l'autre extremitée de l'arc.
		 * @return GraphNode* : l'autre extremitée de l'arc. NULL si le noeud passé en parametre n'est pas une
		 * extremitée de l'arc.
		 */
		GraphNode* getOtherSide(GraphNode* extremity);

	};

};// namespace ground

#include "MemoryManager/debugNewOff.h"

#endif
