/*
Copyright (C) 1997-2001 Id Software, Inc.

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  

See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

*/

#include "ui_local.h"
/*
=============================================================================

START SERVER MENU

=============================================================================
*/
static menuframework_s s_startserver_menu;

static char	**mapnames;
static int	nummaps;
static void	*s_levelshot;

int		timelimit;
int		scorelimit;
int		numbots;

int		m_mapnum;
int		m_gametype;
int		m_skill;
int		m_cheats;
int		m_public;
int		m_instagib;

void M_GametypeFunc( menucommon_t *menuitem ) {
	m_gametype = menuitem->curvalue;
}
void M_SkillLevelFunc( menucommon_t *menuitem ) {
	m_skill = menuitem->curvalue;
}
void M_CheatsFunc( menucommon_t *menuitem ) {
	m_cheats = menuitem->curvalue;
}
void M_InstagibFunc( menucommon_t *menuitem ) {
	m_instagib = menuitem->curvalue;
}
void M_PublicFunc( menucommon_t *menuitem ) {
	m_public = menuitem->curvalue;
}

void MapChangeFunc( menucommon_t *menuitem )
{
	char path[MAX_QPATH];

	m_mapnum = menuitem->curvalue;

	Q_snprintfz( path, sizeof(path), "levelshots/%s.jpg", mapnames[menuitem->curvalue] );

	if( trap_FS_FOpenFile( path, NULL, FS_READ ) == -1 ) 
		Q_snprintfz( path, sizeof(path), "levelshots/%s.tga", mapnames[menuitem->curvalue] );

	if( trap_FS_FOpenFile( path, NULL, FS_READ ) == -1 ) 
		Q_snprintfz( path, sizeof(path), "gfx/ui/unknownmap", mapnames[menuitem->curvalue] );

	s_levelshot = trap_R_RegisterPic( path );
}

void StartServerActionFunc( menucommon_t *unused )
{
	char			startmap[1024];
	char			*str;

	trap_Cvar_Set( "g_gametype", gametype_names[m_gametype] );
	trap_Cvar_SetValue( "sv_skilllevel", m_skill );
	trap_Cvar_SetValue( "sv_cheats", m_cheats );
	trap_Cvar_SetValue( "g_instagib", m_instagib );
	trap_Cvar_SetValue( "sv_public", m_public );

	str = UI_GetMenuitemFieldBuffer( UI_MenuItemByName("m_startserver_hostname") );
	if( str )trap_Cvar_Set( "sv_hostname", str );

	str = UI_GetMenuitemFieldBuffer( UI_MenuItemByName("m_startserver_timelimit") );
	if( str )trap_Cvar_Set( "g_timelimit", str );

	str = UI_GetMenuitemFieldBuffer( UI_MenuItemByName("m_startserver_scorelimit") );
	if( str )trap_Cvar_Set( "g_scorelimit", str );

	str = UI_GetMenuitemFieldBuffer( UI_MenuItemByName("m_startserver_numbots") );
	if( str )trap_Cvar_Set( "g_numbots", str );

	str = UI_GetMenuitemFieldBuffer( UI_MenuItemByName("m_startserver_maxplayers") );
	if( str )trap_Cvar_Set( "sv_maxclients", str );
	
	Q_strncpyz( startmap, mapnames[m_mapnum], sizeof(startmap) );
	if( uis.serverState )
		trap_Cmd_ExecuteText( EXEC_APPEND, "disconnect\n" );
	trap_Cmd_ExecuteText( EXEC_APPEND, va("map %s\n", startmap) );
}

qboolean StartServer_MenuInit( void )
{
	menucommon_t *menuitem;

	static char *skill_names[] =
	{
		"easy",
		"normal",
		"hard",
		"all",
		0
	};

	char *s, *gametype;
	char buffer[2048];
	int nummaps;
	int length;
	int	maxclients;
	int i;
	int y = 40;
	int yoffset = 0;

	/*
	** load the list of maps
	*/
	if( (nummaps = trap_FS_GetFileList( "maps", ".bsp", buffer, sizeof(buffer) )) == 0 ) {
		Menu_SetStatusBar( &s_startserver_menu, "No maps found" );
		return qfalse;
	}

	mapnames = UI_Malloc( sizeof( char * ) * ( nummaps + 1 ) );

	s = buffer;
	length = 0;

	for ( i = 0; i < nummaps; i++, s += length+1 )
	{
		char  shortname[MAX_TOKEN_CHARS];
		char  scratch[200];
		int	  j;

		length = strlen( s );
		for (j=0 ; j<length-4 ; j++)			// skip .bsp
			shortname[j] = s[j];
		shortname[j] = 0;

		Q_snprintfz( scratch, sizeof( scratch ), shortname );

		mapnames[i] = UI_CopyString( scratch );
	}

	mapnames[nummaps] = 0;

	/*
	** initialize the menu stuff
	*/
	s_startserver_menu.x = uis.vidWidth / 2;
	s_startserver_menu.y = y;
	s_startserver_menu.nitems = 0;

	m_mapnum %= nummaps;
	menuitem = UI_InitMenuItem( "m_startserver_map", "initial map", 0, y+yoffset, MTYPE_SPINCONTROL, ALIGN_RIGHT_TOP, uis.fontSystemSmall, MapChangeFunc );
	UI_SetupSpinControl( menuitem, mapnames, m_mapnum );
	Menu_AddItem( &s_startserver_menu, menuitem );
	MapChangeFunc( menuitem ); // update
	yoffset += trap_SCR_strHeight( menuitem->font );

	// get the current gametype
	i = 0;
	gametype = trap_Cvar_VariableString ("g_gametype");
	while( gametype_names[i] != 0 ) {
		if( !Q_stricmp(gametype, gametype_names[i]) )
			break;
		i++;
	}
	if( gametype_names[i] == 0 )
		i = 0;

	// g_gametype
	m_gametype = i;
	menuitem = UI_InitMenuItem( "m_startserver_gametype", "gametype", 0, y+yoffset, MTYPE_SPINCONTROL, ALIGN_RIGHT_TOP, uis.fontSystemSmall, M_GametypeFunc );
	UI_SetupSpinControl( menuitem, gametype_names, m_gametype );
	Menu_AddItem( &s_startserver_menu, menuitem );
	yoffset += trap_SCR_strHeight( menuitem->font );

	// sv_skilllevel
	menuitem = UI_InitMenuItem( "m_startserver_skill", "skill level", 0, y+yoffset, MTYPE_SPINCONTROL, ALIGN_RIGHT_TOP, uis.fontSystemSmall, M_SkillLevelFunc );
	m_skill = trap_Cvar_VariableValue( "sv_skilllevel" );
	UI_SetupSpinControl( menuitem, skill_names, m_skill );
	Menu_AddItem( &s_startserver_menu, menuitem );
	yoffset += trap_SCR_strHeight( menuitem->font );

	// sv_cheats
	menuitem = UI_InitMenuItem( "m_startserver_cheats", "cheats", 0, y+yoffset, MTYPE_SPINCONTROL, ALIGN_RIGHT_TOP, uis.fontSystemSmall, M_CheatsFunc );
	m_cheats = trap_Cvar_VariableValue( "sv_cheats" );
	UI_SetupSpinControl( menuitem, offon_names, m_cheats );
	Menu_AddItem( &s_startserver_menu, menuitem );
	yoffset += trap_SCR_strHeight( menuitem->font );

	// g_instagib
	menuitem = UI_InitMenuItem( "m_startserver_instagib", "instagib", 0, y+yoffset, MTYPE_SPINCONTROL, ALIGN_RIGHT_TOP, uis.fontSystemSmall, M_InstagibFunc );
	m_instagib = trap_Cvar_VariableValue( "g_instagib" );
	UI_SetupSpinControl( menuitem, offon_names, m_instagib );
	Menu_AddItem( &s_startserver_menu, menuitem );
	yoffset += trap_SCR_strHeight( menuitem->font );

	// sv_public
	menuitem = UI_InitMenuItem( "m_startserver_public", "public", 0, y+yoffset, MTYPE_SPINCONTROL, ALIGN_RIGHT_TOP, uis.fontSystemSmall, M_PublicFunc );
	m_public = trap_Cvar_VariableValue( "sv_public" );
	UI_SetupSpinControl( menuitem, offon_names, m_public );
	Menu_AddItem( &s_startserver_menu, menuitem );
	yoffset += trap_SCR_strHeight( menuitem->font );
	
	yoffset += trap_SCR_strHeight( menuitem->font );

	// g_timelimit
	menuitem = UI_InitMenuItem( "m_startserver_timelimit", "time limit", 0, y+yoffset, MTYPE_FIELD, ALIGN_RIGHT_TOP, uis.fontSystemSmall, NULL );
	menuitem->statusbar = "0 = no limit";
	UI_SetupField( menuitem, trap_Cvar_VariableString("g_timelimit"), 6, -1 );
	Menu_AddItem( &s_startserver_menu, menuitem );
	yoffset += trap_SCR_strHeight( menuitem->font );

	// g_scorelimit
	menuitem = UI_InitMenuItem( "m_startserver_scorelimit", "score limit", 0, y+yoffset, MTYPE_FIELD, ALIGN_RIGHT_TOP, uis.fontSystemSmall, NULL );
	menuitem->statusbar = "0 = no limit";
	UI_SetupField( menuitem, trap_Cvar_VariableString("g_scorelimit"), 6, -1 );
	Menu_AddItem( &s_startserver_menu, menuitem );
	yoffset += trap_SCR_strHeight( menuitem->font );

	// g_numbots
	menuitem = UI_InitMenuItem( "m_startserver_numbots", "number of bots", 0, y+yoffset, MTYPE_FIELD, ALIGN_RIGHT_TOP, uis.fontSystemSmall, NULL );
	menuitem->statusbar = "Can't be more than maxclients";
	UI_SetupField( menuitem, trap_Cvar_VariableString("g_numbots"), 6, -1 );
	Menu_AddItem( &s_startserver_menu, menuitem );
	yoffset += trap_SCR_strHeight( menuitem->font );

	// sv_maxclients
	/*
	** maxclients determines the maximum number of players that can join
	** the game.  If maxclients is only "1" then we should default the menu
	** option to 8 players, otherwise use whatever its current value is. 
	*/
	maxclients = trap_Cvar_VariableValue( "sv_maxclients" ) <= 1 ? 8:trap_Cvar_VariableValue( "sv_maxclients" );
	menuitem = UI_InitMenuItem( "m_startserver_maxplayers", "max players", 0, y+yoffset, MTYPE_FIELD, ALIGN_RIGHT_TOP, uis.fontSystemSmall, NULL );
	UI_SetupField( menuitem, va("%i", maxclients), 6, -1 );
	Menu_AddItem( &s_startserver_menu, menuitem );
	yoffset += trap_SCR_strHeight( menuitem->font );

	// sv_hostname
	menuitem = UI_InitMenuItem( "m_startserver_hostname", "server name", 0, y+yoffset, MTYPE_FIELD, ALIGN_RIGHT_TOP, uis.fontSystemSmall, NULL );
	UI_SetupField( menuitem, trap_Cvar_VariableString("sv_hostname"), 20, -1 );
	Menu_AddItem( &s_startserver_menu, menuitem );
	yoffset += trap_SCR_strHeight( menuitem->font );

	// begin button
	menuitem = UI_InitMenuItem( "m_startserver_begin", "begin", 16, y+yoffset, MTYPE_ACTION, ALIGN_LEFT_TOP, uis.fontSystemBig, StartServerActionFunc );
	Menu_AddItem( &s_startserver_menu, menuitem );
	
	menuitem = UI_InitMenuItem( "m_startserver_back", "back", -16, y+yoffset, MTYPE_ACTION, ALIGN_RIGHT_TOP, uis.fontSystemBig, M_genericBackFunc );
	Menu_AddItem( &s_startserver_menu, menuitem );
	yoffset += trap_SCR_strHeight( menuitem->font );

	Menu_Center( &s_startserver_menu );
	Menu_Init ( &s_startserver_menu );
	return qtrue;
}

void StartServer_MenuDraw(void)
{
	trap_R_DrawStretchPic ( s_startserver_menu.x - 80, s_startserver_menu.y - 90, 160, 120, 0, 0, 1, 1, colorWhite, s_levelshot );
	Menu_Draw( &s_startserver_menu );
}

const char *StartServer_MenuKey( int key )
{
	menucommon_t *item;

	item = Menu_ItemAtCursor ( &s_startserver_menu );

	if ( key == K_ESCAPE || ( (key == K_MOUSE2) && (item->type != MTYPE_SPINCONTROL) &&
		(item->type != MTYPE_SLIDER)) )
	{
		if ( mapnames )
		{
			int i;

			for ( i = 0; i < nummaps; i++ )
				UI_Free( mapnames[i] );
			UI_Free( mapnames );
		}
		mapnames = 0;
		nummaps = 0;
	} 

	return Default_MenuKey( &s_startserver_menu, key );
}

const char *StartServer_MenuCharEvent( int key )
{
	return Default_MenuCharEvent( &s_startserver_menu, key );
}

void M_Menu_StartServer_f( void )
{
	if( !StartServer_MenuInit() )
		return;

	Menu_SetStatusBar( &s_startserver_menu, NULL );
	M_PushMenu( &s_startserver_menu, StartServer_MenuDraw, StartServer_MenuKey, StartServer_MenuCharEvent );
}
