
#include "Case.h"
#include "Unit.h"

#include "MemoryManager/debugNew.h"


using namespace ground;

Case::Case()
{
	this->type = MEADOW;
	this->passable = true;
	this->elevation = 0.0f;
	this->coord[0] = this->coord[1] = 0;
	this->dangerZoneID = -1;
	this->strongZoneID = -1;
	this->naturalAxeZoneID = -1;
	this->forestZoneID = -1;
	this->dangerZoneIntensity = 0.0f;
	this->strongZoneIntensity = 0.0f;
	this->naturalAxeIntensity = 0.0f;
	zone = NULL;
}

Case::~Case()
{
}


void Case::setElevation(float h)
{
	this->elevation = h;
}
void Case::setGroundType(GroundType t)
{
	this->type = t;

	//réglage des propriété de la case
	switch(this->type)
	{
	case FOREST:
		this->passable = true;
		break;

	case OREE:
		this->passable = true;
		break;

	case ROAD:
		this->passable = true;
		break;

	case WATER:
		this->passable = false;
		break;

	case MEADOW:
		this->passable = true;
	default:
		this->type = MEADOW;
		this->passable = true;
		break;
	}
}
void Case::setPassable(bool f)
{
	this->passable = f;
}
void Case::setCoord(unsigned int x, unsigned int y)
{
	this->coord[0] = x;
	this->coord[1] = y;
}
void Case::setDangerZoneIntensity(float d)
{
	this->dangerZoneIntensity = d;
}
void Case::setStrongZoneIntensity(float f)
{
	this->strongZoneIntensity = f;
}
void Case::setNaturalAxeIntensity(float a)
{
	this->naturalAxeIntensity = a;
}
void Case::setDangerZoneID(int d)
{
	this->dangerZoneID = d;
}
void Case::setStrongZoneID(int f)
{
	this->strongZoneID = f;
}
void Case::setNaturalAxeID(int a)
{
	this->naturalAxeZoneID = a;
}
void Case::setForestZoneID(int a)
{
	this->forestZoneID = a;
}


float Case::getElevation()
{
	return this->elevation;
}
GroundType Case::getGroundType()
{
	return this->type;
}
bool Case::isPassable()
{
	Unit * currentUnit = ground::GroundMap::getInstance().getCurrentUnit();
	if (currentUnit != NULL){
		if (currentUnit->isMounted()){
			return type != FOREST && type != OREE && this->passable;
		}else{
			return this->passable;
		}
	}else{
		return this->passable;
	}
}
const unsigned int* Case::getCoord()
{
	return this->coord;
}
float Case::getDangerZoneIntensity()
{
	return this->dangerZoneIntensity;
}
float Case::getStrongZoneIntensity()
{
	return this->strongZoneIntensity;
}
float Case::getNaturalAxeIntensity()
{
	return this->naturalAxeIntensity;
}
int Case::getDangerZoneID()
{
	return this->dangerZoneID;
}
int Case::getStrongZoneID()
{
	return this->strongZoneID;
}
int Case::getNaturalAxeID()
{
	return this->naturalAxeZoneID;
}
int Case::getForestZoneID()
{
	return this->forestZoneID;
}

float Case::getCost(AbstractCase * previous){
	Case * prev = static_cast<Case*>(previous);
	float cost = GroundMap::getInstance().getGroundTypeCost(this->type);

	// prise en compte de la hauteur
	float elevationDelta = this->getElevation() - prev->getElevation();
	// elevationDelta est positif si on monte et negatif si on descend
	if (fabs(elevationDelta) < FRANCHISSABLE_DELTA_LIMIT){
		if (elevationDelta < 0){
			elevationDelta /=2.0f;
		}
		// ici on a -FRANCHISSABLE_DELTA_LIMIT < elevationDelta < FRANCHISSABLE_DELTA_LIMIT
		// donc elevationDelta / FRANCHISSABLE_DELTA_LIMIT appartient à [-1..1]
		// on augment le cout des cases qui montent fortement
		cost /= (1 - (elevationDelta / FRANCHISSABLE_DELTA_LIMIT));
	}

	return cost;
}

bool Case::isPassable(AbstractCase * previous){
	Unit * currentUnit = ground::GroundMap::getInstance().getCurrentUnit();
	if (currentUnit != NULL){
		if (currentUnit->isMounted()){
			return type != FOREST && type != OREE && this->passable;
		}else{
			return this->passable;
		}
	}else{
		return this->passable;
	}
}

void Case::setSquareNode(SquareNode* node){
	zone = node;
}

SquareNode* Case::getSquareNode(){
	return zone;
}

