#include "empire.h"

extern void draw_net_icon(int x, int y);
void load_inidata(DyBytes *data);
void load_playerdata(DyBytes *data);
void load_menudata(DyBytes *data);
void send_client_playerdata();
void list_gamestats(int x, int y);

bool error_different_numunits;

extern string connectmsg;

int net_joingame()
{
	const float xratio = float(global.screen_width) / 800.0;
	const float yratio = float(global.screen_height) / 600.0;
	const float minratio = (xratio < yratio) ? xratio : yratio;

	const int players_x = 38;
	const int players_y = 36;
	const int players_size = 90;
	const int orig_players_spacing = 116;
	const int players_spacing = int(orig_players_spacing * yratio);

	const int help_x = int(339 * xratio);
	const int help_y = int(29 * yratio);
	const int minimap_x = int(619 * xratio);  //where the minimap background image begins
	const int minimap_y = int(412 * yratio);
	const int minimap_realx = minimap_x + int(150.0 * (xratio - minratio) / 2.0);  //where the minimap is actually drawn
	const int minimap_realy = minimap_y + int(150.0 * (yratio - minratio) / 2.0);  //(to center the minimap)

	static bool first = true, maploaded, playersloaded, playerwait, teamwait, tintwait, pready[4];
	static _button back, plyrcycle, teamcycle, colorcycle, ready;
	static _listbox chatbox;
	static _textline chattext;
	int i, n;
	string str, datastr;
	DyBytes data;

	if (first)
	{
		const int startw = 100;
		const int starth = 25;
		const int startx = global.screen_width - startw - 10;
		const int starty = global.screen_height - starth - 10;

		play_song(MENU_THEME);

		error_different_numunits = false;
		back.init(10, global.screen_height - 35, 100, 20, "Back");
		ready.init(startx, starty, startw, starth, "Ready?", 1, RED);
		chatbox.init(help_x, help_y, int(glb.bmp(52)->Width() * xratio), int(glb.bmp(52)->Height() * yratio - 17));
		chattext.init(help_x, int(help_y + glb.bmp(52)->Height() * yratio - 15), int(glb.bmp(52)->Width() * xratio), 15, true);
		maploaded = false;
		playersloaded = false;
		playerwait = false;
		teamwait = false;
		tintwait = false;
		i = 0;
		while (i < 4)
		{
			player[i].name = "";
			pready[i] = false;
			player[i].team = i + 1;
			player[i].number = 0;
			player[i].tintcolor = player_color(0, i);
			currentcharacter[i] = character[0];
			i++;
		}

		net.address[0] = net.engine->getRemoteAddr(net.thread);
		net.hostnum = 0;

		gameoptions.time = -999;

		plyrcycle.init(-10, -10, 1, 1, "");
		teamcycle.init(-10, -10, 1, 1, "");
		colorcycle.init(-10, -10, 1, 1, "");
		net.client_pnum = -1;
		first = false;

		empdebug("Entered network client function");
	}

	if (get_host_message(data))
	{
		i = data.getByte(0);
		data.removeFront(1);
		empdebug("Client received data:");

		switch(i)
		{
			case NET_ASK_PLAYERDATA:
				empdebug("  NET_ASK_PLAYERDATA");
				send_client_playerdata();
				break;
			case NET_PLAYER_UPDATE:
				empdebug("  NET_PLAYER_UPDATE");
				playersloaded = false;
				break;
			case NET_PLAYERDATA:
				empdebug("  NET_PLAYERDATA");
				load_playerdata(&data);

				{
					const float player_y_pos = players_y + (orig_players_spacing * net.client_pnum);
					const int centeredx = int(players_x * xratio + (players_size * (xratio - minratio) / 2.0));
					const int centeredy = int(player_y_pos * yratio + (players_size * (yratio - minratio) / 2.0));

					plyrcycle.init(centeredx, centeredy, int(players_size * minratio), int(players_size * minratio), "", 6, WHITE);
				}

				teamcycle.init(int(150 * xratio), int(70 * yratio + (players_spacing * net.client_pnum)), 40, 40, "", glb.bmp(13 + player[net.client_pnum].team));
				colorcycle.init(int(275 * xratio), int(28 * yratio + (players_spacing * net.client_pnum)), 40, 40, "", NULL, 2, player[net.client_pnum].tintcolor);
				playersloaded = true;
				playerwait = false;
				teamwait = false;
				tintwait = false;
				break;
			case NET_MENUDATA:
				empdebug("  NET_MENUDATA");
				load_menudata(&data);
				break;
			case NET_CHARACTER:
				empdebug("  NET_CHARACTER");
				i = data.getByte(0);
				n = (signed char)data.getByte(1);
				player[i].number = n;

				if (n == -1)
					currentcharacter[i] = NULL;
				else
					currentcharacter[i] = character[n];

				if (i == net.client_pnum)
				{
					const float player_y_pos = players_y + (orig_players_spacing * net.client_pnum);
					const int centeredx = int(players_x * xratio + (players_size * (xratio - minratio) / 2.0));
					const int centeredy = int(player_y_pos * yratio + (players_size * (yratio - minratio) / 2.0));

					plyrcycle.init(centeredx, centeredy, int(players_size * minratio), int(players_size * minratio), "", 6, WHITE);
					playerwait = false;
				}
				break;
			case NET_PLAYERTEAM:
				empdebug("  NET_PLAYERTEAM");
				i = data.getByte(0);
				n = data.getByte(1);
				player[i].team = n;
				if (i == net.client_pnum)
				{
					teamcycle.picture = glb.bmp(13 + player[i].team);
					teamwait = false;
				}
				break;
			case NET_PLAYERTINT:
				empdebug("  NET_PLAYERTINT");
				i = data.getByte(0);
				data.removeFront(1);
				data.extractVariable(0, player[i].tintcolor);
				if (i == net.client_pnum)
				{
					colorcycle.recolor(player[i].tintcolor);
					tintwait = false;
				}

				if (maploaded)
				{  //if the map is loaded, update it to reflect the new tint color
					minimap.create();
					minimap.a = 1.0;
				}
				break;
			case NET_FUNDSPERBUILDING:
				empdebug("  NET_FUNDSPERBUILDING");
				i = data.getByte(0);
				gameoptions.funding = i * 1000;
				break;
			case NET_SHOWDAMAGE:
				empdebug("  NET_SHOWDAMAGE");
				gameoptions.show_damage = (data.getByte(0) != 0);
				break;
			case NET_STARTINGCASH:
				empdebug("  NET_STARTINGCASH");
				n = data.getByte(0);
				i = 0;
				while (i < 4)
				{
					player[i].cash = n * 1000;
					i++;
				}
				break;
			case NET_TECHLEVEL:
				empdebug("  NET_TECHLEVEL");
				i = data.getByte(0);
				game->techlevel = i;
				break;
			case NET_CASHTURNS:
				empdebug("  NET_CASHTURNS");
				i = data.getByte(0);
				game->cashturns = i;
				break;
			case NET_MAPCHANGE:
				empdebug("  NET_MAPCHANGE");
				maploaded = false;
				break;
			case NET_MAPDATA:
				empdebug("  NET_MAPDATA");
				if (load_mapdata(&data))
				{
					minimap.create();
					minimap.a = 1.0;
					maploaded = true;
					data.clear();
					data.appendByte(NET_MAPLOADED);
					net.engine->sendTCP(net.thread, data);
				}
				else
				{
					do_clientchat(&chatbox, "Error loading map data!");
				}
				break;
			case NET_CLIENTREADY:
				empdebug("  NET_CLIENTREADY");
				i = data.getByte(0);
				if (data.getByte(1) == 0)
				{
					pready[i] = false;
				}
				else
				{
					pready[i] = true;
				}
				break;
			case NET_UNREADYALL:
				empdebug("  NET_UNREADYALL");
				pready[1] = false;
				pready[2] = false;
				pready[3] = false;
				ready.rename("Ready?");
				ready.recolor(RED);
				break;
			case NET_INIDATA:
				empdebug("  NET_INIDATA");
				load_inidata(&data);
				if (error_different_numunits)
				{
					DyBytes outdata;

					connectmsg = "Couldn't join game: You have a different number of units, crashing would be certain!";
					first = true;
					if (net.chatengine->isConnected(net.chatthread))
						net.chatengine->disconnectHost(net.chatthread);
					if (net.engine->isConnected(net.thread))
						net.engine->disconnectHost(net.thread);

					addID(outdata, BACK_IN_LOBBY);
					net.lobbyengine->sendTCP(net.lobbythread, outdata);

					return NET_LOBBY;
				}
				break;
			case NET_GO:
				empdebug("  NET_GO");
				//starting a game, so the lobby connection is no longer needed
				net.lobbyengine->disconnectHost(net.lobbythread);

				create_sidebars();
				//TODO: Need to load AI stuff in networkclient, once AI advances beyond braindead
				player[net.client_pnum].controller = HUMAN;

				game->game_just_started = true;
				game->loaded_from_file = false;

				first = true;
				return NET_PLAY;
				break;
			case NET_DISCONNECT:
				{
					DyBytes outdata;

					first = true;
					if ((net.chatthread >= 0) && (net.chatthread < MAX_CONNECTIONS))
					{
						if (net.chatengine->isConnected(net.chatthread))
							net.chatengine->disconnectHost(net.chatthread);
					}
					if ((net.thread >= 0) && (net.thread < MAX_CONNECTIONS))
					{
						if (net.engine->isConnected(net.thread))
							net.engine->disconnectHost(net.thread);
					}

					connectmsg = "The game's host decided to stop hosting";

					addID(outdata, BACK_IN_LOBBY);
					net.lobbyengine->sendTCP(net.lobbythread, outdata);

					return NET_LOBBY;
					break;
				}
		}
	}

	if ( (net.thread < 0) || (net.thread >= MAX_CONNECTIONS) || (net.chatthread < 0) || (net.chatthread >= MAX_CONNECTIONS) ||
		 !net.engine->isConnected(net.thread) || !net.chatengine->isConnected(net.chatthread) )
	{
		DyBytes outdata;
		stringstream s;

		s << "Connection to host died: net.thread = " << net.thread << ", net.chatthread = " << net.chatthread;
		empdebug(s.str());

		first = true;
		if ((net.chatthread >= 0) && (net.chatthread < MAX_CONNECTIONS))
		{
			if (net.chatengine->isConnected(net.chatthread))
				net.chatengine->disconnectHost(net.chatthread);
		}
		if ((net.thread >= 0) && (net.thread < MAX_CONNECTIONS))
		{
			if (net.engine->isConnected(net.thread))
				net.engine->disconnectHost(net.thread);
		}

		connectmsg = "Lost connection to game's host";

		addID(outdata, BACK_IN_LOBBY);
		net.lobbyengine->sendTCP(net.lobbythread, outdata);

		return NET_LOBBY;
	}

	glb.draw_fullscreen(36);
	back.check();
	buffer_rect(ready.x - 5, ready.y, ready.x + ready.w, ready.y + ready.h + 5, BLACK);
	ready.check();
	chatbox.check(false);
	str = chattext.check();
	do_clientchat(&chatbox, str);

	if ((ready.clicked()) && maploaded && (net.client_pnum != -1))
	{
		if (pready[net.client_pnum])
		{
			pready[net.client_pnum] = false;
			ready.rename("Ready?");
			data.clear();
			data.appendByte(NET_CLIENTREADY);
			data.appendByte(0);
			net.engine->sendTCP(net.thread, data);
		}
		else
		{
			pready[net.client_pnum] = true;
			ready.rename("Ready!");
			ready.recolor(BLACK);
			data.clear();
			data.appendByte(NET_CLIENTREADY);
			data.appendByte(1);
			net.engine->sendTCP(net.thread, data);
		}
	}

	list_gamestats(int(345 * xratio), int(390 * yratio));

	if (maploaded)
	{
		buffer_textout_ex(normal, worldmap.get_name(), minimap_x, minimap_y - 17, BLACK);

		if ((xratio > 1.0) || (yratio > 1.0))
		{
			buffer_rectfill(minimap_x, minimap_y, minimap_x + int(150 * xratio), minimap_y + int(150 * yratio), BLACK);
			minimap.draw_scaled(minimap_realx, minimap_realy, minratio);
		}
		else
			minimap.draw(false, minimap_x, minimap_y, false);
	}
	else
	{
		buffer_textout_ex(normal, "Loading map...", int(620 * xratio), int(384 * yratio), BLACK);
	}

	if (playersloaded)
	{
		i = 0;
		while (i < 4)
		{
			if ((player[i].name != "") || (i == net.client_pnum))
			{
				const float player_y_pos = players_y + (orig_players_spacing * i);
				const int teamlabel_x = int(157 * xratio);
				const int teamlabel_y = int((56 + orig_players_spacing * i) * yratio);
				const int namex = int(145 * xratio);
				const int namey = int(34 * yratio + (players_spacing * i));

				//create a black-with-white-outline "Team" label
				buffer_textout_ex(med, "Team", teamlabel_x - 1, teamlabel_y - 1, WHITE);
				buffer_textout_ex(med, "Team", teamlabel_x + 1, teamlabel_y - 1, WHITE);
				buffer_textout_ex(med, "Team", teamlabel_x - 1, teamlabel_y + 1, WHITE);
				buffer_textout_ex(med, "Team", teamlabel_x + 1, teamlabel_y + 1, WHITE);
				buffer_textout_ex(med, "Team", teamlabel_x, teamlabel_y, BLACK);

				// draw over the "X?" in the background image, draw the player's army, and check the transparent button that's over it
				ol::Bitmap *player_image = glb.bmp(51);  //set the player army image to the "random dice"

				buffer_rectfill(int(players_x * xratio), int(player_y_pos * yratio), int((players_x + players_size) * xratio), int((player_y_pos + players_size) * yratio), WHITE);

				if (currentcharacter[i] != NULL)
					player_image = currentcharacter[i]->picture;

				buffer_stretch_sprite(player_image, plyrcycle.x, int(player_y_pos * yratio + (players_size * (yratio - minratio) / 2.0)), plyrcycle.w, plyrcycle.h);


				if (i != net.client_pnum)
				{
					const int teamx = int(150 * xratio);
					const int teamy = int((70 + (orig_players_spacing * i)) * yratio);
					const int tintx = int(275 * xratio);
					const int tinty = int((32 + (orig_players_spacing * i)) * yratio);

					buffer_draw_sprite(glb.bmp(13 + player[i].team), teamx, teamy);
					buffer_textout_ex(normal, player[i].name, namex, namey, BLACK);

					if (currentcharacter[i] != NULL)
						buffer_rectfill(tintx, tinty, tintx + 40, tinty + 40, player[i].tintcolor);
				}
				else buffer_textout_ex(normal, global.netname, namex, namey, BLACK);

				if (player[i].controller == NETAI)
					glb.draw(55, int(200 * xratio), int((70 + (orig_players_spacing * i)) * yratio));  //draw the little AI image

				if (pready[i])
					buffer_draw_sprite(glb.bmp(28), int(275 * xratio), int((188 + (orig_players_spacing * (i - 1))) * yratio));
			}
			i++;
		}

		if (!playerwait)
		{
			plyrcycle.check();
			buffer_rect(int(37 * xratio), int((36 + (orig_players_spacing * net.client_pnum)) * yratio), int(128 * xratio), int((126 + (orig_players_spacing * net.client_pnum)) * yratio), BLACK);

			if (plyrcycle.clicked())
			{
				data.clear();
				data.appendByte(NET_CHARACTER);
				data.appendByte(net.client_pnum);
				net.engine->sendTCP(net.thread, data);

				playerwait = true;
			}
			else if (plyrcycle.rclicked())
			{
				data.clear();
				data.appendByte(NET_CHARACTER_R);
				data.appendByte(net.client_pnum);
				net.engine->sendTCP(net.thread, data);

				playerwait = true;
			}
		}
		else
		{
			plyrcycle.draw();
			buffer_rectrounded(plyrcycle.x, plyrcycle.y, plyrcycle.x + plyrcycle.w, plyrcycle.y + plyrcycle.h, BLACK, 0.7, 3.0);
		}

		if (!teamwait)
		{
			teamcycle.check();
			if (teamcycle.clicked())
			{
				data.clear();
				data.appendByte(NET_PLAYERTEAM);
				data.appendByte(net.client_pnum);
				data.appendByte(player[net.client_pnum].team);
				net.engine->sendTCP(net.thread, data);

				teamwait = true;
			}
			else if (teamcycle.rclicked())
			{
				data.clear();
				data.appendByte(NET_PLAYERTEAM_R);
				data.appendByte(net.client_pnum);
				data.appendByte(player[net.client_pnum].team);
				net.engine->sendTCP(net.thread, data);

				teamwait = true;
			}
		}
		else
		{
			teamcycle.draw();
			buffer_rectrounded(teamcycle.x, teamcycle.y, teamcycle.x + teamcycle.w, teamcycle.y + teamcycle.h, BLACK, 0.7, 3.0);
		}

		if (!tintwait && (currentcharacter[net.client_pnum] != NULL))
		{
			colorcycle.check();
			if (colorcycle.clicked())
			{
				data.clear();
				data.appendByte(NET_CLIENT_TINTCYCLE);
				net.engine->sendTCP(net.thread, data);

				tintwait = true;
			}
			else if (colorcycle.rclicked())
			{
				data.clear();
				data.appendByte(NET_CLIENT_TINTCYCLE_R);
				net.engine->sendTCP(net.thread, data);

				tintwait = true;
			}
		}
		else if (currentcharacter[net.client_pnum] != NULL)
		{
			colorcycle.draw();
			buffer_rectrounded(colorcycle.x, colorcycle.y, colorcycle.x + colorcycle.w, colorcycle.y + colorcycle.h, BLACK, 0.7, 3.0);
		}
	}
	else  //if it hasn't loaded the initial player data yet
	{
		buffer_rectrounded(int(29 * xratio), int(27 * yratio), int(270 * xratio), int(481 * yratio), BLACK, 0.7, 5.0);
		buffer_textout_ex(big, "Loading...", int(101 * xratio), int(240 * yratio), WHITE);
	}

	if (back.clicked())
	{
		DyBytes outdata;

		net.engine->disconnectHost(net.thread);
		net.chatengine->disconnectHost(net.chatthread);
		first = true;

		return NET_FIRST;  //reinitiate lobby connection (if we returned from a game, it will have been dropped)
	}

	draw_mouse();

	return NET_CLIENT;
}

bool do_clientchat(_listbox *chatbox, string str)
{  //returns true if it got a new item to display
	bool result = false;
	DyBytes chatdata;

	if ((str != "/NOTHING YET/") && (str != ""))
	{
		string chatstr = global.netname;
		chatstr += ": ";
		chatstr += str;
		chatdata.insertString(chatstr);

		net.chatengine->sendTCP(net.chatthread, chatdata);
	}

	if (net.chatengine->getMessage(net.chatthread, chatdata))
	{
		chatbox->additem(chatdata.getAsString().c_str(), true);
		chatbox->scroll_to_end();
		result = true;
	}
	return result;
}

void load_inidata(DyBytes *data)
{
	char *str;
	int i, j, k, n;

	data->decompress();

	i = 0;
	while (i < 3)
	{
		data->extractVariable<int32_t>(0, armystats[i].pricefraction);
		data->removeFront(sizeof(int32_t));

		data->extractVariable<int32_t>(0, armystats[i].movemod);
		data->removeFront(sizeof(int32_t));

		data->extractVariable<int32_t>(0, armystats[i].rangemaxmod);
		data->removeFront(sizeof(int32_t));

		j = 0;
		while (j < 3)
		{
			data->extractVariable<int32_t>(0, armystats[i].attackfraction[j]);
			data->removeFront(sizeof(int32_t));

			data->extractVariable<int32_t>(0, armystats[i].resistfraction[j]);
			data->removeFront(sizeof(int32_t));
			j++;
		}
		i++;
	}

	n = data->getByte(0);
	data->removeFront(1);
	if (n != NUM_UNITS)
	{
		error_different_numunits = true;
		return;
	}

	i = 0;
	while (i < n)
	{
		data->extractVariable<int32_t>(0, j);
		data->removeFront(sizeof(int32_t));
		str = (char *)malloc(sizeof(char) * (j + 1));
		k = 0;
		while (k < j)
		{
			str[k] = data->getByte(0);
			data->removeFront(1);
			k++;
		}
		str[k] = '\0';
		unitstats[i].name = str;
		free(str);

		data->extractVariable<int32_t>(0, j);
		data->removeFront(sizeof(int32_t));
		str = (char *)malloc(sizeof(char) * (j + 1));
		k = 0;
		while (k < j)
		{
			str[k] = data->getByte(0);
			data->removeFront(1);
			k++;
		}
		str[k] = '\0';
		unitstats[i].description = str;
		free(str);

		data->extractVariable<int16_t>(0, unitstats[i]._move);
		data->removeFront(sizeof(int16_t));

		data->extractVariable<int16_t>(0, unitstats[i].movetype);
		data->removeFront(sizeof(int16_t));

		data->extractVariable<int16_t>(0, unitstats[i].attacktype);
		data->removeFront(sizeof(int16_t));

		data->extractVariable<int16_t>(0, unitstats[i].basetype);
		data->removeFront(sizeof(int16_t));

		data->extractVariable<int16_t>(0, unitstats[i]._rangemin);
		data->removeFront(sizeof(int16_t));

		data->extractVariable<int16_t>(0, unitstats[i]._rangemax);
		data->removeFront(sizeof(int16_t));

		data->extractVariable<int32_t>(0, unitstats[i]._price);
		data->removeFront(sizeof(int32_t));

		data->extractVariable<int16_t>(0, unitstats[i].loadcapacity);
		data->removeFront(sizeof(int16_t));

		data->extractVariable<int16_t>(0, unitstats[i].loadtype);
		data->removeFront(sizeof(int16_t));

		data->extractVariable<int16_t>(0, unitstats[i].canhit);
		data->removeFront(sizeof(int16_t));

		data->extractVariable<int16_t>(0, unitstats[i].attackparticle);
		data->removeFront(sizeof(int16_t));

		data->extractVariable<int16_t>(0, unitstats[i].attacksound);
		data->removeFront(sizeof(int16_t));

		data->extractVariable<int16_t>(0, unitstats[i].movesound);
		data->removeFront(sizeof(int16_t));

		data->extractVariable<int16_t>(0, unitstats[i].moveparticle);
		data->removeFront(sizeof(int16_t));

		data->extractVariable<uint8_t>(0, (uint8_t&)unitstats[i].cancapture);
		data->removeFront(sizeof(uint8_t));

		data->extractVariable<uint8_t>(0, (uint8_t&)unitstats[i].isarmy[0]);
		data->removeFront(sizeof(uint8_t));

		data->extractVariable<uint8_t>(0, (uint8_t&)unitstats[i].isarmy[1]);
		data->removeFront(sizeof(uint8_t));

		data->extractVariable<uint8_t>(0, (uint8_t&)unitstats[i].isarmy[2]);
		data->removeFront(sizeof(uint8_t));

		data->extractVariable<int16_t>(0, unitstats[i].techlevel);
		data->removeFront(sizeof(int16_t));

		data->extractVariable<uint8_t>(0, (uint8_t&)unitstats[i].attacksburn);
		data->removeFront(sizeof(uint8_t));

		data->extractVariable<int16_t>(0, unitstats[i].blastradius);
		data->removeFront(sizeof(int16_t));

		data->extractVariable<int16_t>(0, unitstats[i].attackdelay);
		data->removeFront(sizeof(int16_t));

		j = 0;
		while (j < 3)
		{
			data->extractVariable<int16_t>(0, unitstats[i]._attack[j]);
			data->removeFront(sizeof(int16_t));

			data->extractVariable<int16_t>(0, unitstats[i]._resist[j]);
			data->removeFront(sizeof(int16_t));
			j++;
		}
		i++;
	}
}

void load_playerdata(DyBytes *data)
{
	int i, k, d;
	char str[50];

	data->decompress();

	net.client_pnum = data->getByte(0);
	data->removeFront(1);

	i = 0;
	while (i < 4)
	{
		player[i].name = "";
		player[i].playing = 0;
		player[i].everplaying = 0;
		if (i != 0) net.address[i] = "";

		d = data->getByte(0);
		data->removeFront(1);

		if (d != 0)
		{
			player[i].playing = 1;
			player[i].everplaying = 1;

			k = 0;
			while (k < d)
			{
				str[k] = data->getByte(k);
				k++;
			}
			str[k] = '\0';
			player[i].name = str;
			data->removeFront(d);

			player[i].number = (signed char)data->getByte(0);
			if (player[i].number == -1) currentcharacter[i] = NULL;
			else currentcharacter[i] = character[player[i].number];
			player[i].controller = data->getByte(1);
			player[i].team = data->getByte(2);
			data->removeFront(3);
			data->extractVariable<int32_t>(0, player[i].tintcolor);
			data->removeFront(sizeof(int32_t));

			d = data->getByte(0);
			data->removeFront(1);
			k = 0;
			while (k < d)
			{
				str[k] = data->getByte(k);
				k++;
			}
			str[k] = '\0';
			net.address[i] = str;
			data->removeFront(d);
		}
		i++;
	}

	empdebug("net.address:");
	empdebug(net.address[0]);
	empdebug(net.address[1]);
	empdebug(net.address[2]);
	empdebug(net.address[3]);
}

void send_client_playerdata()
{
	unsigned int i;
	DyBytes data;
	data.clear();

	data.appendByte(global.netname.length());
	i = 0;
	while (i < global.netname.length())
	{
		data.appendByte(global.netname[i]);
		i++;
	}
	data.compress(9);
	data.insertByte(NET_PLAYERDATA);

	net.engine->sendTCP(net.thread, data);

	empdebug("Sent playerdata to host");
}

void load_menudata(DyBytes *data)
{
	int i, c;

	data->decompress();
	game->cashturns = data->getByte(0);
	c = data->getByte(1);
	i = 0;
	while (i < 4)
	{
		player[i].cash = c * 1000;
		i++;
	}
	game->techlevel = data->getByte(2);
	gameoptions.funding = data->getByte(3) * 1000;
	gameoptions.show_damage = data->getByte(4);
}

void list_gamestats(int x, int y)
{
	char c[50];
	const int w = 200;
	const int h = 110;

	buffer_rectfill(x, y, x + w, y + h, WHITE, 0.6);
	buffer_rect(x, y, x + w, y + h, BLACK);

	sprintf(c, "Starting Cash: %d", player[0].cash);
	buffer_textout_ex(normal, c, x + 10, y + 8, BLACK);

	sprintf(c, "Funds per Building: %d", gameoptions.funding);
	buffer_textout_ex(normal, c, x + 10, y + 28, BLACK);

	if (gameoptions.show_damage > 0)
	{
		buffer_textout_ex(normal, "Show Attacking Damage: Yes", x + 10, y + 48, BLACK);
	}
	else
	{
		buffer_textout_ex(normal, "Show Attacking Damage: No", x + 10, y + 48, BLACK);
	}

	sprintf(c, "Tech Level: %d", game->techlevel);
	buffer_textout_ex(normal, c, x + 10, y + 68, BLACK);

	if (game->cashturns == 0)
	{
		buffer_textout_ex(normal, "Derricks Last: Forever", x + 10, y + 88, BLACK);
	}
	else
	{
		sprintf(c, "Derricks Last: %d Turns", game->cashturns);
		buffer_textout_ex(normal, c, x + 10, y + 88, BLACK);
	}
}
