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

//=============================================================================
//
//PLAYER CONFIG MENU
//
//=============================================================================

static menuframework_s	s_player_config_menu;

#define NUM_CROSSHAIRS	5

static void HandednessCallback( menucommon_t *menuitem )
{
	trap_Cvar_SetValue( "hand", menuitem->curvalue );
}

//==============================
//	CrossHair
//==============================

static void				*s_crosshair_pic;
static int				menu_crosshair_id;
static void CrosshairFunc( void *unused )
{
	menu_crosshair_id++;
	if( menu_crosshair_id < 0 || menu_crosshair_id >= NUM_CROSSHAIRS )
		menu_crosshair_id = 0;

	s_crosshair_pic = trap_R_RegisterPic( va("gfx/hud/crosshair%i", menu_crosshair_id) );
	trap_Cvar_SetValue( "cg_crosshair", menu_crosshair_id );
}

cvar_t *pcolor;

//=================
//M_PlayerConfig_ApplyChanges
//=================
void M_PlayerConfig_ApplyChanges( void ) {
	menucommon_t *playerbox = UI_MenuItemByName( "m_playerconfig_model" );
	menucommon_t *skinbox = UI_MenuItemByName( "m_playerconfig_skin" );
	menucommon_t *namebox = UI_MenuItemByName( "m_playerconfig_name" );
	m_listitem_t *item = UI_FindItemInScrollListWithId( &playermodelsItemsList, playerbox->curvalue );
	playermodelinfo_s *playermodel = (playermodelinfo_s*)item->data;

	trap_Cvar_Set( "name", ((menufield_t*)namebox->itemlocal)->buffer );
	trap_Cvar_Set( "skin", playermodel->skinnames[skinbox->curvalue] );
	trap_Cvar_Set( "model", playermodel->directory );
	trap_Cvar_Set( "color", va( "%i %i %i", (int)playerColor[0], (int)playerColor[1], (int)playerColor[2] ) );
}

static void M_PlayerConfig_Close( menucommon_t *menuitem ) {
	M_genericBackFunc( menuitem );
}

static void M_PlayerConfig_SaveAndClose( menucommon_t *menuitem ) {
	M_PlayerConfig_ApplyChanges();
	M_PlayerConfig_Close( menuitem );
}

static void ModelCallback( menucommon_t *menuitem )
{
	menucommon_t *playerbox, *skinbox;
	m_listitem_t *item;
	playermodelinfo_s *playermodel;

	playerbox = UI_MenuItemByName( "m_playerconfig_model" );
	skinbox = UI_MenuItemByName( "m_playerconfig_skin" );
	if( !playerbox || !skinbox )
		return;

	item = UI_FindItemInScrollListWithId( &playermodelsItemsList, playerbox->curvalue );
	playermodel = (playermodelinfo_s*)item->data;
	skinbox->itemnames = playermodel->skinnames;

	skinbox->curvalue = 0;
}

void M_GetPlayerColor( void ) {
	int rgbcolor;
	pcolor = trap_Cvar_Get( "color", "", CVAR_ARCHIVE|CVAR_USERINFO );
	rgbcolor = COM_ReadColorRGBString( pcolor->string );
	if( rgbcolor == -1 ) {
		rgbcolor = COM_ReadColorRGBString( pcolor->dvalue );
	}
	if( rgbcolor != -1 ) {
		Vector4Set( playerColor, COLOR_R(rgbcolor), COLOR_G(rgbcolor), COLOR_B(rgbcolor), 255 ); 
	} else {
		Vector4Set( playerColor, 255, 255, 255, 255 ); // start white
	}
	pcolor->modified = qfalse;
}

//=================
//PlayerConfig_MenuInit
//=================
qboolean PlayerConfig_MenuInit( void )
{
	menucommon_t	*menuitem;
	int currentdirectoryindex = 0;
	int currentskinindex = 0;
	int	hand = trap_Cvar_VariableValue( "hand" );
	char *name = trap_Cvar_VariableString( "name" );
	char *model = trap_Cvar_VariableString( "model" );
	char *skin = trap_Cvar_VariableString( "skin" );
	int x = -150;
	int y = -100;
	int y_offset;
	static char *handedness[] = { "right", "left", "center", 0 };
	m_listitem_t *item;
	playermodelinfo_s *playermodel;

	M_GetPlayerColor();

	if( playermodelsItemsList.numItems == 0 )
		return qfalse;

	if ( hand < 0 || hand > 2 )
		trap_Cvar_SetValue( "hand", 0 );

	// find the skin and model matching our user settings (if any)
	UI_FindIndexForModelAndSkin( model, skin, &currentdirectoryindex, &currentskinindex );

	s_player_config_menu.x = uis.vidWidth / 2; 
	s_player_config_menu.y = uis.vidHeight / 2;
	s_player_config_menu.nitems = 0;

	// name
	menuitem = UI_InitMenuItem( "m_playerconfig_name", "name", x, y, MTYPE_FIELD, ALIGN_RIGHT_TOP, uis.fontSystemSmall, NULL );
	UI_SetupField( menuitem, name, 20, -1 );
	Menu_AddItem( &s_player_config_menu, menuitem );

	y_offset = trap_SCR_strHeight( menuitem->font );

	// cg_crosshair
	menuitem = UI_InitMenuItem( "m_playerconfig_crosshair", "crosshair", x, y += 8 + y_offset, MTYPE_ACTION, ALIGN_RIGHT_TOP, uis.fontSystemSmall, CrosshairFunc );
	Menu_AddItem( &s_player_config_menu, menuitem );
	menu_crosshair_id = trap_Cvar_VariableValue( "cg_crosshair" );
	clamp( menu_crosshair_id, 0, NUM_CROSSHAIRS - 1 );
	s_crosshair_pic = trap_R_RegisterPic( va ("gfx/hud/crosshair%i", menu_crosshair_id));

	y_offset = trap_SCR_strHeight( menuitem->font );
	y += y_offset;

	// model
	menuitem = UI_InitMenuItem( "m_playerconfig_model", "model", x, y+=y_offset, MTYPE_SPINCONTROL, ALIGN_RIGHT_TOP, uis.fontSystemSmall, ModelCallback );
	UI_SetupSpinControl( menuitem, playermodelsItemsList.item_names, currentdirectoryindex );
	Menu_AddItem( &s_player_config_menu, menuitem );

	// skin
	item = UI_FindItemInScrollListWithId( &playermodelsItemsList, currentdirectoryindex );
	playermodel = (playermodelinfo_s*)item->data;
	menuitem = UI_InitMenuItem( "m_playerconfig_skin", "skin", x, y+=y_offset, MTYPE_SPINCONTROL, ALIGN_RIGHT_TOP, uis.fontSystemSmall, NULL );
	UI_SetupSpinControl( menuitem, playermodel->skinnames, currentskinindex );
	Menu_AddItem( &s_player_config_menu, menuitem );

	y+=y_offset;

	// hand
	menuitem = UI_InitMenuItem( "m_playerconfig_handedness", "handedness", x, y+=y_offset, MTYPE_SPINCONTROL, ALIGN_RIGHT_TOP, uis.fontSystemSmall, HandednessCallback );
	UI_SetupSpinControl( menuitem, handedness, trap_Cvar_VariableValue( "hand" ) );
	Menu_AddItem( &s_player_config_menu, menuitem );
	y+=y_offset;

	menuitem = UI_InitMenuItem( "m_playerconfig_colorred", "red", x, y+=y_offset, MTYPE_SLIDER, ALIGN_RIGHT_TOP, uis.fontSystemSmall, UI_ColorRedCallback );
	Menu_AddItem( &s_player_config_menu, menuitem );
	UI_SetupSlider( menuitem, 12, playerColor[0], 0, 255 );

	menuitem = UI_InitMenuItem( "m_playerconfig_colorgreen", "green", x, y+=y_offset, MTYPE_SLIDER, ALIGN_RIGHT_TOP, uis.fontSystemSmall, UI_ColorGreenCallback );
	Menu_AddItem( &s_player_config_menu, menuitem );
	UI_SetupSlider( menuitem, 12, playerColor[1], 0, 255 );

	menuitem = UI_InitMenuItem( "m_playerconfig_colorblue", "blue", x, y+=y_offset, MTYPE_SLIDER, ALIGN_RIGHT_TOP, uis.fontSystemSmall, UI_ColorBlueCallback );
	Menu_AddItem( &s_player_config_menu, menuitem );
	UI_SetupSlider( menuitem, 12, playerColor[2], 0, 255 );

	y+=y_offset;
	y+=y_offset;

	menuitem = UI_InitMenuItem( "m_playerconfig_apply", "apply", x + 16, y, MTYPE_ACTION, ALIGN_LEFT_TOP, uis.fontSystemBig, M_PlayerConfig_SaveAndClose );
	Menu_AddItem( &s_player_config_menu, menuitem );

	menuitem = UI_InitMenuItem( "m_playerconfig_back", "back", x - 16, y, MTYPE_ACTION, ALIGN_RIGHT_TOP, uis.fontSystemBig, M_PlayerConfig_Close );
	Menu_AddItem( &s_player_config_menu, menuitem );

	Menu_Init( &s_player_config_menu );

	return qtrue;
}

//=================
//PlayerConfig_MenuDraw - skelmod
//=================
void PlayerConfig_MenuDraw( void )
{
	menucommon_t *playerbox, *skinbox;
	m_listitem_t *item;
	playermodelinfo_s *playermodel;
	int x, y, width, height;

	//draw crosshair
	if ( s_crosshair_pic ) {
		menucommon_t *crosshairbox = UI_MenuItemByName( "m_playerconfig_crosshair" );
		if( crosshairbox ) {
			trap_R_DrawStretchPic ( s_player_config_menu.x + crosshairbox->x + 16,
				s_player_config_menu.y + crosshairbox->y - 8, 32, 32, 
				0, 0, 1, 1, colorWhite, s_crosshair_pic );
		}
	}

	// go for the model

	// if the color cvar is modified from outside of the ui (console), update the color vector
	if( pcolor && pcolor->modified ) {
		M_GetPlayerColor();
	}

	playerbox = UI_MenuItemByName( "m_playerconfig_model" );
	skinbox = UI_MenuItemByName( "m_playerconfig_skin" );
	if( !playerbox || !skinbox )
		return;

	Menu_Draw( &s_player_config_menu ); // draw menu first

	item = UI_FindItemInScrollListWithId( &playermodelsItemsList, playerbox->curvalue ); 
	if( item && item->data ) {
		playermodel = (playermodelinfo_s*)item->data;
		if( !playermodel->skinnames[skinbox->curvalue] )
			return;

		// draw player model
		x = (uis.vidWidth / 2) - (64*(uis.vidWidth/800));
		y = 0;
		width = (uis.vidWidth / 2);
		height = uis.vidHeight;
		UI_DrawPlayerModel( playermodel->directory, playermodel->skinnames[skinbox->curvalue], playerColor, x, y, width, height );
	}
}


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

	item = Menu_ItemAtCursor ( &s_player_config_menu );

	if ( key == K_ESCAPE || ( (key == K_MOUSE2) && (item->type != MTYPE_SPINCONTROL) &&
		(item->type != MTYPE_SLIDER)) )
	{
		M_PlayerConfig_SaveAndClose( NULL );
		return menu_out_sound;
	}

	return Default_MenuKey( &s_player_config_menu, key );
}

const char *PlayerConfig_MenuCharEvent( int key )
{
	return Default_MenuCharEvent( &s_player_config_menu, key );
}

void M_Menu_PlayerConfig_f( void )
{
	if( !PlayerConfig_MenuInit() )
	{
		Menu_SetStatusBar( &s_player_config_menu, "No valid player models found" );
		return;
	}

	Menu_SetStatusBar( &s_player_config_menu, NULL );
	M_PushMenu( &s_player_config_menu, PlayerConfig_MenuDraw, PlayerConfig_MenuKey, PlayerConfig_MenuCharEvent );
}
