#include "empire.h"

int load_characters();
bool get_customres(const string &text, int *x, int *y);

void _ingameoptions::reset() {
	show_damage = true;
	funding = 4000;
	time = -999;
}

vector<pair<int, int> >::const_iterator resolution_index(int w, int h)
{
	for (vector<pair<int, int> >::const_iterator it = global.screenmodes.begin(); it != global.screenmodes.end(); it++)
	{
		if ((it->first == w) && (it->second == h))
		{  //we've found the desired resolution
			return it;
		}
	}
	return global.screenmodes.end();
}

int do_gameoptions(bool ingame) //this menu can also be entered while in-game
{
	static bool first = true;
	static int previous_maporder;
	static vector<pair<int, int> >::const_iterator screenmode_it;
	static _button back;
	static _button speed[2];
	static _button fxvol[2];
	static _button musvol[2];
	static _button scroll;
	static _button arrange;
	static _button screenmode;
	static _button applygfx;
	static _button applycustomres;
	static _button testsound;
	static _button resolution;
	static _button showbattle;
	static _button netserver_default;
	static _textline customres;
	static _textline netname;
	static _textline netserver;
	char tempchar[30];

	static string old_customres = "";

	const float xratio = float(global.screen_width) / 800.0;
	const float yratio = float(global.screen_height) / 600.0;
	const pair<int, int> graphicsgroup = pair<int, int>(int(100 * xratio), int(100 * yratio));
	const pair<int, int> soundgroup = pair<int, int>(int(490 * xratio), int(100 * yratio));
	const pair<int, int> gameplaygroup = pair<int, int>(int(350 * xratio), int(300 * yratio));

	if (first)
	{
		previous_maporder = global.maporder;
		back.init(10, global.screen_height - 30, 100, 20, "Back");

		if (global.fullscreen)
			screenmode.init(graphicsgroup.first, graphicsgroup.second + 40, 210, 30, "Fullscreen");
		else
			screenmode.init(graphicsgroup.first, graphicsgroup.second + 40, 210, 30, "Windowed");

		screenmode_it = resolution_index(global.screen_width, global.screen_height);
		if (screenmode_it == global.screenmodes.end())
		{
			empdebug("Huh?  For some reason, the current screen resolution wasn't in the list of available resolutions.");
			empdebug("Adding the current resolution to the list.");

			global.screenmodes.push_back(pair<int, int>(global.screen_width, global.screen_height));
			//don't bother sorting the vector again
			screenmode_it = resolution_index(global.screen_width, global.screen_height);

			if (screenmode_it == global.screenmodes.end())
			{
				empdebug("What!?  It still can't find the current screen mode?  I just added it!");
				screenmode_it = global.screenmodes.begin();
			}
		}

		{
			stringstream s;
			s << "Resolution: " << screenmode_it->first << " x " << screenmode_it->second;
			resolution.init(graphicsgroup.first, graphicsgroup.second + 85, 210, 40, s.str());
		}

		applygfx.init(graphicsgroup.first + 220, graphicsgroup.second + 40, 70, 85, "Apply");

		{
			stringstream s;
			s << screenmode_it->first << "x" << screenmode_it->second;

			customres.init(graphicsgroup.first, graphicsgroup.second + 150, 210, 16, false);
			customres.set_text(s.str());
			customres.disable();

			applycustomres.init(graphicsgroup.first + 220, graphicsgroup.second + 150, 70, 16, "Apply");
		}

		fxvol[0].init (soundgroup.first,       soundgroup.second + 50, 30, 20, "<");
		fxvol[1].init (soundgroup.first + 120, soundgroup.second + 50, 30, 20, ">");
		testsound.init(soundgroup.first + 180, soundgroup.second + 50, 90, 20, "Test");
		musvol[0].init(soundgroup.first,       soundgroup.second + 95, 30, 20, "<");
		musvol[1].init(soundgroup.first + 120, soundgroup.second + 95, 30, 20, ">");

		netname.init(gameplaygroup.first + 120, gameplaygroup.second + 30, 150, 18, false);
		netname.set_text(global.orignetname);

		netserver.init(gameplaygroup.first + 120, gameplaygroup.second + 60, 150, 18, false);
		netserver.set_text(global.netlobby);
		netserver.disable();

		netserver_default.init(gameplaygroup.first + 280, gameplaygroup.second + 60, 120, 20, "Set to Default");

		switch (global.scroll_divider)
		{
			case 1:
				scroll.init(gameplaygroup.first + 120, gameplaygroup.second + 90, 140, 20, "Very Fast");
				break;
			case 2:
				scroll.init(gameplaygroup.first + 120, gameplaygroup.second + 90, 140, 20, "Fast");
				break;
			case 4:
				scroll.init(gameplaygroup.first + 120, gameplaygroup.second + 90, 140, 20, "Normal");
				break;
			case 8:
				scroll.init(gameplaygroup.first + 120, gameplaygroup.second + 90, 140, 20, "Slow");
				break;
			case 16:
				scroll.init(gameplaygroup.first + 120, gameplaygroup.second + 90, 140, 20, "Slooooooooow");
				break;
		}

		switch (global.maporder)
		{
			case 0:
				arrange.init(gameplaygroup.first + 120, gameplaygroup.second + 130, 140, 20, "Name");
				break;
			case 1:
				arrange.init(gameplaygroup.first + 120, gameplaygroup.second + 130, 140, 20, "Number of Players");
				break;
			case 2:
				arrange.init(gameplaygroup.first + 120, gameplaygroup.second + 130, 140, 20, "Map Size");
				break;
		}

		speed[0].init(gameplaygroup.first + 120, gameplaygroup.second + 160, 30, 20, "<");
		speed[1].init(gameplaygroup.first + 200, gameplaygroup.second + 160, 30, 20, ">");

		if (global.battle_animation == 1)
			showbattle.init(gameplaygroup.first + 120, gameplaygroup.second + 190, 100, 20, "ON");
		else
			showbattle.init(gameplaygroup.first + 120, gameplaygroup.second + 190, 100, 20, "OFF");

		first = false;
	}

	glb.draw_fullscreen(7);

	buffer_textout_ex(big, "Graphics", graphicsgroup.first, graphicsgroup.second, WHITE);
	buffer_textout_ex(big, "Sound", soundgroup.first, soundgroup.second, WHITE);
	buffer_textout_ex(big, "Gameplay", gameplaygroup.first, gameplaygroup.second, WHITE);

	buffer_textout_ex(normal, "Custom Resolution: ", graphicsgroup.first, graphicsgroup.second + 139, WHITE);

	buffer_textout_centre_ex(normal, "Sound Effects Volume", soundgroup.first + 75, soundgroup.second + 30, WHITE);
	sprintf(tempchar, "%-1d", global.volume);
	buffer_textout_centre_ex(normal, tempchar, soundgroup.first + 75, soundgroup.second + 55, WHITE);
	buffer_textout_centre_ex(normal, "Music Volume", soundgroup.first + 75, soundgroup.second + 75, WHITE);
	sprintf(tempchar, "%-1d", global.music_volume);
	buffer_textout_centre_ex(normal, tempchar, soundgroup.first + 75, soundgroup.second + 100, WHITE);

	buffer_textout_right_ex(normal, "Network name:", gameplaygroup.first + 100, gameplaygroup.second + 30, WHITE);
	buffer_textout_right_ex(normal, "Network Server:", gameplaygroup.first + 100, gameplaygroup.second + 60, WHITE);
	buffer_textout_right_ex(normal, "Map Scroll Speed:", gameplaygroup.first + 100, gameplaygroup.second + 93, WHITE);
	buffer_textout_right_ex(normal, "Arrange Maps by:",  gameplaygroup.first + 100, gameplaygroup.second + 133, WHITE);
	buffer_textout_right_ex(normal, "Mouse Speed (Higher value means slower mouse)", gameplaygroup.first + 100, gameplaygroup.second + 163, WHITE);
	sprintf(tempchar, "%-1d", global.mspeed);
	buffer_textout_centre_ex(normal, tempchar, gameplaygroup.first + 175, gameplaygroup.second + 163, WHITE);
	buffer_textout_right_ex(normal, "Battle Animation:", gameplaygroup.first + 100, gameplaygroup.second + 193, WHITE);


	back.check();
	fxvol[0].check();
	fxvol[1].check();
	musvol[0].check();
	musvol[1].check();
	testsound.check();
	scroll.check();
	speed[0].check();
	speed[1].check();
	screenmode.check();
	resolution.check();
	applygfx.check();
	customres.check();
	applycustomres.check();
	arrange.check();
	showbattle.check();
	netname.check();
	netserver.check();
	netserver_default.check();

	if (netname.mouseclicked())
	{
		netname.enable();
		netserver.disable();
		customres.disable();
	}
	else if (netserver.mouseclicked())
	{
		netname.disable();
		netserver.enable();
		customres.disable();
	}
	else if (customres.mouseclicked())
	{
		netname.disable();
		netserver.disable();
		customres.enable();
	}

	if (old_customres != customres.current_text())
	{
		int x, y;

		if (get_customres(customres.current_text(), &x, &y))
			customres.set_color(WHITE);
		else
			customres.set_color(RED);

		old_customres = customres.current_text();
	}

	if (arrange.clicked())
	{
		global.maporder++;
		if (global.maporder >= 3)
			global.maporder = 0;

		switch (global.maporder)
		{
			default:
			case 0:
				arrange.rename("Name");
				break;
			case 1:
				arrange.rename("Number of Players");
				break;
			case 2:
				arrange.rename("Map Size");
				break;
		}
	}
	if (arrange.rclicked())
	{
		global.maporder--;
		if (global.maporder < 0)
			global.maporder = 2;

		switch (global.maporder)
		{
			default:
			case 0:
				arrange.rename("Name");
				break;
			case 1:
				arrange.rename("Number of Players");
				break;
			case 2:
				arrange.rename("Map Size");
				break;
		}
	}

	if (resolution.clicked())
	{
		stringstream s;

		screenmode_it++;

		if (screenmode_it == global.screenmodes.end())
			screenmode_it = global.screenmodes.begin();

		s << "Resolution: " << screenmode_it->first << " x " << screenmode_it->second;
		resolution.rename(s.str());
	}
	if (resolution.rclicked())
	{
		stringstream s;

		if (screenmode_it == global.screenmodes.begin())
			screenmode_it = global.screenmodes.end() - 1;
		else
			screenmode_it--;

		s << "Resolution: " << screenmode_it->first << " x " << screenmode_it->second;
		resolution.rename(s.str());
	}

	if ((screenmode.clicked()) || (screenmode.rclicked()))
	{
		if (global.fullscreen)
		{
			screenmode.rename("Windowed");
		}
		else
		{
			screenmode.rename("Fullscreen");
		}
	}

	bool setcustom = applycustomres.clicked();
	bool setnormal = applygfx.clicked();
	int customx, customy;

	if (setcustom)
	{
		if (!get_customres(customres.current_text(), &customx, &customy))
			setcustom = false;
	}

	if (setcustom || setnormal)
	{
		bool prev_fullscreen = global.fullscreen;
		int prev_screenw = global.screen_width;
		int prev_screenh = global.screen_height;

		if (screenmode.get_text() == "Fullscreen")
			global.fullscreen = true;
		else
			global.fullscreen = false;

		if (setcustom)
		{
			global.screen_width = customx;
			global.screen_height = customy;
		}
		else
		{
			global.screen_width = screenmode_it->first;
			global.screen_height = screenmode_it->second;
		}
		XTILES = (global.screen_width / MAP_TILE_SIZE) - 5;  //5 tiles needed for the sidebar
		YTILES = (global.screen_height / MAP_TILE_SIZE);

		unload_graphics();

		if (!ol::Setup::SetupScreen(global.screen_width, global.screen_height, global.fullscreen))
		{
			empdebug("Error: Unable to change the screen resolution");

			global.fullscreen = prev_fullscreen;
			global.screen_width = prev_screenw;
			global.screen_height = prev_screenh;

			ol::Setup::SetupScreen(global.screen_width, global.screen_height, global.fullscreen);
		}


		drawqueue.clear();

		ol::Canvas::Fill(ol::Rgba(BLACK, 255));
		big.SetColor(ol::Rgba(WHITE, 255));
		big.Print("Reloading Graphics...", 20, 20 + big.Height("Reloading Graphics"));
		ol::Canvas::Refresh();

		load_graphics();
		load_characters();

		if (ingame)
			create_sidebars();

		first = true;

		if (ingame)
			return 1; //returning 1 means this menu is still being used
		else
			return MENU_GAME_OPTIONS;
	}

	if (testsound.clicked())
		play_sound(rand()%11);

	if (fxvol[0].mousedown())
	{
		if (global.volume > 0)
			global.volume--;
		set_sfx_volume(global.volume);
	}
	if (fxvol[1].mousedown())
	{
		if (global.volume < 100)
			global.volume++;
		set_sfx_volume(global.volume);
	}

	if (musvol[0].mousedown())
	{
		if (global.music_volume > 0)
		{
			global.music_volume--;
			set_music_volume(global.music_volume);
		}
	}
	if (musvol[1].mousedown())
	{
		if (global.music_volume < 100)
		{
			global.music_volume++;
			set_music_volume(global.music_volume);
		}
	}

	if (netserver_default.clicked())
	{
		netserver.set_text(DEFAULT_SERVER);
	}

	if (scroll.clicked())
	{
		if (global.scroll_divider > 1)
		{
			global.scroll_divider /= 2;
		}
		else
		{
			global.scroll_divider = 16;
		}

		switch (global.scroll_divider)
		{
			case 1:
				scroll.rename("Very Fast");
				break;
			case 2:
				scroll.rename("Fast");
				break;
			case 4:
				scroll.rename("Normal");
				break;
			case 8:
				scroll.rename("Slow");
				break;
			case 16:
				scroll.rename("Slooooooooow");
				break;
		}
	}
	if (scroll.rclicked())
	{
		if (global.scroll_divider < 16)
		{
			global.scroll_divider *= 2;
		}
		else
		{
			global.scroll_divider = 1;
		}

		switch (global.scroll_divider)
		{
			case 1:
				scroll.rename("Very Fast");
				break;
			case 2:
				scroll.rename("Fast");
				break;
			case 4:
				scroll.rename("Normal");
				break;
			case 8:
				scroll.rename("Slow");
				break;
			case 16:
				scroll.rename("Slooooooooow");
				break;
		}
	}

	if (speed[0].clicked())
	{
		if (global.mspeed > 1)
			global.mspeed--;
		set_mouse_speed(global.mspeed, global.mspeed);
	}
	if (speed[1].clicked())
	{
		if (global.mspeed < 9)
			global.mspeed++;
		set_mouse_speed(global.mspeed, global.mspeed);
	}

	if ((showbattle.clicked()) || (showbattle.rclicked()))
	{
		if (global.battle_animation == 0)
		{
			global.battle_animation = 1;
			showbattle.rename("ON");
		}
		else
		{
			global.battle_animation = 0;
			showbattle.rename("OFF");
		}
	}

	if (back.clicked())
	{
		global.orignetname = netname.current_text();
		if (global.orignetname == "")
			global.orignetname = "Default";

		global.netlobby = netserver.current_text();

		first = true;

		if (ingame)
			return 0; //returning 0 means the player is going back to the game
		else
			return MENU_FIRST;
	}

	draw_mouse();

	if (ingame)
		return 1; //returning 1 means this menu is still being used
	else
		return MENU_GAME_OPTIONS;
}

bool get_customres(const string &text, int *x, int *y)
{
	size_t dividerloc = text.find("x");

	if (dividerloc == string::npos)
		return false;

	for (unsigned int i = 0; i < text.length(); i++)
	{
		if (i == dividerloc)
			continue;

		if ((text[i] < '0') || (text[i] > '9'))
			return false;
	}

	*x = atoi(text.substr(0, dividerloc).c_str());
	*y = atoi(text.substr(dividerloc + 1, text.length()).c_str());

	if ((*x < 800) || (*x > 4096))
		return false;
	if ((*y < 600) || (*y > 4096))
		return false;

	return true;
}
