/*
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"

#define REF_OPENGL	0
#define REF_3DFX	1
#define REF_POWERVR	2
#define REF_VERITE	3

static void Video_MenuInit( void );

/*
=======================================================================

VIDEO MENU

=======================================================================
*/

static menuframework_s	s_video_menu;


static void BrightnessCallback( menucommon_t *menuitem )
{
	float gamma;

	gamma = ( 0.8 - ( menuitem->curvalue/10.0 - 0.5 ) ) + 0.5;
	trap_Cvar_SetValue( "r_gamma", gamma );
}

static void ResetDefaults( menucommon_t *menuitem )
{
	Video_MenuInit();
}

static void ExtensionsCallback( menucommon_t *menuitem )
{
	trap_Cmd_ExecuteText( EXEC_APPEND, "menu_glext" );
}

static void ApplyChanges( menucommon_t *unused )
{
	menucommon_t *menuitem;

	menuitem = UI_MenuItemByName( "m_video_r_picmip" );
	trap_Cvar_SetValue( "r_picmip", 6 - menuitem->curvalue );

	menuitem = UI_MenuItemByName( "m_video_r_skymip" );
	trap_Cvar_SetValue( "r_skymip", 3 - menuitem->curvalue );

	menuitem = UI_MenuItemByName( "m_video_r_subdivisions" );
	trap_Cvar_SetValue( "r_subdivisions", (8 - menuitem->curvalue)*4 );

	menuitem = UI_MenuItemByName( "m_video_vid_fullscreen" );
	trap_Cvar_SetValue( "vid_fullscreen", menuitem->curvalue );

	menuitem = UI_MenuItemByName( "m_video_r_mode" );
	trap_Cvar_SetValue( "r_mode", menuitem->curvalue );

	menuitem = UI_MenuItemByName( "m_video_r_colorbits" );
	trap_Cvar_SetValue( "r_colorbits", 16 * menuitem->curvalue );

	menuitem = UI_MenuItemByName( "m_video_r_texturebits" );
	trap_Cvar_SetValue( "r_texturebits", 16 * menuitem->curvalue );

	menuitem = UI_MenuItemByName( "m_video_r_detailtextures" );
	trap_Cvar_SetValue( "r_detailtextures", menuitem->curvalue );

	menuitem = UI_MenuItemByName( "m_video_r_texturemode" );
	trap_Cvar_Set( "r_texturemode", menuitem->curvalue ? "GL_LINEAR_MIPMAP_LINEAR" : "GL_LINEAR_MIPMAP_NEAREST" );

#ifdef CGAMEGETLIGHTORIGIN
	menuitem = UI_MenuItemByName( "m_video_cg_shadows" );
	trap_Cvar_SetValue( "cg_shadows", menuitem->curvalue );
	trap_Cvar_SetValue( "r_stencilbits", (menuitem->curvalue > 1)*8 );  //  2 is SHADOWS_STENCIL
#else
	menuitem = UI_MenuItemByName( "m_video_cg_shadows" );
	trap_Cvar_SetValue( "r_shadows", menuitem->curvalue );
	trap_Cvar_SetValue( "r_stencilbits", menuitem->curvalue != 0) * 8 );  //  2 is SHADOWS_STENCIL
#endif
	menuitem = UI_MenuItemByName( "m_video_r_bloom" );
	trap_Cvar_SetValue( "r_bloom", menuitem->curvalue );

	menuitem = UI_MenuItemByName( "m_video_r_swapinterval" );
	trap_Cvar_SetValue( "r_swapinterval", menuitem->curvalue );

	trap_Cmd_ExecuteText( EXEC_APPEND, "vid_restart\n" );
	trap_Cmd_Execute();
}

/*
** Video_MenuInit
*/
static void Video_MenuInit( void )
{
	menucommon_t *menuitem;
	char *gl_driver = trap_Cvar_VariableString( "gl_driver" );
	int y = 0;
	int yoffset = 0;
	static char *resolutions[] = 
	{
		"[320 240  ]",	// { "Mode 0: 320x240",   320, 240,   0 },
		"[400 300  ]",	// { "Mode 1: 400x300",   400, 300,   1 },
		"[512 384  ]",	// { "Mode 2: 512x384",   512, 384,   2 },
		"[640 480  ]",	// { "Mode 3: 640x480",   640, 480,   3 },
		"[800 600  ]",	// { "Mode 4: 800x600",   800, 600,   4 },
		"[960 720  ]",	// { "Mode 5: 960x720",   960, 720,   5 },
		"[1024 768 ]",	// { "Mode 6: 1024x768",  1024, 768,  6 },
		"[1152 864 ]",	// { "Mode 7: 1152x864",  1152, 864,  7 },
		"[1280 800 ]",	// { "Mode 8: 1280x800",  1280, 800,  8 },
		"[1280 960 ]",	// { "Mode 9: 1280x960",  1280, 960,  9 },
		"[1280 1024]",	// { "Mode 10: 1280x1024",  1280, 1024, 10 },
		"[1600 1200]",	// { "Mode 11: 1600x1200", 1600, 1200, 11 },
		"[2048 1536]",	// { "Mode 12: 2048x1536", 2048, 1536, 12 }
		0
	};
	static char *refs[] =
	{
		"[default OpenGL]",
		"[3Dfx OpenGL   ]",
		"[PowerVR OpenGL]",
//		"[Rendition OpenGL]",
		0
	};

	static char *filter_names[] =
	{
		"bilinear", "trilinear", 0
	};

	static char *colordepth_names[] =
	{
		"desktop", "16 bits", "32 bits", 0
	};

	static char *texturebits_names[] =
	{
		"default", "16", "32", 0
	};
#ifdef CGAMEGETLIGHTORIGIN
	static char *shadows_names[] =
	{
		"no", "simple", "stencil", 0
	};
#endif

	s_video_menu.x = uis.vidWidth / 2;
	s_video_menu.y = 0;
	s_video_menu.nitems = 0;

	menuitem = UI_InitMenuItem( "m_video_glext", "OpenGL Extensions", 0, y+yoffset, MTYPE_ACTION, ALIGN_CENTER_TOP, uis.fontSystemMedium, ExtensionsCallback );
	Menu_AddItem( &s_video_menu, menuitem );
	yoffset += trap_SCR_strHeight( menuitem->font );

	menuitem = UI_InitMenuItem( "m_video_gl_driver", "driver", 0, y+yoffset, MTYPE_SPINCONTROL, ALIGN_RIGHT_TOP, uis.fontSystemSmall, NULL );
	Menu_AddItem( &s_video_menu, menuitem );
	if( !Q_stricmp( gl_driver, "3dfxgl" ) )
		UI_SetupSpinControl( menuitem, refs, REF_3DFX );
	else if( !Q_stricmp( gl_driver, "pvrgl" ) )
		UI_SetupSpinControl( menuitem, refs, REF_POWERVR );
	else if( !Q_stricmp( gl_driver, "opengl32" ) )
		UI_SetupSpinControl( menuitem, refs, REF_OPENGL );
	else
		UI_SetupSpinControl( menuitem, refs, REF_OPENGL );
	yoffset += trap_SCR_strHeight( menuitem->font );

	menuitem = UI_InitMenuItem( "m_video_r_mode", "video mode", 0, y+yoffset, MTYPE_SPINCONTROL, ALIGN_RIGHT_TOP, uis.fontSystemSmall, NULL );
	Menu_AddItem( &s_video_menu, menuitem );
	UI_SetupSpinControl( menuitem, resolutions, trap_Cvar_VariableValue( "r_mode" ) );
	yoffset += trap_SCR_strHeight( menuitem->font );

	menuitem = UI_InitMenuItem( "m_video_r_gamma", "brightness", 0, y+yoffset, MTYPE_SLIDER, ALIGN_RIGHT_TOP, uis.fontSystemSmall, BrightnessCallback );
	Menu_AddItem( &s_video_menu, menuitem );
	UI_SetupSlider( menuitem, 12, (( 1.3 - trap_Cvar_VariableValue( "r_gamma" ) + 0.5 ) * 10), 5, 13 );
	yoffset += trap_SCR_strHeight( menuitem->font );

	menuitem = UI_InitMenuItem( "m_video_vid_fullscreen", "fullscreen", 0, y+yoffset, MTYPE_SPINCONTROL, ALIGN_RIGHT_TOP, uis.fontSystemSmall, NULL );
	Menu_AddItem( &s_video_menu, menuitem );
	UI_SetupSpinControl( menuitem, noyes_names, trap_Cvar_VariableValue( "vid_fullscreen" ) != 0 );
	yoffset += trap_SCR_strHeight( menuitem->font );

	menuitem = UI_InitMenuItem( "m_video_r_colorbits", "color depth", 0, y+yoffset, MTYPE_SPINCONTROL, ALIGN_RIGHT_TOP, uis.fontSystemSmall, NULL );
	Menu_AddItem( &s_video_menu, menuitem );
	if( !Q_stricmp( trap_Cvar_VariableString( "r_colorbits" ), "16" ) )
		UI_SetupSpinControl( menuitem, colordepth_names, 1 );
	else if( !Q_stricmp( trap_Cvar_VariableString( "r_colorbits" ), "32" ) )
		UI_SetupSpinControl( menuitem, colordepth_names, 2 );
	else
		UI_SetupSpinControl( menuitem, colordepth_names, 0 );
	yoffset += trap_SCR_strHeight( menuitem->font );
	
	menuitem = UI_InitMenuItem( "m_video_r_texturebits", "texture bits", 0, y+yoffset, MTYPE_SPINCONTROL, ALIGN_RIGHT_TOP, uis.fontSystemSmall, NULL );
	Menu_AddItem( &s_video_menu, menuitem );
	if( !Q_stricmp( trap_Cvar_VariableString( "r_texturebits" ), "16" ) )
		UI_SetupSpinControl( menuitem, texturebits_names, 1 );
	else if( !Q_stricmp( trap_Cvar_VariableString( "r_texturebits" ), "32" ) )
		UI_SetupSpinControl( menuitem, texturebits_names, 2 );
	else
		UI_SetupSpinControl( menuitem, texturebits_names, 0 );
	yoffset += trap_SCR_strHeight( menuitem->font );

	menuitem = UI_InitMenuItem( "m_video_r_detailtextures", "detail textures", 0, y+yoffset, MTYPE_SPINCONTROL, ALIGN_RIGHT_TOP, uis.fontSystemSmall, NULL );
	Menu_AddItem( &s_video_menu, menuitem );
	UI_SetupSpinControl( menuitem, offon_names, trap_Cvar_VariableValue( "r_detailtextures" ) != 0 );
	yoffset += trap_SCR_strHeight( menuitem->font );

	menuitem = UI_InitMenuItem( "m_video_r_picmip", "texture quality", 0, y+yoffset, MTYPE_SLIDER, ALIGN_RIGHT_TOP, uis.fontSystemSmall, NULL );
	Menu_AddItem( &s_video_menu, menuitem );
	UI_SetupSlider( menuitem, 12, 6-trap_Cvar_VariableValue( "r_picmip" ), 0, 6 );
	yoffset += trap_SCR_strHeight( menuitem->font );

	menuitem = UI_InitMenuItem( "m_video_r_skymip", "sky quality", 0, y+yoffset, MTYPE_SLIDER, ALIGN_RIGHT_TOP, uis.fontSystemSmall, NULL );
	Menu_AddItem( &s_video_menu, menuitem );
	UI_SetupSlider( menuitem, 12, 3-trap_Cvar_VariableValue( "r_skymip" ), 0, 3 );
	yoffset += trap_SCR_strHeight( menuitem->font );

	menuitem = UI_InitMenuItem( "m_video_r_subdivisions", "curves geometric detail", 0, y+yoffset, MTYPE_SLIDER, ALIGN_RIGHT_TOP, uis.fontSystemSmall, NULL );
	Menu_AddItem( &s_video_menu, menuitem );
	UI_SetupSlider( menuitem, 12, (8-(trap_Cvar_VariableValue( "r_subdivisions" )/4)), 0, 7 );
	yoffset += trap_SCR_strHeight( menuitem->font );

	menuitem = UI_InitMenuItem( "m_video_r_texturemode", "texture filter", 0, y+yoffset, MTYPE_SPINCONTROL, ALIGN_RIGHT_TOP, uis.fontSystemSmall, NULL );
	Menu_AddItem( &s_video_menu, menuitem );
	if( !Q_stricmp( trap_Cvar_VariableString( "r_texturemode" ), "GL_LINEAR_MIPMAP_NEAREST" ) )
		UI_SetupSpinControl( menuitem, filter_names, 0 );
	else
		UI_SetupSpinControl( menuitem, filter_names, 1 );
	yoffset += trap_SCR_strHeight( menuitem->font );

	menuitem = UI_InitMenuItem( "m_video_cg_shadows", "shadows", 0, y+yoffset, MTYPE_SPINCONTROL, ALIGN_RIGHT_TOP, uis.fontSystemSmall, NULL );
	Menu_AddItem( &s_video_menu, menuitem );
#ifdef CGAMEGETLIGHTORIGIN
	UI_SetupSpinControl( menuitem, shadows_names, trap_Cvar_VariableValue( "cg_shadows" ) );
#else
	UI_SetupSpinControl( menuitem, noyes_names, trap_Cvar_VariableValue( "r_shadows" ) );
#endif
	yoffset += trap_SCR_strHeight( menuitem->font );

	menuitem = UI_InitMenuItem( "m_video_r_bloom", "light bloom", 0, y+yoffset, MTYPE_SPINCONTROL, ALIGN_RIGHT_TOP, uis.fontSystemSmall, NULL );
	Menu_AddItem( &s_video_menu, menuitem );
	UI_SetupSpinControl( menuitem, noyes_names, trap_Cvar_VariableValue( "r_bloom" ) );
	yoffset += trap_SCR_strHeight( menuitem->font );

	menuitem = UI_InitMenuItem( "m_video_r_swapinterval", "vertical sync", 0, y+yoffset, MTYPE_SPINCONTROL, ALIGN_RIGHT_TOP, uis.fontSystemSmall, NULL );
	Menu_AddItem( &s_video_menu, menuitem );
	UI_SetupSpinControl( menuitem, noyes_names, trap_Cvar_VariableValue( "r_swapinterval" ) );
	yoffset += trap_SCR_strHeight( menuitem->font );
	yoffset += trap_SCR_strHeight( menuitem->font );

	menuitem = UI_InitMenuItem( "m_video_reset", "reset to defaults", 0, y+yoffset, MTYPE_ACTION, ALIGN_CENTER_TOP, uis.fontSystemSmall, ResetDefaults );
	Menu_AddItem( &s_video_menu, menuitem );
	yoffset += trap_SCR_strHeight( menuitem->font );

	menuitem = UI_InitMenuItem( "m_video_apply", "apply", 16, y+yoffset, MTYPE_ACTION, ALIGN_LEFT_TOP, uis.fontSystemBig, ApplyChanges );
	Menu_AddItem( &s_video_menu, menuitem );

	menuitem = UI_InitMenuItem( "m_video_back", "back", -16, y+yoffset, MTYPE_ACTION, ALIGN_RIGHT_TOP, uis.fontSystemBig, M_genericBackFunc );
	Menu_AddItem( &s_video_menu, menuitem );
	yoffset += trap_SCR_strHeight( menuitem->font );

	Menu_Center( &s_video_menu );
	Menu_Init( &s_video_menu );
}

/*
================
Video_MenuDraw
================
*/
void Video_MenuDraw( void )
{
	/*
	** move cursor to a reasonable starting position
	*/
	Menu_AdjustCursor( &s_video_menu, 1 );

	/*
	** draw the menu
	*/
	Menu_Draw( &s_video_menu );
}

/*
================
Video_MenuKey
================
*/
const char *Video_MenuKey( int key )
{
	return Default_MenuKey( &s_video_menu, key );
}

/*
================
Video_MenuCharEvent
================
*/
const char *Video_MenuCharEvent( int key )
{
	return Default_MenuCharEvent( &s_video_menu, key );
}

void M_Menu_Video_f( void )
{
	Video_MenuInit();
	M_PushMenu( &s_video_menu, Video_MenuDraw, Video_MenuKey, Video_MenuCharEvent );
}
