#include "empire.h"

int move_priority(_unit* u);

void _uselessstats::reset()
{
	raised = 0;
	spent = 0;
	produced = 0;
	killed = 0;
	lost = 0;
}

_player::_player() :
	playing (false),
	everplaying (false),
	number (-1),
	cash (0),
	controller (HUMAN),
	team (0),
	tintcolor (player_color(0, 0)),
	name (""),
	stats (_uselessstats())
{
	for (int i = 0; i < 50; i++)
		unit[i].exists = 0;
}

int _player::create_unit(int type, int x, int y, int player)
{
	for (int i = 0; i < 50; i++)
	{
		if (unit[i].exists == 0)
		{
			unit[i].create(type, x, y, player, i);
			return i;  //return the number of the newly created unit
		}
	}
	
	return -1;
}

void _player::reset()
{
	clear_units();
	stats.reset();
	playing = 0;
	everplaying = 0;
	cash = 0;
	
	//deliberately not resetting team, tintcolor, or controller
}

void _player::clear_units()
{
	for (int i = 0; i < 50; i++)
	{
		if ((unit[i].exists == 1) && worldmap.tile_in_bounds(unit[i].tilex, unit[i].tiley))
		{
			worldmap.get_tile(unit[i].tilex, unit[i].tiley)->set_unit(-1, -1);
		}
		unit[i].exists = 0;
		unit[i].ready = 0;
	}
}

void _player::ready_units()
{
	int i = 0;
	while (i < 50)
	{
		unit[i].ready = 1;
		unit[i].canmove = true;
		i++;
	}
}

void _player::reapply_unitstats()
{
	int i = 0;
	while (i < 50)
	{
		if (unit[i].exists == 1)
		{
			unit[i].create(int(unit[i].type), int(unit[i].tilex), int(unit[i].tiley), int(unit[i].owner), i);
		}
		i++;
	}
}

int _player::units_in_play()
{
	int i = 0;
	int n = 0;
	while (i < 50)
	{
		if (unit[i].exists == 1)
		{
			n++;
		}
		i++;
	}
	return n;
}

bool _player::defeated(int pnum)
{
	if (units_in_play() > 0)
	{
		return false;
	}
	
	for (int j = 0; j < worldmap.get_height(); j++)
	{
		for (int i = 0; i < worldmap.get_length(); i++)
		{
			if (worldmap.get_tile(i, j)->is_unit_producing())
			{  //if the building can make units
				if (worldmap.get_tile(i, j)->owned_by(pnum))
				{  //and is owned by the player
					int z = worldmap.get_tile(i, j)->unit_here();
					if (z == -1)
					{  //and doesn't have a unit on it (the unit must be an enemy at this point)
						return false;
					}
					else if (player[z / 100].unit[z % 100].ready == 1)
					{  //if the unit could move off the tile (like if a move is cancelled)
						return false;
					}
				}
			}
		}
	}

	return true;  //the player has no units and can't make any units, so he's defeated
}

void _player::sort_units()
{
	mergesort_units(0, 49);
}

void _player::mergesort_units(int min, int max)
{
	vector<_unit> temp;
	int left, right, size, i, pivot, a, b;
	size = max - min + 1;
	pivot = (min + max) / 2;
	temp.clear();
	if (min == max)
	{
		return;
	}
	mergesort_units(min, pivot);
	mergesort_units(pivot + 1, max);
	i = 0;
	while (i < size)
	{
		temp.push_back(unit[min + i]);
		i++;
	}
	left = 0;
	right = pivot - min + 1;
	i = 0;
	while (i < size)
	{
		if (right <= max - min)
		{
			if (left <= pivot - min)
			{
				a = move_priority(&temp[left]);
				b = move_priority(&temp[right]);
				if (a > b)
				{
					unit[i + min] = temp[right];
					unit[i + min].number = i + min;
					if (unit[i].exists == 1)
					{
						worldmap.get_tile(unit[i].tilex, unit[i].tiley)->set_unit(unit[i].owner, unit[i].number);
					}
					right++;
				}
				else
				{
					unit[i + min] = temp[left];
					unit[i + min].number = i + min;
					if (unit[i].exists == 1)
					{
						worldmap.get_tile(unit[i].tilex, unit[i].tiley)->set_unit(unit[i].owner, unit[i].number);
					}
					left++;
				}
			}
			else
			{
				unit[i + min] = temp[right];
				unit[i + min].number = i + min;
				if (unit[i].exists == 1)
				{
					worldmap.get_tile(unit[i].tilex, unit[i].tiley)->set_unit(unit[i].owner, unit[i].number);
				}
				right++;
			}
		}
		else
		{
			unit[i + min] = temp[left];
			unit[i + min].number = i + min;
			if (unit[i].exists == 1)
			{
				worldmap.get_tile(unit[i].tilex, unit[i].tiley)->set_unit(unit[i].owner, unit[i].number);
			}
			left++;
		}
		i++;
	}
}


//==============================================================================
//==============================================================================


_character::_character() :
	name (0),
	description (0),
	picture (0)
{}

_character::~_character()
{
	destroy();
}

void _character::destroy()
{
	if (name != NULL)
	{
		free(name);
		name = NULL;
	}
	if (description != NULL)
	{
		free(description);
		description = NULL;
	}
	if (picture)
	{
		picture->Destroy();
		delete picture;
	}
	picture = NULL;
}

int move_priority(_unit* u)
{
	if (unitstats[u->type].attacktype == RANGED)
	{
		return 0;
	}
	else if (unitstats[u->type].attacktype == DIRECT)
	{
		if (unitstats[u->type].cancapture)
		{
			return 2;
		}
		else
		{
			return 1;
		}
	}
	return 3;
}

const char *_character::getname()
{
	return name;
}

const char *_character::getdescription()
{
	return description;
}

void _character::setname(const char *n)
{
	if (name != NULL)
	{
		free(name);
	}
	name = (char *)malloc(sizeof(char) * (strlen(n) + 1));
	strcpy(name, n);
}

void _character::setdescription(const char *d)
{
	if (description != NULL)
	{
		free(description);
	}
	description = (char *)malloc(sizeof(char) * (strlen(d) + 1));
	strcpy(description, d);
}
