entity self;
.float nextthink;
.float frame;
.void () think;

integer do_single_player;

string [32] quitMessage = {
/*   .........1.........2.... */
	"  Are you gonna quit    ",
	"  this game just like   ",
	"   everything else?     ",
	"                        ",

	" Milord, methinks that  ",
	"   thou art a lowly     ",
	" quitter. Is this true? ",
	"                        ",

	" Do I need to bust your ",
	"  face open for trying  ",
	"        to quit?        ",
	"                        ",

	" Man, I oughta smack you",
	"   for trying to quit!  ",
	"     Press Y to get     ",
	"      smacked out.      ",

	" Press Y to quit like a ",
	"   big loser in life.   ",
	"  Press N to stay proud ",
	"    and successful!     ",

	"   If you press Y to    ",
	"  quit, I will summon   ",
	"  Satan all over your   ",
	"      hard drive!       ",

	"  Um, Asmodeus dislikes ",
	" his children trying to ",
	" quit. Press Y to return",
	"   to your Tinkertoys.  ",

	"  If you quit now, I'll ",
	"  throw a blanket-party ",
	"   for you next time!   ",
	"                        "
};
integer quit_index;

// ********* LOAD / SAVE

#define MAX_SAVEGAMES 12
string [MAX_SAVEGAMES] filenames;
integer [MAX_SAVEGAMES] loadable;
integer load_cursor;
integer save_cursor;

void () scan_saves =
{
	local integer i;
	local string f;	//FIXME need a file type;
	for (i = 0; i < MAX_SAVEGAMES; i++) {
		loadable[i] = 0;
		filenames[i] = "--- UNUSED SLOT ---";
		f = File_Open (sprintf ("s%i.sav", i), "rz");
		if (!f)
			continue;
		File_GetLine (f);
		filenames[i] = String_ReplaceChar ('_', ' ', File_GetLine (f));
		loadable[i] = 1;
		File_Close (f);
	}
};

integer (string text, integer key) load_f =
{
	scan_saves ();
	Menu_SelectMenu ("load");
	return 0;
};

integer (string text, integer key) save_f =
{
	scan_saves ();
	Menu_SelectMenu ("save");
	return 0;
};

void () load_save_f =
{
	if (Cmd_Argv (0) == "menu_load")
		Menu_SelectMenu ("load");
	else
		Menu_SelectMenu ("save");
};

integer () load_draw =
{
	local integer i;

	Draw_CenterPic (160, 4, Draw_CachePic ("gfx/p_load.lmp", 1));
	for (i=0 ; i< MAX_SAVEGAMES; i++)
		Draw_String (16, 32 + 8 * i, filenames[i]);
	Draw_Character (8, 32 + load_cursor * 8, 12 + (integer (time * 4) & 1));
	return 1;
};

integer () save_draw =
{
	local integer i;

	Draw_CenterPic (160, 4, Draw_CachePic ("gfx/p_save.lmp", 1));
	for (i=0 ; i< MAX_SAVEGAMES; i++)
		Draw_String (16, 32 + 8 * i, filenames[i]);
	Draw_Character (8, 32 + save_cursor * 8, 12 + (integer (time * 4) & 1));
	return 1;
};

integer (integer key, integer unicode, integer down) load_keyevent =
{
	switch (key) {
		case QFK_DOWN:
		case QFM_WHEEL_DOWN:
			load_cursor++;
			load_cursor %= MAX_SAVEGAMES;
			return 1;
		case QFK_UP:
		case QFM_WHEEL_UP:
			load_cursor += MAX_SAVEGAMES - 1;
			load_cursor %= MAX_SAVEGAMES;
			return 1;
		case QFK_RETURN:
		case QFM_BUTTON1:
			if (loadable[load_cursor]) {
				Menu_SelectMenu (NIL);
				Cbuf_AddText (sprintf ("load s%i.sav\n", load_cursor));
			}
			return 1;
	}
	return 0;
};

integer (integer key, integer unicode, integer down) save_keyevent =
{
	switch (key) {
		case QFK_DOWN:
		case QFM_WHEEL_DOWN:
			save_cursor++;
			save_cursor %= MAX_SAVEGAMES;
			return 1;
		case QFK_UP:
		case QFM_WHEEL_UP:
			save_cursor += MAX_SAVEGAMES - 1;
			save_cursor %= MAX_SAVEGAMES;
			return 1;
		case QFK_RETURN:
		case QFM_BUTTON1:
			Menu_SelectMenu (NIL);
			Cbuf_AddText (sprintf ("save s%i.sav\n", save_cursor));
			return 1;
	}
	return 0;
};

void () load_menu =
{
	Menu_Begin (0, 0, "load");
	Menu_FadeScreen (1);
	Menu_KeyEvent (load_keyevent);
	Menu_Draw (load_draw);
	Menu_End ();
	Cmd_AddCommand ("menu_load", load_save_f);
};

void () save_menu =
{
	Menu_Begin (0, 0, "save");
	Menu_FadeScreen (1);
	Menu_KeyEvent (save_keyevent);
	Menu_Draw (save_draw);
	Menu_End ();
	Cmd_AddCommand ("menu_save", load_save_f);
};

// ********* QUIT

integer () quit =
{
	Menu_SelectMenu ("quit");
	quit_index = integer (random () * 8);
	quit_index &= 7;
	return 0;
};

integer (string text, integer key) quit_f =
{
	quit ();
	return 0;
};

integer (integer key, integer unicode, integer down) quit_keyevent =
{
	if (key == 'y') {
		Menu_Quit ();
		return 1;
	}
	if (key == 'n') {
		Menu_SelectMenu (NIL);
		return 1;
	}
	return 0;
};

integer () quit_draw =
{
	text_box (56, 76, 24, 4);
	Draw_String (64, 84, quitMessage[quit_index *4 + 0]);
	Draw_String (64, 92, quitMessage[quit_index *4 + 1]);
	Draw_String (64, 100, quitMessage[quit_index *4 + 2]);
	Draw_String (64, 108, quitMessage[quit_index *4 + 3]);
	return 1;
};

void () quit_menu =
{
	Menu_Begin (0, 0, "quit");
	Menu_FadeScreen (1);
	Menu_KeyEvent (quit_keyevent);
	Menu_Draw (quit_draw);
	Menu_End ();
};

integer (string text, integer key) sp_start =
{
	Menu_SelectMenu (NIL);
	Cbuf_AddText ("disconnect\n");
	Cbuf_AddText ("maxplayers 1\n");
	Cbuf_AddText ("coop 0\n");
	Cbuf_AddText ("deathmatch 0\n");
	Cbuf_AddText ("teamplay 0\n");
	Cbuf_AddText ("listen 0\n");
	Cbuf_AddText ("noexit 0\n");
	Cbuf_AddText ("samelevel 0\n");
	Cbuf_AddText ("map start\n");
	return 0;
};

void () single_player_menu =
{
	Menu_Begin (54, 32, "");
	Menu_FadeScreen (1);
	Menu_Pic (16, 4, "gfx/qplaque.lmp");
	Menu_CenterPic (160, 4, "gfx/ttl_sgl.lmp");
	Menu_Pic (72, 32, "gfx/sp_menu.lmp");
	Menu_Cursor (spinner);
	Menu_Item (54, 32, "", sp_start, 0);
	Menu_Item (54, 52, "", load_f, 0);
	Menu_Item (54, 72, "", save_f, 0);
	Menu_End ();
};

// ********* MULTIPLAYER

integer JoiningGame;
integer lanConfig_cursor;
string my_tcpip_address;
string lanConfig_portname;
string lanConfig_joinname;
#define NUM_LANCONFIG_CMDS 3
integer [NUM_LANCONFIG_CMDS] lanConfig_cursor_table = { 72, 92, 124 };
inputline_t lanConfig_port_il;
inputline_t lanConfig_join_il;
inputline_t input_active;

integer () join_draw =
{
	local integer f = (320 - 26 * 8) / 2;
	text_box (f, 134, 24, 4);
	Draw_String (f, 142, " Commonly used to play  ");
	Draw_String (f, 150, " over the Internet, but ");
	Draw_String (f, 158, " also used on a Local   ");
	Draw_String (f, 166, " Area Network.          ");
	return 0;
};

integer () lanconfig_draw =
{
	local integer basex = 54;
	local string startJoin = JoiningGame ? "Join Game" : "New Game";
	local string protocol = "UDP";

	Draw_String (basex, 32, sprintf ("%s - %s", startJoin, protocol));
	basex += 8;
	Draw_String (basex, 52, "Address:");
	Draw_String (basex + 9 * 8, 52, "127.0.0.1");
	Draw_String (basex, lanConfig_cursor_table[0], "Port");
	text_box (basex + 8 * 8, lanConfig_cursor_table[0] - 8, 6, 1);
	InputLine_Draw (lanConfig_port_il, basex + 8 * 8, lanConfig_cursor_table[0], lanConfig_cursor == 0 && input_active);
	Draw_String (basex + 9 * 8, lanConfig_cursor_table[0], lanConfig_portname);

	if (JoiningGame) {
		Draw_String (basex, lanConfig_cursor_table[1], "Search for local games...");
		Draw_String (basex, 108, "Join game at:");
		text_box (basex + 8, lanConfig_cursor_table[2] - 8, 22, 1);
		InputLine_Draw (lanConfig_join_il, basex + 8, lanConfig_cursor_table[2], lanConfig_cursor == 2 && input_active);
		Draw_String (basex + 16, lanConfig_cursor_table[2], lanConfig_joinname);
	} else {
		text_box (basex, lanConfig_cursor_table[1] - 8, 2, 1);
		Draw_String (basex + 8, lanConfig_cursor_table[1], "OK");
	}
	if (!input_active)
		Draw_Character (basex - 8, lanConfig_cursor_table[lanConfig_cursor],
						12 + (integer (time * 4) & 1));

	return 0;
};

integer (integer key, integer unicode, integer down) lanconfig_keyevent =
{
	if (input_active)
		InputLine_Process (input_active, key >= 256 ? key : unicode);
	switch (key) {
		case QFK_DOWN:
		case QFM_WHEEL_DOWN:
			if (!input_active) {
				lanConfig_cursor ++;
				lanConfig_cursor %= NUM_LANCONFIG_CMDS;
			}
			break;
		case QFK_UP:
		case QFM_WHEEL_UP:
			if (!input_active) {
				lanConfig_cursor += NUM_LANCONFIG_CMDS - 1;
				lanConfig_cursor %= NUM_LANCONFIG_CMDS;
			}
			break;
		case QFK_RETURN:
			if (input_active) {
				input_active = NIL;
			} else {
				if (lanConfig_cursor == 0) {
					input_active = lanConfig_port_il;
				} else if (JoiningGame) {
					if (lanConfig_cursor == 2) {
						input_active = lanConfig_join_il;
					}
				}
			}
			break;
	}
	return 1;
};

void () lanconfig_menu =
{
	Menu_Begin (54, 92, "");
	Menu_FadeScreen (1);
	Menu_Pic (16, 4, "gfx/qplaque.lmp");
	Menu_CenterPic (160, 4, "gfx/p_multi.lmp");
	Menu_Draw (lanconfig_draw);
	Menu_KeyEvent (lanconfig_keyevent);
	Menu_End ();
};

void () join_menu =
{
	Menu_Begin (54, 32, "");
	Menu_FadeScreen (1);
	Menu_Pic (16, 4, "gfx/qplaque.lmp");
	Menu_CenterPic (160, 4, "gfx/p_multi.lmp");
	Menu_Pic (72, 32, "gfx/dim_modm.lmp");
	Menu_Pic (72, 51, "gfx/dim_drct.lmp");
	Menu_Pic (72, 70, "gfx/dim_ipx.lmp");
	Menu_Pic (72, 89, "gfx/netmen4.lmp");
	lanconfig_menu ();
	Menu_Draw (join_draw);
	Menu_Cursor (spinner);
	Menu_End ();
};

integer (integer key, integer unicode, integer down) multi_player_keyevent =
{
	if (key == QFK_RETURN) {
		JoiningGame = (Menu_GetIndex () == 0);
	}
	return 0;
};

void () multi_player_menu =
{
	Menu_Begin (54, 52, "");
	Menu_FadeScreen (1);
	Menu_Pic (16, 4, "gfx/qplaque.lmp");
	Menu_CenterPic (160, 4, "gfx/p_multi.lmp");
	Menu_Pic (72, 32, "gfx/mp_menu.lmp");
	Menu_KeyEvent (multi_player_keyevent);
	join_menu ();
	if (do_single_player)
		Menu_Item (54, 52, "", quit_f, 0);
	Menu_Item (54, 72, "", quit_f, 0);
	Menu_Cursor (spinner);
	Menu_End ();
};



void () help_menu =
{
	Menu_Item (54, 92, "", quit_f, 0);
};

void () main_menu =
{
	Menu_Begin (0, 0, "main");
	Menu_FadeScreen (1);
	Menu_Pic (16, 4, "gfx/qplaque.lmp");
	Menu_CenterPic (160, 4, "gfx/ttl_main.lmp");
	Menu_Pic (71,32, "gfx/mainmenu.lmp");
	Menu_Cursor (spinner);
	if (do_single_player)
		single_player_menu ();
	switch (gametype ()) {
	case "netquake":
		multi_player_menu ();
		break;
	case "quakeworld":
		server_list_menu ();
		break;
	default:
		break;
	}
	MENU_options ();
	help_menu ();
	Menu_Item (54, 112, "", quit_f, 0);
	Menu_End ();
};

void () menu_init =
{
	load_menu_pics ();

	lanConfig_port_il = InputLine_Create (4, 8, ' ');
	InputLine_SetWidth (lanConfig_port_il, 10);
	lanConfig_join_il = InputLine_Create (4, 24, ' ');
	InputLine_SetWidth (lanConfig_join_il, 26);
	switch (gametype ()) {
	case "netquake":
		do_single_player = 1;
		break;
	case "quakeworld":
		do_single_player = 0;
		break;
	default:
		break;
	}
	main_menu ();
	quit_menu ();
	load_menu ();
	save_menu ();
	Menu_TopMenu ("main");
	Menu_SetQuit (quit);
};