
#include <math.h>

#include "Common/World/Point.h"
#include "Common/Formation.h"

Formation::Formation()
{


	for (int i=0;i<FORMATION_COUNT;i++) {
		m_PreDefFormations[i][0].m_Role = PR_GoalKeeper;
		m_PreDefFormations[i][0].m_AbsPos = Point (-45.0f, 0.0f);
	}

	//Formation 622
	m_PreDefFormations[FORMATION_622][1].m_Role = PR_Defensman;
	m_PreDefFormations[FORMATION_622][2].m_Role = PR_Defensman;
	m_PreDefFormations[FORMATION_622][3].m_Role = PR_Defensman;
	m_PreDefFormations[FORMATION_622][4].m_Role = PR_Defensman;
	m_PreDefFormations[FORMATION_622][5].m_Role = PR_Defensman;
	m_PreDefFormations[FORMATION_622][6].m_Role = PR_Defensman;
	m_PreDefFormations[FORMATION_622][7].m_Role = PR_Midfielder;
	m_PreDefFormations[FORMATION_622][8].m_Role = PR_Midfielder;
	m_PreDefFormations[FORMATION_622][9].m_Role = PR_Forward;
	m_PreDefFormations[FORMATION_622][10].m_Role = PR_Forward;
	
	m_PreDefFormations[FORMATION_622][1].m_AbsPos = Point(-30.0f, -25.0f);
	m_PreDefFormations[FORMATION_622][2].m_AbsPos = Point(-30.0f, -15.0f);
	m_PreDefFormations[FORMATION_622][3].m_AbsPos = Point(-30.0f, -5.0f);
	m_PreDefFormations[FORMATION_622][4].m_AbsPos = Point(-30.0f, 5.0f);
	m_PreDefFormations[FORMATION_622][5].m_AbsPos = Point(-30.0f, 15.0f);
	m_PreDefFormations[FORMATION_622][6].m_AbsPos = Point(-30.0f, 25.0f);
	m_PreDefFormations[FORMATION_622][7].m_AbsPos = Point(-4.0f, -25.0f);
	m_PreDefFormations[FORMATION_622][8].m_AbsPos = Point(-4.0f, 25.0f);
	m_PreDefFormations[FORMATION_622][9].m_AbsPos = Point(25.0f, -25.0f);
	m_PreDefFormations[FORMATION_622][10].m_AbsPos = Point(25.0f, 25.0f);

	// FORMATION_532
	m_PreDefFormations[FORMATION_532][1].m_Role = PR_Defensman;
	m_PreDefFormations[FORMATION_532][2].m_Role = PR_Defensman;
	m_PreDefFormations[FORMATION_532][3].m_Role = PR_Defensman;
	m_PreDefFormations[FORMATION_532][4].m_Role = PR_Defensman;
	m_PreDefFormations[FORMATION_532][5].m_Role = PR_Defensman;
	m_PreDefFormations[FORMATION_532][6].m_Role = PR_Midfielder;
	m_PreDefFormations[FORMATION_532][7].m_Role = PR_Midfielder;
	m_PreDefFormations[FORMATION_532][8].m_Role = PR_Midfielder;
	m_PreDefFormations[FORMATION_532][9].m_Role = PR_Forward;
	m_PreDefFormations[FORMATION_532][10].m_Role = PR_Forward;
	
	m_PreDefFormations[FORMATION_532][1].m_AbsPos = Point(-30.0f, -25.6f);
	m_PreDefFormations[FORMATION_532][2].m_AbsPos = Point(-30.0f, -12.8f);
	m_PreDefFormations[FORMATION_532][3].m_AbsPos = Point(-30.0f, 0.0f);
	m_PreDefFormations[FORMATION_532][4].m_AbsPos = Point(-30.0f, 12.8f);
	m_PreDefFormations[FORMATION_532][5].m_AbsPos = Point(-30.0f, 25.6f);
	m_PreDefFormations[FORMATION_532][6].m_AbsPos = Point(-4.0f, -21.0f);
	m_PreDefFormations[FORMATION_532][7].m_AbsPos = Point(-4.0f, 0.0f);
	m_PreDefFormations[FORMATION_532][8].m_AbsPos = Point(-4.0f, 21.0f);
	m_PreDefFormations[FORMATION_532][9].m_AbsPos = Point(25.0f, -16.0f);
	m_PreDefFormations[FORMATION_532][10].m_AbsPos = Point(25.0f, 16.0f);

	// FORMATION_523
	m_PreDefFormations[FORMATION_523][1].m_Role = PR_Defensman;
	m_PreDefFormations[FORMATION_523][2].m_Role = PR_Defensman;
	m_PreDefFormations[FORMATION_523][3].m_Role = PR_Defensman;
	m_PreDefFormations[FORMATION_523][4].m_Role = PR_Defensman;
	m_PreDefFormations[FORMATION_523][5].m_Role = PR_Defensman;
	m_PreDefFormations[FORMATION_523][6].m_Role = PR_Midfielder;
	m_PreDefFormations[FORMATION_523][7].m_Role = PR_Midfielder;
	m_PreDefFormations[FORMATION_523][8].m_Role = PR_Forward;
	m_PreDefFormations[FORMATION_523][9].m_Role = PR_Forward;
	m_PreDefFormations[FORMATION_523][10].m_Role = PR_Forward;
	
	m_PreDefFormations[FORMATION_523][1].m_AbsPos = Point(-30.0f, -25.6f);
	m_PreDefFormations[FORMATION_523][2].m_AbsPos = Point(-30.0f, -12.8f);
	m_PreDefFormations[FORMATION_523][3].m_AbsPos = Point(-30.0f, 0.0f);
	m_PreDefFormations[FORMATION_523][4].m_AbsPos = Point(-30.0f, 12.8f);
	m_PreDefFormations[FORMATION_523][5].m_AbsPos = Point(-30.0f, 25.6f);
	m_PreDefFormations[FORMATION_523][6].m_AbsPos = Point(-4.0f, -16.0f);
	m_PreDefFormations[FORMATION_523][7].m_AbsPos = Point(-4.0f, 16.0f);
	m_PreDefFormations[FORMATION_523][8].m_AbsPos = Point(25.0f, -21.0f);
	m_PreDefFormations[FORMATION_523][9].m_AbsPos = Point(25.0f, 0.0f);
	m_PreDefFormations[FORMATION_523][10].m_AbsPos = Point(25.0f, 21.0f);

	// FORMATION_433
	m_PreDefFormations[FORMATION_433][1].m_Role = PR_Defensman;
	m_PreDefFormations[FORMATION_433][2].m_Role = PR_Defensman;
	m_PreDefFormations[FORMATION_433][3].m_Role = PR_Defensman;
	m_PreDefFormations[FORMATION_433][4].m_Role = PR_Defensman;
	m_PreDefFormations[FORMATION_433][5].m_Role = PR_Defensman;
	m_PreDefFormations[FORMATION_433][6].m_Role = PR_Midfielder;
	m_PreDefFormations[FORMATION_433][7].m_Role = PR_Midfielder;
	m_PreDefFormations[FORMATION_433][8].m_Role = PR_Forward;
	m_PreDefFormations[FORMATION_433][9].m_Role = PR_Forward;
	m_PreDefFormations[FORMATION_433][10].m_Role = PR_Forward;
	
	m_PreDefFormations[FORMATION_433][1].m_AbsPos = Point(-26.0f, -26.0f);
	m_PreDefFormations[FORMATION_433][2].m_AbsPos = Point(-33.0f, -13.0f);
	m_PreDefFormations[FORMATION_433][3].m_AbsPos = Point(-33.0f, 0.0f);
	m_PreDefFormations[FORMATION_433][4].m_AbsPos = Point(-33.0f, 13.0f);
	m_PreDefFormations[FORMATION_433][5].m_AbsPos = Point(-26.0f, 26.0f);
	m_PreDefFormations[FORMATION_433][6].m_AbsPos = Point(-4.0f, -13.0f);
	m_PreDefFormations[FORMATION_433][7].m_AbsPos = Point(-4.0f, 13.0f);
	m_PreDefFormations[FORMATION_433][8].m_AbsPos = Point(22.0f, -19.0f);
	m_PreDefFormations[FORMATION_433][9].m_AbsPos = Point(25.0f, 0.0f);
	m_PreDefFormations[FORMATION_433][10].m_AbsPos = Point(22.0f, 19.0f);

	// FORMATION_334
	m_PreDefFormations[FORMATION_334][1].m_Role = PR_Defensman;
	m_PreDefFormations[FORMATION_334][2].m_Role = PR_Defensman;
	m_PreDefFormations[FORMATION_334][3].m_Role = PR_Defensman;
	m_PreDefFormations[FORMATION_334][4].m_Role = PR_Midfielder;
	m_PreDefFormations[FORMATION_334][5].m_Role = PR_Midfielder;
	m_PreDefFormations[FORMATION_334][6].m_Role = PR_Midfielder;
	m_PreDefFormations[FORMATION_334][7].m_Role = PR_Forward;
	m_PreDefFormations[FORMATION_334][8].m_Role = PR_Forward;
	m_PreDefFormations[FORMATION_334][9].m_Role = PR_Forward;
	m_PreDefFormations[FORMATION_334][10].m_Role = PR_Forward;
	
	m_PreDefFormations[FORMATION_334][1].m_AbsPos = Point(-30.0f, -21.0f);
	m_PreDefFormations[FORMATION_334][2].m_AbsPos = Point(-30.0f, 0.0f);
	m_PreDefFormations[FORMATION_334][3].m_AbsPos = Point(-30.0f, 21.0f);
	m_PreDefFormations[FORMATION_334][4].m_AbsPos = Point(-4.0f, -21.0f);
	m_PreDefFormations[FORMATION_334][5].m_AbsPos = Point(-4.0f, 0.0f);
	m_PreDefFormations[FORMATION_334][6].m_AbsPos = Point(-4.0f, 21.0f);
	m_PreDefFormations[FORMATION_334][7].m_AbsPos = Point(25.0f, -18.0f);
	m_PreDefFormations[FORMATION_334][8].m_AbsPos = Point(25.0f, -8.0f);
	m_PreDefFormations[FORMATION_334][9].m_AbsPos = Point(25.0f, 8.0f);
	m_PreDefFormations[FORMATION_334][10].m_AbsPos = Point(25.0f, 18.0f);

	// FORMATION_226
	m_PreDefFormations[FORMATION_226][1].m_Role = PR_Defensman;
	m_PreDefFormations[FORMATION_226][2].m_Role = PR_Defensman;
	m_PreDefFormations[FORMATION_226][3].m_Role = PR_Midfielder;
	m_PreDefFormations[FORMATION_226][4].m_Role = PR_Midfielder;
	m_PreDefFormations[FORMATION_226][5].m_Role = PR_Forward;
	m_PreDefFormations[FORMATION_226][6].m_Role = PR_Forward;
	m_PreDefFormations[FORMATION_226][7].m_Role = PR_Forward;
	m_PreDefFormations[FORMATION_226][8].m_Role = PR_Forward;
	m_PreDefFormations[FORMATION_226][9].m_Role = PR_Forward;
	m_PreDefFormations[FORMATION_226][10].m_Role = PR_Forward;
	
	m_PreDefFormations[FORMATION_226][1].m_AbsPos = Point(-30.0f, -16.0f);
	m_PreDefFormations[FORMATION_226][2].m_AbsPos = Point(-30.0f, 16.0f);
	m_PreDefFormations[FORMATION_226][3].m_AbsPos = Point(-4.0f, -16.0f);
	m_PreDefFormations[FORMATION_226][4].m_AbsPos = Point(-4.0f, 16.0f);
	m_PreDefFormations[FORMATION_226][5].m_AbsPos = Point(25.0f, -26.3f);
	m_PreDefFormations[FORMATION_226][6].m_AbsPos = Point(25.0f, -16.3f);
	m_PreDefFormations[FORMATION_226][7].m_AbsPos = Point(25.0f, -5.3f);
	m_PreDefFormations[FORMATION_226][8].m_AbsPos = Point(25.0f, 5.3f);
	m_PreDefFormations[FORMATION_226][9].m_AbsPos = Point(25.0f, 16.3f);
	m_PreDefFormations[FORMATION_226][10].m_AbsPos = Point(25.0f, 26.3f);

	// FORMATION_451
	m_PreDefFormations[FORMATION_451][1].m_Role = PR_Defensman;
	m_PreDefFormations[FORMATION_451][2].m_Role = PR_Defensman;
	m_PreDefFormations[FORMATION_451][3].m_Role = PR_Defensman;
	m_PreDefFormations[FORMATION_451][4].m_Role = PR_Defensman;
	m_PreDefFormations[FORMATION_451][5].m_Role = PR_Midfielder;
	m_PreDefFormations[FORMATION_451][6].m_Role = PR_Midfielder;
	m_PreDefFormations[FORMATION_451][7].m_Role = PR_Midfielder;
	m_PreDefFormations[FORMATION_451][8].m_Role = PR_Midfielder;
	m_PreDefFormations[FORMATION_451][9].m_Role = PR_Midfielder;
	m_PreDefFormations[FORMATION_451][10].m_Role = PR_Forward;
	
	m_PreDefFormations[FORMATION_451][1].m_AbsPos = Point(-30.0f, -16.0f);
	m_PreDefFormations[FORMATION_451][2].m_AbsPos = Point(-20.0f, -8.0f);
	m_PreDefFormations[FORMATION_451][3].m_AbsPos = Point(-30.0f, 8.0f);
	m_PreDefFormations[FORMATION_451][4].m_AbsPos = Point(-20.0f, 16.0f);
	m_PreDefFormations[FORMATION_451][5].m_AbsPos = Point(10.0f, -26.3f);
	m_PreDefFormations[FORMATION_451][6].m_AbsPos = Point(20.0f, -13.3f);
	m_PreDefFormations[FORMATION_451][7].m_AbsPos = Point(10.0f, -0.3f);
	m_PreDefFormations[FORMATION_451][8].m_AbsPos = Point(20.0f, 13.3f);
	m_PreDefFormations[FORMATION_451][9].m_AbsPos = Point(10.0f, 26.3f);
	m_PreDefFormations[FORMATION_451][10].m_AbsPos = Point(30.0f, 0.0f);

	// FORMATION_442
	m_PreDefFormations[FORMATION_442][1].m_Role = PR_Defensman;
	m_PreDefFormations[FORMATION_442][2].m_Role = PR_Defensman;
	m_PreDefFormations[FORMATION_442][3].m_Role = PR_Defensman;
	m_PreDefFormations[FORMATION_442][4].m_Role = PR_Defensman;
	m_PreDefFormations[FORMATION_442][5].m_Role = PR_Midfielder;
	m_PreDefFormations[FORMATION_442][6].m_Role = PR_Midfielder;
	m_PreDefFormations[FORMATION_442][7].m_Role = PR_Midfielder;
	m_PreDefFormations[FORMATION_442][8].m_Role = PR_Midfielder;
	m_PreDefFormations[FORMATION_442][9].m_Role = PR_Forward;
	m_PreDefFormations[FORMATION_442][10].m_Role = PR_Forward;
	
	m_PreDefFormations[FORMATION_442][1].m_AbsPos = Point(-30.0f, -16.0f);
	m_PreDefFormations[FORMATION_442][2].m_AbsPos = Point(-20.0f, -8.0f);
	m_PreDefFormations[FORMATION_442][3].m_AbsPos = Point(-30.0f, 8.0f);
	m_PreDefFormations[FORMATION_442][4].m_AbsPos = Point(-20.0f, 16.0f);
	m_PreDefFormations[FORMATION_442][5].m_AbsPos = Point(10.0f, -16.3f);
	m_PreDefFormations[FORMATION_442][6].m_AbsPos = Point(20.0f, -8.3f);
	m_PreDefFormations[FORMATION_442][7].m_AbsPos = Point(10.0f, 8.3f);
	m_PreDefFormations[FORMATION_442][8].m_AbsPos = Point(20.0f, 16.3f);
	m_PreDefFormations[FORMATION_442][9].m_AbsPos = Point(1.0f, -15.0f);
	m_PreDefFormations[FORMATION_442][10].m_AbsPos = Point(30.0f, 6.0f);


}



void Formation::InitializeFormation (int FormationId)
{
	for (int i=0;i<PLAYER_COUNT; i++) {
		m_Formation[i] = m_PreDefFormations[FormationId][i];
	}
}

FormationRole Formation::GetPlayerRole (int nTeamSide, int nPlayerId) {
	return (m_Formation[nPlayerId].m_Role);
}

Point Formation::GetPlayerPosition( int nPlayerId, const Point& cBallPos ) {
	Point abs_Point = m_Formation[nPlayerId-1].m_AbsPos;
	float tmp_x;
	
	switch (GetPlayerRole(0, nPlayerId-1)) {
		case PR_Defensman:
			if (cBallPos.GetX() <= DEF_LINE) {
				//tmp_x = (((cBallPos.GetX() + HALF_FIELD_LENGTH) / HALF_FIELD_LENGTH) * (abs_Point.GetX() - DEF_MIN)) + DEF_MIN;
				tmp_x = (((DEF_LINE - cBallPos.GetX()) / (DEF_LINE + HALF_FIELD_LENGTH)) * (-1 * (abs_Point.GetX() - DEF_MIN))) + abs_Point.GetX();
				
			} else {
				//tmp_x = (((cBallPos.GetX() + HALF_FIELD_LENGTH) / FIELD_LENGTH) * (DEF_MAX - abs_Point.GetX())) + abs_Point.GetX();
				tmp_x = (((cBallPos.GetX() - DEF_LINE) / (HALF_FIELD_LENGTH - DEF_LINE)) * (DEF_MAX - abs_Point.GetX())) + abs_Point.GetX();

			}
			break;
		case PR_Midfielder:
			if (cBallPos.GetX() <= MID_LINE) {
				//tmp_x = (((cBallPos.GetX() + HALF_FIELD_LENGTH) / HALF_FIELD_LENGTH) * (abs_Point.GetX() - MID_MIN)) + MID_MIN;
				tmp_x = (((MID_LINE - cBallPos.GetX()) / (MID_LINE + HALF_FIELD_LENGTH)) * (-1 * (abs_Point.GetX() - MID_MIN))) + abs_Point.GetX();
			} else {
				//tmp_x = (((cBallPos.GetX() + HALF_FIELD_LENGTH) / FIELD_LENGTH) * (MID_MAX - abs_Point.GetX())) + abs_Point.GetX();
				tmp_x = (((cBallPos.GetX() - MID_LINE) / (HALF_FIELD_LENGTH - MID_LINE)) * (MID_MAX - abs_Point.GetX())) + abs_Point.GetX();
			}
			break;
		case PR_Forward:
			if (cBallPos.GetX() <= FOR_LINE) {
				//tmp_x = (((cBallPos.GetX() + HALF_FIELD_LENGTH) / HALF_FIELD_LENGTH) * (abs_Point.GetX() - FOR_MIN)) + FOR_MIN;
				tmp_x = (((FOR_LINE - cBallPos.GetX()) / (FOR_LINE + HALF_FIELD_LENGTH)) * (-1 * (abs_Point.GetX() - FOR_MIN))) + abs_Point.GetX();
			} else {
				//tmp_x = (((cBallPos.GetX() + HALF_FIELD_LENGTH) / FIELD_LENGTH) * (FOR_MAX - abs_Point.GetX())) + abs_Point.GetX();
				tmp_x = (((cBallPos.GetX() - FOR_LINE) / (HALF_FIELD_LENGTH - FOR_LINE)) * (FOR_MAX - abs_Point.GetX())) + abs_Point.GetX();
			}
			break;


	}

	float tmp_y;
	if (cBallPos.GetY() <= abs_Point.GetY()) {
		tmp_y = (((abs_Point.GetY() - cBallPos.GetY()) / (abs_Point.GetY() + HALF_FIELD_WIDTH)) * (Y_DEF_AREA / -2 )) + abs_Point.GetY();
	} else {
		tmp_y = (((cBallPos.GetY() - abs_Point.GetY()) / (HALF_FIELD_WIDTH - abs_Point.GetY())) * (Y_DEF_AREA / 2)) + abs_Point.GetY();
	}
	
	if (tmp_y > HALF_FIELD_WIDTH) tmp_y = HALF_FIELD_WIDTH - 5.0f;
	if (tmp_y < (-1*HALF_FIELD_WIDTH)) tmp_y = (-1*HALF_FIELD_WIDTH) + 5.0f;

	Point tmp_Point = Point(tmp_x, tmp_y);


	return (tmp_Point);
	
}

Point Formation::GetPlayerPosition( int nTeamSide, const nPlayerId ) {
	
	Point tmp_Point = m_Formation[nPlayerId-1].m_AbsPos;
	return (tmp_Point);
}

int Formation::GetFormationId(int def, int mid, int att) {
	if ((def==6) && (mid==2) && (att==2)) return FORMATION_622;
	if ((def==5) && (mid==3) && (att==2)) return FORMATION_532;
	if ((def==5) && (mid==2) && (att==3)) return FORMATION_523;
	if ((def==4) && (mid==3) && (att==3)) return FORMATION_433;
	if ((def==3) && (mid==4) && (att==3)) return FORMATION_343;
	if ((def==3) && (mid==3) && (att==4)) return FORMATION_334;
	if ((def==2) && (mid==2) && (att==6)) return FORMATION_226;
	if ((def==4) && (mid==5) && (att==1)) return FORMATION_451;
	if ((def==4) && (mid==4) && (att==2)) return FORMATION_442;

	return 0;
}

Point Formation::GetPlayerPositionInFormation(int nPlayerId, int FormationId) {
	return m_PreDefFormations[FormationId][nPlayerId-1].m_AbsPos;
}

void Formation::SetPlayerPosition( int nTeamSide, const nPlayerId, Point pozicia ) {
	

	m_Formation[nPlayerId-1].m_AbsPos = pozicia;
	
}

void Formation::SetPlayerRole (int nTeamSide, const nPlayerId, FormationRole role){
	

	m_Formation[nPlayerId-1].m_Role = role;
	
}

int Formation::GetRoleCount(int nTeamSide, FormationRole role) {
	int i = 0;
	for (int j=1; j < PLAYER_COUNT; j++)
		if (m_Formation[j].m_Role == role) i++;	
	return i;
}

