#include "empire.h"

void text_box(int x, int y, int w, int h, char *ret, int leng, int spaces, string title);
int unit_here_thorough(int plyr, int tx, int ty, int ignore_n);
int attackable_unit_here(_unit *attacker, int tx, int ty);
int attackable_unit_here(_unit *attacker, int tx, int ty, bool ignore_teams);
int any_unit_here(int tx, int ty);
int unit_price(int type, int army);

string unit_name(int type);
int unit_type(string name);

int random_buildpos(bool *buildarray);

extern int SIDEBAR_WIDTH, BOTTOMBAR_HEIGHT;

int do_unitmenu(int type, int tx, int ty, int pturn)
{
	const int buildingx = ((tx - worldmap.camera.get_scroll_x()) * MAP_TILE_SIZE - worldmap.camera.get_offset_x());
	const int leftborderx = (buildingx > 5) ? buildingx : 5;
	
	const int buildingy = ((ty - worldmap.camera.get_scroll_y()) * MAP_TILE_SIZE - worldmap.camera.get_offset_y());
	const int topbordery = (buildingy > 5) ? buildingy : 5;
	
	const int x = (leftborderx + 385 < global.screen_width - SIDEBAR_WIDTH) ? leftborderx : global.screen_width - SIDEBAR_WIDTH - 385;
	const int y = (topbordery + 355 < global.screen_height - BOTTOMBAR_HEIGHT) ? topbordery : global.screen_height - BOTTOMBAR_HEIGHT - 355;
	
	
	static bool first = true;
	static bool ok[MAX_UNITS];  //each ok[] corresponds to a unit type
	static _button items[15];  //maximum number of buttons possible at once is 15
	static _button pos[9];
	static int lastitem, unittype, buildpos;
	static bool limit, buildable[9];
	bool drewbuildpos;
	char tempchar[30];
	int i, j, bx, by;
	DyBytes data;
	_player *p = &player[game->pturn];

	if (first)
	{
		limit = false;

		i = 0;
		while (i < 9)
		{
			bx = tx + (i % 3) - 1;
			by = ty + (i / 3) - 1;
			buildable[i] = true;
			if ((bx < 0) || (bx >= worldmap.get_length())) buildable[i] = false;
			if ((by < 0) || (by >= worldmap.get_height())) buildable[i] = false;
			if (any_unit_here(bx, by) != -1) buildable[i] = false;
			i++;
		}
		buildpos = random_buildpos(&buildable[0]);

		i = 0;
		while (i < NUM_UNITS)
		{
			ok[i] = false;
			switch(type)
			{
			case BASE:
				if (unitstats[i].basetype == LAND) ok[i] = true;
				break;
			case AIRPORT:
				if (unitstats[i].basetype == AIR) ok[i] = true;
				break;
			case PORT:
				if (unitstats[i].basetype == SEA) ok[i] = true;
				break;
			}
			if (!unitstats[i].isarmy[player[pturn].number])
			{  //if the player's army can't build this unit
				ok[i] = false;
			}
			if (unitstats[i].techlevel > game->techlevel)
			{
				ok[i] = false;
			}
			i++;
		}
		if (p->units_in_play() >= 50)  //if the player cannot make more units
		{
			i = 0;
			while (i < NUM_UNITS)
			{
				ok[i] = false;
				i++;
			}
			buffer_textout_ex(normal, "Unit Limit Reached", 50, 290, BLACK);
			limit = true;
		}
		i = 0;
		j = 0;
		while (i < NUM_UNITS)
		{
			if (ok[i])
			{
				items[j].init(x + 30, y + 78 + (20 * j), 120, 15, unit_name(i));
				j++;
			}
			i++;
		}
		items[j].init(x + 8, y + 10, 22, 22, "");  //close button
		lastitem = j;
		position_mouse(x + 20, y + 20);

		j = 0;
		while (j < 3)
		{
			i = 0;
			while (i < 3)
			{
				pos[i + j * 3].init(x + 80 + 19 * i, y + 10 + 19 * j, 18, 18);
				i++;
			}
			j++;
		}

		first = false;
	}
	buffer_draw_sprite(glb.bmp(35), x, y, 0.9);

	if (!limit)
	{
		i = 0;
		while (i < 9)
		{
			if (buildable[i])
			{
				pos[i].check();
				if (pos[i].clicked())
				{
					buildpos = i;
				}
			}
			else
			{
				buffer_rectfill(x + 80 + (i % 3) * 19, y + 10 + (i / 3) * 19, x + 98 + (i % 3) * 19, y + 28 + (i / 3) * 19, makecol(128, 0, 0), 0.75);
			}
			i++;
		}
	}
	drewbuildpos = false;

	j = 0;
	i = 0;
	while ((i < lastitem) && (!limit))
	{
		items[i].check();
		if (items[i].mouseover() == 1)
		{
			j = 1;
			unittype = unit_type(items[i].get_text());
			buffer_textout_centre_ex(med, unit_name(unittype), x + 265, y + 35, BLACK, 0.7);
			
			sprintf(tempchar, "Price: %-1d", unit_price(unittype, p->number));
			if (unit_price(unittype, p->number) <= p->cash)
			{
				buffer_textout_centre_ex(normal, tempchar, x + 265, y + 50, BLACK);
			}
			else
			{
				buffer_textout_centre_ex(normal, tempchar, x + 265, y + 50, RED);
			}
			
			bigunits.draw(unittype, x + 215, y + 95);
			multiline_textout_ex(normal, unitstats[unittype].description, x + 180, y + 213, 170, BLACK);

			bx = tx + (buildpos % 3) - 1;
			by = ty + (buildpos / 3) - 1;

			if ((any_unit_here(bx, by) == -1) && (bx >= 0) && (bx < worldmap.get_length()) && (by >= 0) && (by < worldmap.get_height()) &&
				(moves_needed(unitstats[unittype].movetype, bx, by, game->pturn) < UNREACHABLE))
			{  //if the selected unit can be built on the selected tile
				buffer_rectfill(x + 80 + (buildpos % 3) * 19, y + 10 + (buildpos / 3) * 19, x + 98 + (buildpos % 3) * 19, y + 28 + (buildpos / 3) * 19, GREEN, 0.75);
			}
			else
			{
				buffer_rectfill(x + 80 + (buildpos % 3) * 19, y + 10 + (buildpos / 3) * 19, x + 98 + (buildpos % 3) * 19, y + 28 + (buildpos / 3) * 19, RED, 0.75);
			}
			drewbuildpos = true;
		}
		if (items[i].clicked())
		{
			if (p->cash >= unit_price(unittype, p->number))
			{
				bx = tx + (buildpos % 3) - 1;
				by = ty + (buildpos / 3) - 1;
				if (moves_needed(unitstats[unittype].movetype, bx, by, game->pturn) < UNREACHABLE)
				{
					if ((bx >= 0) && (bx < worldmap.get_length()) && (by >= 0) && (by < worldmap.get_height()) && (any_unit_here(bx, by) == -1))
					{
						if (!global.netgame)
						{
							p->cash -= unit_price(unittype, p->number);
							p->create_unit(unittype, bx, by, game->pturn);

							p->stats.produced++;
							p->stats.spent += unit_price(unittype, p->number);
						}
						else
						{
							if (!net.server)
							{  //if it's not the network host, it just sends a request for a new unit here
								data.clear();
								data.appendByte(NET_CLIENT_NEWUNIT);
								data.appendByte(unittype);
								data.appendByte(bx);
								data.appendByte(by);
								net.engine->sendTCP(net.thread, data);
							}
							else
							{
								p->cash -= unit_price(unittype, p->number);
								p->create_unit(unittype, bx, by, game->pturn);

								p->stats.spent += unit_price(unittype, p->number);
								p->stats.produced++;

								data.clear();
								data.appendByte(NET_NEWUNIT);
								data.appendByte(game->pturn);
								data.appendByte(unittype);
								data.appendByte(bx);
								data.appendByte(by);
								data.appendVariable(p->cash);
								net.engine->broadcastTCP(data);
							}
						}
						
						position_mouse(game->old_mouse_location.x, game->old_mouse_location.y);
						first = true;
						return 1;
					}
				}
			}
		}
		i++;
	}
	if ((!limit) && (!drewbuildpos))
	{
		buffer_rectfill(x + 80 + (buildpos % 3) * 19, y + 10 + (buildpos / 3) * 19, x + 98 + (buildpos % 3) * 19, y + 28 + (buildpos / 3) * 19, WHITE, 0.75);
	}

	if (limit)
	{  //the 50-unit limit has been hit
		buffer_textout_ex(normal, "Unit Limit Reached", x + 160, y + 215, RED);
	}
	items[lastitem].check();
	if (items[lastitem].clicked())  //cancel button
	{
		//set_mouse_range(0, 0, 639, 479);
		position_mouse(game->old_mouse_location.x, game->old_mouse_location.y);
		first = true;
		return -1;
	}
	return 0;
}

string do_generalmenu()
{
	static bool first = true, surrendering = false;
	static _button quit, save, option, cancel, help, surrender[6];
	int i, col;
	char c[40];
	
	const int x = (global.screen_width - SIDEBAR_WIDTH) / 2 - 100;
	const int y = (global.screen_height - BOTTOMBAR_HEIGHT) / 2 - 160;
	
	if (first)
	{
		save.init(x + 50, y + 50, 100, 20, "Save Game");
		option.init(x + 50, y + 90, 100, 20, "Game Options");
		help.init(x + 50, y + 130, 100, 20, "Help");
		surrender[0].init(x + 50, y + 170, 100, 20, "Surrender");
		quit.init(x + 50, y + 210, 100, 20, "Quit to Menu");
		cancel.init(x + 50, y + 270, 100, 20, "Return to Game");
		
		surrendering = false;
		first = false;
	}
	
	if (!surrendering)
	{
		buffer_rectrounded(x, y, x + 200, y + 320, GREY, 0.85, 10.0);
		buffer_textout_centre_ex(big, "Options", x + 100, y + 10, BLACK, 0.9);
		
		if (!global.netgame)
		{
			save.check();
		}
		
		quit.check();
		option.check();
		help.check();
		cancel.check();
		if (player[game->pturn].controller == HUMAN) surrender[0].check();
		else surrender[0].draw_disabled();
		
		if (quit.clicked())
		{
			return "Quit";
		}
		if (option.clicked())
		{
			return "Options";
		}
		if ((player[game->pturn].controller == HUMAN) && (surrender[0].clicked()))
		{
			i = 0;
			while (i < worldmap.get_num_players())
			{
				if ((i != game->pturn) && (player[i].playing == 1))
				{
					if (global.netgame) sprintf(c, "Surrender to %s", player[i].name.c_str());
					else sprintf(c, "Surrender to Player %d", i + 1);
					surrender[i].init(x - 10, y + 50 + (30 * i), 220, 20, c);
				}
				i++;
			}
			surrender[i].init(x - 10, y + 50 + (30 * i), 220, 20, "Surrender");
			if (!global.netgame) surrender[i + 1].init(x - 10, y + 100 + (30 * i), 220, 20, "Give Control to AI");
			cancel.init(x + 30, y + 270, 140, 20, "Don't Surrender");
			surrendering = true;
		}
		if (help.clicked())
		{
			return "Help";
		}
		if ((!global.netgame) && (save.clicked()))
		{
			return "Save";
		}
		if (cancel.clicked() || mouse_rclicked())
		{
			first = true;
			return "Cancel";
		}
	}
	else  //surrendering
	{
		buffer_rectrounded(x - 40, y, x + 240, y + 320, GREY, 0.85, 10.0);
		buffer_textout_centre_ex(big, "Surrender", x + 100, y + 10, BLACK, 0.9);
		
		i = 0;
		while (i < worldmap.get_num_players())
		{
			if ((i != game->pturn) && (player[i].playing == 1))
			{
				col = player[i].tintcolor;
				buffer_rectrounded(surrender[i].x, surrender[i].y, surrender[i].x + surrender[i].w, surrender[i].y + surrender[i].h, col, 1.0, 2.0);
				surrender[i].check();
				
				if (surrender[i].clicked())
				{
					global.surrenderval = i;
					first = true;
					return "Surrender";
				}
			}
			i++;
		}
		buffer_rectrounded(surrender[i].x, surrender[i].y, surrender[i].x + surrender[i].w, surrender[i].y + surrender[i].h, WHITE, 0.3, 2.0);
		surrender[i].check();
		if (surrender[i].clicked())
		{
			global.surrenderval = -1;
			first = true;
			return "Surrender";
		}
		if (!global.netgame)
		{
			surrender[i + 1].check();
			if (surrender[i + 1].clicked())
			{
				player[game->pturn].controller = AI;
				first = true;
				return "Cancel";
			}
		}
		
		cancel.check();
		if (cancel.clicked())
		{
			surrender[0].init(x + 50, y + 170, 100, 20, "Surrender");
			cancel.init(x + 50, y + 270, 100, 20, "Return to Game");
			surrendering = false;
		}
	}
	
	return "-";
}

int do_savemenu()
{
	static bool first = true;
	static _button slot[10];
	int i;
	char path[20];
	char name[25] = "";
	
	const int x = (global.screen_width - SIDEBAR_WIDTH) / 2 - 100;
	const int y = (global.screen_height - BOTTOMBAR_HEIGHT) / 2 - 170;

	if (first)
	{
		position_mouse(x + 100, y + 145);
		//set_mouse_range(239, 84, 401, 391);
		i = 0;
		while (i < 9)
		{
			string gamename = "";
			sprintf(path, "saves/game%-1d.sav", i);
			
			if (exists(path))
			{
				gamename = read_savefile_name(path);
			}
			slot[i].init(x + 30, y + 40 + (i * 25), 140, 20, gamename);
			
			i++;
		}
		slot[9].init(x + 30, y + 290, 140, 20, "Cancel");
		first = false;
	}
	
	buffer_rectrounded(x, y, x + 200, y + 340, GREY, 0.85, 10.0);
	buffer_textout_centre_ex(normal, "Choose a save slot", x + 100, y + 23, BLACK);

	i = 0;
	while (i < 10)
	{
		slot[i].check();
		if (slot[i].clicked())
		{
			if (i == 9)  //Cancel was clicked
			{
				first = true;
				return 0;
			}
			else
			{
				if (slot[i].get_text() != "")
				{
					sprintf(name, "%s", slot[i].get_text().c_str());
				}
				text_box(x + 20, y + 100, 161, 35, name, 20, 0, "Name your saved game");
				if (strcmp(name, "_CANCEL_") == 0)
				{  //if ESC was pressed in text_box, don't save
					first = 1;
					//set_mouse_range(0, 0, 639, 479);
					return 0;
				}
				sprintf(path, "saves/game%-1d.sav", i);
				
				
				if (!save_game_to_file(name, path))
					empdebug("Error saving game!");
				
				first = true;
				counter = 0;  //the save process might take a while, so reset the counter
				return 0;
			}
		}
		i++;
	}
	return 1;  //returns 1 if it isn't finished
}

int random_buildpos(bool *buildarray)
{
	int i;
	vector<int> positions;
	
	i = 0;
	while (i < 9)
	{
		if (buildarray[i])
		{
			if (i != 4)
			{
				positions.push_back(i);
			}
		}
		i++;
	}
	
	if (positions.size() > 0)
	{
		return positions[rand()%positions.size()];
	}
	return 4;
}
