#include "ActionGoTo.h"
#include "ActionMove.h"
#include "Unit.h"

#include "MemoryManager/debugNew.h"

using namespace std;
using namespace ground;

ActionGoTo::ActionGoTo(Unit*u,unitEnumeration::UnitState state, ground::pathFinding::PathFinderMode mode,const Point2D& destination) : UnitAction(u,state){
	unit = u;
	this->destination = destination;
	this->mode = mode;
	ground::GroundMap::getInstance().setPathFinderMode(mode);
	ground::GroundMap::getInstance().computeUnitPath(this->unit,(Point2D&)destination);
	this->path = ground::GroundMap::getInstance().getLastPath();
}

ActionGoTo::~ActionGoTo(void){
}

void ActionGoTo::execute(){
	/**
	 * on restaure l'etat de l'unité
	 */
	unit->setState(this->unitState);
	unit->allowDust(false);
	// cas de bug :
	// quand l'unité est placé sur un point non passable, et qu'on lui demande de trouver un chemin, puis qu'elle
	// doit poursuivre un ennemie, elle poursuit l'ennemie, le tue puis regarde son chemin et... trouve un chemin vide
	// alors qu'elle pouvait peut etre aller au point demandé au depart...
	GroundMap& groundMap = GroundMap::getInstance();
	if (!path.empty()){
		std::vector<Point2D>::iterator it = path.begin();
		groundMap.setCurrentUnit(unit);
		Point2D& pos = (*it);
		Case * c = groundMap.getCase((int)pos.getX(),(int)pos.getY());
		if (c != NULL){
			if (c->isPassable()){
				if((pos - this->unit->getPosition()).getLength() > 2){
					ground::GroundMap::getInstance().setPathFinderMode(mode);
					ground::GroundMap::getInstance().computeUnitPath(this->unit,(Point2D&)destination);
					this->path = ground::GroundMap::getInstance().getLastPath();
					unit->pushAction(this);
				}else{
					unit->pushAction(this);
					unit->pushAction(new ActionMove(unit,this->unitState,pos));
					unit->update();
					path.erase(it);
				}
			}else{
				ground::GroundMap::getInstance().setPathFinderMode(mode);
				ground::GroundMap::getInstance().computeUnitPath(this->unit,(Point2D&)destination);
				this->path = ground::GroundMap::getInstance().getLastPath();
				// on test si on a effectivement trouvé un chemin (si path est vide, c'est qu'on
				// est deja su le point le plus proche possible)
				if (!path.empty()){
					unit->pushAction(this);
				}else{
					dispose();
					// TODO : supprimer ca, utilisé juste pour placer un breakpoint
					int i = 0;
				}
			}
		}else{
			dispose();
		}
	}else{
		dispose();
	}
}

