#include "GroupPathFinder.h"
#include "GroupPathFinderManager.h"

#include "MemoryManager/debugNew.h"

using namespace std;
using namespace ground;

GroupPathFinder::GroupPathFinder(void){
	minUnitSpeed = 1.0f;
	GroupPathFinderManager::getInstance().addGroup(this);
}

GroupPathFinder::~GroupPathFinder(void){
	if (GroupPathFinderManager::getInstance().containGroup(this)){
		GroupPathFinderManager::getInstance().removeGroup(this);
	}
}

void GroupPathFinder::addUnit(Unit* unit){
	units[unit] = unit;
	offset[unit] = Point2D();
}

void GroupPathFinder::removeUnit(Unit* unit){
	map<void*,Unit*>::iterator it = units.find(unit);
	if (it != units.end()){
		units.erase(it);
		offset.erase(offset.find(unit));
	}
	// si l'unité avais signalé qu'elle etait arrivé, on l'enleve de la map.
	map<void*,Unit*>::iterator it2 = arrivedUnits.find(unit);
	if(it2 != arrivedUnits.end()){
		arrivedUnits.erase(it2);
	}
}

bool GroupPathFinder::containUnit(Unit* unit){
	return units.find(unit) != units.end();
}

void GroupPathFinder::removeAllUnit(){
	units.clear();
	offset.clear();
	arrivedUnits.clear();
}

std::map<void*,Unit*>& GroupPathFinder::getUnits(){
	return units;
}

Point2D GroupPathFinder::getCenter(){
	Point2D ret;
	for (map<void*,Unit*>::iterator it = units.begin(); it != units.end(); ++it){
		ret += it->second->getPosition();
	}
	ret *= (1.0/units.size());
	return ret;
}

std::map<Unit*,Point2D>& GroupPathFinder::getOffsetMap(){
	Point2D &center = getCenter();
	for (map<Unit*,Point2D>::iterator it = offset.begin(); it != offset.end(); ++it){
		it->second = it->first->getPosition() - center;
		// pas besoin d'arrondire les position, ainsi, le groupe garde sa formation autant que possible
		it->second.setCoord(it->second.getX(),it->second.getY());
	}
	return offset;
}

float GroupPathFinder::getMinUnitSpeed(){
	return minUnitSpeed;
}

void GroupPathFinder::computeMinUnitSpeed(){
	minUnitSpeed = 9999.0f;
	for (std::map<void*,Unit*>::iterator it = units.begin(); it != units.end(); ++it){
		float speed	= it->second->getSpeed();
		if (speed < minUnitSpeed){
			minUnitSpeed = speed;
		}
	}
}

bool GroupPathFinder::moveFinished(){
	return arrivedUnits.size() == units.size();
}

void GroupPathFinder::signalArriving(Unit* unit){
	arrivedUnits[unit] = unit;
}

