#ifndef TERRAIN_CASE
#define TERRAIN_CASE

#include "AbstractCase.h"
#include "SquareNodeOwner.h"
#include "GroundMap.h"

#include "MemoryManager/debugNew.h"


#define CASE_SIDE_SIZE		6.0f

namespace ground{
	/**
	 * Enumeration contenant tout les types possible de terrain
	 *
	 * @see : Renderer::renderGroundWithTexture s'il l'on change le nombre de type de sol.
	 */
	enum GroundType
	{
		/**
		 * la plaine
		 */
		MEADOW = 0,
		/**
		 * la foret
		 */
		FOREST,
		/**
		 * l'orée de la foret
		 */
		OREE,
		/**
		 * la route
		 */
		ROAD,
		/**
		 * l'eau
		 */
		WATER
	};

	/**
	 *	La classe représentant une case de l'air de jeu : le terrain.
	 *
	 * cette classe implemente l'interface AbstractCase pour pouvoir s'interfacer avec le
	 * path finder.
	 *
	 * Une case a une elevation qui permet de determiner son altitude, un type de terrain, elle peut etre passable ou pas,
	 * elle a un niveau de danger, un niveau de place forte et un niveau d'axe naturel
	 */
	class Case : public AbstractCase , public SquareNodeOwner
	{
	private:

		/**
		 * La hauteur de la case
		 */
		float elevation;

		/**
		 * Le type de terrain sur la case
		 */
		GroundType type;

		/**
		 * Indique si le terrain est franchissable(true) ou non(false)
		 */
		bool passable;

		/**
		 * La coordonnée de la case dans l'échiquier du terrain
		 */
		unsigned int coord[2];

		/**
		 * Le numéro de la zone de danger associé a ce point.
		 * @see Cette valeur est calculer par le manager de zone.
		 * -1 : zone neutre
		 */
		int dangerZoneID;

		/**
		 * Le numéro de la zone forte asocié a se point.
		 * @see Cette valeur est calculer par le manager de zone.
		 * -1 : zone neutre
		 */
		int strongZoneID;

		/**
		 * L'intensité de danger sur cette case.
		 * @see Cette valeur est calculer par le manager de zone.
		 */
		float dangerZoneIntensity;

		/**
		 * L'intensité d'avantage sur cette case.
		 * @see Cette valeur est calculer par le manager de zone.
		 */
		float strongZoneIntensity;

		/**
		 * Le numéro de l'axe naturel asocié a se point.
		 * @see Cette valeur est calculer par le manager de zone.
		 */
		int naturalAxeZoneID;

		/**
		 * L'intensité d'axe naturel sur cette case.
		 * @see Cette valeur est calculer par le manager de zone.
		 */
		float naturalAxeIntensity;

		/**
		 * Le numéro de la foret asocié à se point.
		 * @see Cette valeur est calculer par le manager de zone.
		 */
		int forestZoneID;

		/**
		 * la zone dans laquel se trouve la case.
		 */
		SquareNode * zone;
	protected:

	public:

		/**
		 * Le constructeur par défaut
		 */
		Case();

		/**
		 * destructeur
		 */
		~Case();

		/**
		 *	Permet de définir la hauteur.
		 *
		 * @param h : la hauteur
		 */
		void setElevation(float h);

		/**
		 *	Permet de définir le type de terrain
		 *	Assigne, par la même occasion, les propriété de la case (isFranchissable....). Si le type n'est pas valide,
		 * on positionne le terrain "prairie".
		 *
		 * @param t : le type de terrain
		 */
		void setGroundType(GroundType t);

		/**
		 *	Permet de définir si la cases est franchissable
		 *
		 * @param f : true si la case est franchissable, false sinon
		 */
		void setPassable(bool f);

		/**
		 *	Permet de définir la position de cette case dans le tableau
		 *
		 * @param x : la position sur l'axe x
		 * @param y : la position sur l'axe y
		 * @pre : x>=0 && x<Terrain::getInstance()->getWidth() && y>=0 && y<Terrain::getInstance()->getHeight()
		 */
		void setCoord(unsigned int x, unsigned int y);

		/**
		 *	Permet de définir l'intensité de la zone de danger
		 *
		 * @param d : l'intensité
		 */
		void setDangerZoneIntensity(float d);

		/**
		 *	Permet de définir l'intensité de la zone forte
		 *
		 * @param f : l'intensité
		 */
		void setStrongZoneIntensity(float f);

		/**
		 *	Permet de définir l'intensité d'axe naturel
		 *
		 * @param a : l'intensité
		 */
		void setNaturalAxeIntensity(float a);

		/**
		 *	Permet de définir l'identifiant de la zone de danger
		 *
		 * @param d : l'identifiant
		 */
		void setDangerZoneID(int d);

		/**
		 *	Permet de définir l'identifiant de la zone de danger
		 *
		 * @param f : l'identifiant
		 */
		void setStrongZoneID(int f);

		/**
		 *	Permet de définir l'identifiant de l'axe de danger auquel appartient cette cases
		 *
		 * @param a : l'identifiant
		 */
		void setNaturalAxeID(int a);

		/**
		 *	Permet de définir l'identifiant de la foret auquel appartient cette cases
		 *
		 * @param a : l'identifiant
		 */
		void setForestZoneID(int f);

		/**
		 *	Donne accès à la hauteur de cette cases
		 *
		 * @return la hauteur
		 */
		float getElevation();

		/**
		 *	Donne accès au type de terrain
		 *
		 * @return le type
		 */
		GroundType getGroundType();

		/**
		 *	Indique si la case est franchissable
		 *
		 * @return true si la case est franchissable, false sinon
		 */
		bool isPassable();

		/**
		 *	Donne accès au coordonnée de la case dans le tableau
		 *
		 * @return un pointeur sur un tableau de tpye float[2]
		 */
		const unsigned int* getCoord();

		/**
		 *	Donne accès à l'intensité de la zone de danger
		 *
		 * @return l'intensité
		 */
		float getDangerZoneIntensity();

		/**
		 *	Donne accès à l'intensité de la zone forte
		 *
		 * @return l'intensité
		 */
		float getStrongZoneIntensity();

		/**
		 *	Donne accès à l'intensité de l'axe naturel
		 *
		 * @return l'intensité
		 */
		float getNaturalAxeIntensity();

		/**
		 *	Donne accès à l'identifiant de la zone de danger
		 *
		 * @return l'identifiant
		 */
		int getDangerZoneID();

		/**
		 *	Donne accès à l'identifiant de la zone forte
		 *
		 * @return l'identifiant
		 */
		int getStrongZoneID();

		/**
		 *	Donne accès à l'identifiant de l'axe naturel
		 *
		 * @return l'identifiant
		 */
		int getNaturalAxeID();

		/**
		 *	Donne accès à l'identifiant de la foret
		 *
		 * @return l'identifiant
		 */
		int getForestZoneID();

		/**
		 * methode permettant de recuperer le cout de la case pour le pathfinder
		 *
		 * @param previous : la case precedente dans l'analyse du pathfinder. c'est en fait
		 * une instance de Case
		 * @return float : le cout de la case
		 */
		float getCost(AbstractCase * previous);

		/**
		 * Methode permettant de savoir si la case es passable ou pas.
		 *
		 * @param previous : la case precedente dans l'analyse du path finder (celle dont vient l'unitée)
		 * c'est en fait une intance de Case
		 * @return bool : true si la cae est passable, false sinon.
		 */
		bool isPassable(AbstractCase * previous);
		/**
		 * methode permettant de definir le SquareNode possedé
		 * @param area : le SquareNode possedé.
		 */
		void setSquareNode(SquareNode* node);
		/**
		 * methode permettant de recuperer le SquareNode possédé.
		 * @return SquareNode : le SquareNode possédé.
		 */
		SquareNode* getSquareNode();
	};
};//namespace ground

#include "MemoryManager/debugNewOff.h"


#endif
