#include "empire.h"

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

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

int random_buildpos(bool *buildarray);

int do_unitmenu(int type, int tx, int ty, int pturn)
{
	const int x = 160, y = 70;
	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.l)) buildable[i] = false;
			if ((by < 0) || (by >= worldmap.h)) 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), 100, 15, unit_name(i));
				j++;
			}
			i++;
		}
		items[j].init(x + 8, y + 10, 22, 22, "");  //close button
		lastitem = j;
		position_mouse(220, 195);

		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 + 225, 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 + 225, y + 55, BLACK);
			}
			else
			{
				buffer_textout_centre_ex(normal, tempchar, x + 225, y + 55, RED);
			}
			
			bigunits.draw(unittype, x + 175, y + 95);
			multiline_textout_ex(normal, unitstats[unittype].description, x + 160, y + 215, 130, BLACK);

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

			if ((any_unit_here(bx, by) == -1) && (bx >= 0) && (bx < worldmap.l) && (by >= 0) && (by < worldmap.h) &&
				(moves_needed(unitstats[unittype].movetype, bx, by, game->pturn) < 99))
			{  //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) < 99)
				{
					if ((bx >= 0) && (bx < worldmap.l) && (by >= 0) && (by < worldmap.h) && (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];
	
	if (first)
	{
		save.init(270, 160, 100, 20, "Save Game");
		option.init(270, 200, 100, 20, "Game Options");
		help.init(270, 240, 100, 20, "Help");
		surrender[0].init(270, 280, 100, 20, "Surrender");
		quit.init(270, 320, 100, 20, "Quit to Menu");
		cancel.init(270, 380, 100, 20, "Return to Game");
		
		surrendering = false;
		first = false;
	}
	
	if (!surrendering)
	{
		buffer_rectrounded(220, 110, 420, 430, GREY, 0.85, 10.0);
		buffer_textout_centre_ex(big, "Options", 320, 120, 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 < numplayers)
			{
				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(210, 160 + (30 * i), 220, 20, c);
				}
				i++;
			}
			surrender[i].init(210, 160 + (30 * i), 220, 20, "Surrender");
			if (!global.netgame) surrender[i + 1].init(210, 210 + (30 * i), 220, 20, "Give Control to AI");
			cancel.init(250, 380, 140, 20, "Don't Surrender");
			surrendering = true;
		}
		if (help.clicked())
		{
			return "Help";
		}
		if ((!global.netgame) && (save.clicked()))
		{
			return "Save";
		}
		if ((cancel.clicked()) || (mouse_rclicked() == 1))
		{
			first = true;
			return "Cancel";
		}
	}
	else  //surrendering
	{
		buffer_rectrounded(180, 110, 460, 430, GREY, 0.85, 10.0);
		buffer_textout_centre_ex(big, "Surrender", 320, 120, BLACK, 0.9);
		
		i = 0;
		while (i < numplayers)
		{
			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(270, 280, 100, 20, "Surrender");
			cancel.init(270, 380, 100, 20, "Return to Game");
			surrendering = false;
		}
	}
	
	return "-";
}

int do_unloadmenu(_unit *u)
{
  static _button b[3];
  static int first = 1;
  static int oldmx, oldmy;
  if (first == 1)
  {
    oldmx = mouse_x;
    oldmy = mouse_y;
    if (u->load[0].loaded == 1)
    {
      b[0].init(502, 2, 135, 28, unit_name(u->load[0].type).c_str());
    }
    else
    {
      b[0].init(502, 2, 135, 28, "-");
    }
    if (u->load[1].loaded == 1)
    {
      b[1].init(502, 32, 135, 28, unit_name(u->load[1].type).c_str());
    }
    else
    {
      b[1].init(502, 32, 135, 28, "-");
    }
    b[2].init(502, 62, 135, 28, "Cancel");
    position_mouse(570, 15);
    //set_mouse_range(500, 0, 640, 92);
    first = 0;
  }
  buffer_menuback(500, 0, 639, 92, DGREY, GREY, LGREY, 0.8);
  
  b[0].check();
  b[1].check();
  b[2].check();
  if ((b[0].clicked()) && (b[0].get_text() != "-"))
  {
    //set_mouse_range(0, 0, 639, 479);
    position_mouse(oldmx, oldmy);
    first = 1;
    return 0;
  }
  if ((b[1].clicked()) && (b[1].get_text() != "-"))
  {
    //set_mouse_range(0, 0, 639, 479);
    position_mouse(oldmx, oldmy);
    first = 1;
    return 1;
  }
  if (b[2].clicked())
  {
    //set_mouse_range(0, 0, 639, 479);
    position_mouse(oldmx, oldmy);
    first = 1;
    return 2;
  }
  return -1;
}

int do_savemenu()
{
	static bool first = true;
	static _button slot[10];
	int i;
	char path[20];
	char text[20];
	char name[20] = "";

	if (first)
	{
		buffer_textout_centre_ex(normal, "Choose a save slot", 320, 93, BLACK);
		position_mouse(320, 245);
		//set_mouse_range(239, 84, 401, 391);
		i = 0;
		while (i < 9)
		{
			sprintf(path, "saves/game%-1d.sav", i);
			if (exists(path) != 0)
			{
				ifstream n(path);
				n >> text;
				slot[i].init(250, 140 + (i * 25), 140, 20, text);
				n.close();
			}
			else
			{
				slot[i].init(250, 140 + (i * 25), 140, 20, "Empty");
			}
			i++;
		}
		slot[9].init(250, 390, 140, 20, "Cancel");
		first = false;
	}
	buffer_rectrounded(220, 100, 420, 440, GREY, 0.85, 10.0);
	buffer_textout_centre_ex(normal, "Choose a save slot", 320, 123, 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() != "Empty")
				{
					sprintf(name, "%s", slot[i].get_text().c_str());
				}
				text_box(240, 200, 161, 35, name, 15, 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);
				ofstream savefile(path);
				if (!(savefile.bad()))
				{
					savefile << name << "\n" << worldmap.l << "\n" << worldmap.h << "\n";

					save_map_and_players(&savefile);

					savefile << "pturn " << game->pturn << "\n" << gameoptions.funding << "\n";
					savefile << gameoptions.show_damage << "\n" << gameoptions.time << "\n";
					savefile << game->time << "\n" << game->techlevel << "\n" << game->cashturns << "\n";
					savefile << worldmap.get_name().c_str();

					savefile.close();
				}
				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;
}
