

#include "gui/textbox.h"
using namespace VGUI;

TextBox::TextBox( Widget* w )
{
	setting = "";
	accepts = "";
	center = w->GetCenter();
	name = w->GetName();
	text = w->GetText();
	type = w->GetType();
	tip = w->GetTip();
	rel_width = w->GetRelWidth();
	rel_height = w->GetRelHeight();
	enabled = w->GetEnabled();
	selected = w->GetSelected();
	is_default = w->GetDefault();
	is_cancel = w->GetCancel();
	has_icon = w->GetHasIcon();
	width_auto = w->GetWidthAuto();
	height_auto = w->GetHeightAuto();
	font_size = w->GetFontSize();
	color_r = w->GetColorR();
	color_g = w->GetColorG();
	color_b = w->GetColorB();
	spacing = 0.3;
	cursor_pos = 0;
	highlight_start = highlight_end = 10000;

	string skin_path = settings.GetSkinPath();
	textbox_tex.Load( skin_path + "/textures/widgets/text_box.png", false );
	cursor_tex.Load( skin_path + "/textures/widgets/text_cursor.png", false );
	highlight_tex.Load( skin_path + "/textures/widgets/text_highlight.png", false );

	tex_width = 0.0277;
	tex_height = 0.0370;

	// width = dist from left of text to wheel + width of wheel + texture width
	if( width_auto )
	{
		rel_width = spacing + font.Width( "999.999.999.999", 1, 6 ) + 0.1;
	}

	// height = button texture height
	if( height_auto )
	{
		rel_height = tex_height;
	}
	
	l_down=r_down=bkspc_down=del_down=mbtn_down=cursor_on = false;
}

TextBox::~TextBox()
{
}

void TextBox::SetSpacing( float new_spacing )
{
	spacing = new_spacing;
	if( width_auto )
	{
		rel_width = spacing + font.Width( "999.999.999.999", 1, 6 ) + 0.1;
	}
}

void TextBox::Save()
{
	settings.Set( setting, value );
}

void TextBox::ResetValue()
{
	string default_val;
	settings.Get( setting, default_val );
	SetValue( default_val );
}

void TextBox::Draw()
{
	Draw( 1.0 );
}

void TextBox::Draw( float opacity )
{
	//float char_width = 0.0;
	float center_x = center.GetXPercent();
	float center_y = center.GetYPercent();
	float rel_width_half = rel_width / 2.0f;
	float rel_height_half = rel_height / 2.0f;
	float opacity_txt = selected ? 0.9 : enabled ? 0.75 : 0.4;

	// draw textbox image
	utility.DrawButton( center_x - rel_width_half + spacing + 0.02777,
	                    center_y - rel_height_half,
	                    center_x + rel_width_half - 0.02777,
	                    center_y + rel_height_half,
	                    0.02777, &textbox_tex, opacity * opacity_txt );

/*	// draw highlight
	if( ( highlight_start != 10000 ) && ( highlight_end != 10000 ) && ( highlight_start != cursor_pos ) && ( highlight_start != highlight_end ) )
	{
		string::size_type h_s, h_e;
		if( highlight_start > highlight_end )
		{
			h_e = highlight_start;
			h_s = highlight_end;
		}
		else
		{
			h_s = highlight_start;
			h_e = highlight_end;
		}

		float highlight_min_x = center_x - rel_width_half + spacing + 0.02777 + font.Width( value.substr( 0, h_s ).c_str(), 1, font_size );
		float highlight_max_x = highlight_min_x + ( h_s == h_e ? 0.0 : font.Width( value.substr( h_s, h_e ).c_str(), 1, font_size ) - 0.02777 );

		utility.DrawButton( highlight_min_x + 0.02777,
		                    center_y - rel_height_half,
		                    highlight_max_x,
		                    center_y + rel_height_half,
		                    0.02777, highlight_tex, opacity * opacity_txt );
	}		
*/
	// draw textbox text
	font.Print( center_x - rel_width_half + spacing + 0.029,
	            center_y - rel_height_half - 0.005,
	            value.c_str(), 1, font_size, 0.0, 0.0, 0.0, opacity );

	float blink_time = (float)( SDL_GetTicks() - last_blink ) / 1000.0;
	if( blink_time >= 0.5 )
	{
		cursor_on = !cursor_on;
		last_blink = SDL_GetTicks();
	}

	// draw textbox cursor
	if( selected && cursor_on )
	{
		float cursor_x = center_x - rel_width_half + spacing + 0.02777 + font.Width( value.substr( 0, cursor_pos ).c_str(), 1, font_size );

		utility.Draw2D( cursor_x,
		                center_y - rel_height_half,
		                cursor_x + tex_width,
		                center_y + rel_height_half,
		                &cursor_tex, 0.0, 0, opacity );
	}

	// draw text
	font.Print( center_x - rel_width_half,
	            center_y - ( font.Height( text.c_str(), 1, font_size ) / 2.0f ),
	            text.c_str(), 1, font_size, color_r, color_g, color_b, opacity_txt * opacity );

	// draw tip
	if( selected && ( tip != "" ) )
		font.Print( 0.5 - ( font.Width( tip.c_str(), 1, 6 ) / 2.0f ), 0.90, tip.c_str(), 1, 6, 0.7, 0.7, 0.7, 0.9 );	
}

void TextBox::IncValuePress()
{
	Release();
	r_down = true;
}

void TextBox::IncValueRelease()
{
	if( r_down && ( cursor_pos < value.size() ) )
	{
		cursor_pos++;
	}
	Release();
}

void TextBox::DecValuePress()
{
	Release();
	l_down = true;
}

void TextBox::DecValueRelease()
{
	if( l_down && ( cursor_pos > 0 ) )
	{
		cursor_pos--;
	}
	Release();
}

void TextBox::BackspacePress()
{
	Release();
	bkspc_down = true;
}

void TextBox::BackspaceRelease()
{
	if( bkspc_down && ( cursor_pos > 0 ) )
	{
		cursor_pos--;
		value.erase( cursor_pos, 1 );
	}	
	Release();
}

void TextBox::DeletePress()
{
	Release();
	del_down = true;
}

void TextBox::DeleteRelease()
{
	if( del_down && ( cursor_pos < value.size() ) )
	{
		value.erase( cursor_pos, 1 );
	}	
	Release();
}

void TextBox::Release()
{
	r_down = l_down = bkspc_down = del_down = false;
}

void TextBox::EnterText( SDLKey key )
{
	if( key == SDLK_END )
	{
		cursor_pos = value.size();
		return;
	}
	else if( key == SDLK_HOME )
	{
		cursor_pos = 0;
		return;
	}

	for( unsigned int i = 0; i < accepts.size(); i++ )
	{
		if( accepts[i] == key )
		{
			string t;
			t.append((char *) &key);
			value.insert( cursor_pos, t );
			cursor_pos++;
			break;
		}
	}
}

bool TextBox::MouseOver( float x, float y )
{
	//string::size_type cursor_pos_click = 10000;
	float min_x, min_y, max_x, max_y;
	float center_x = center.GetXPercent();
	float center_y = center.GetYPercent();
	float rel_width_half = rel_width / 2.0f;
	float rel_height_half = rel_height / 2.0f;
	min_x = center_x - rel_width_half;
	min_y = center_y - rel_height_half;
	max_x = center_x + rel_width_half;
	max_y = center_y + rel_height_half;
/*
	if( mbtn_down && ( highlight_start != 10000 ) && 
	    ( x >= min_x ) && ( x <= max_x ) && ( y >= min_y ) && ( y <= max_y ) )
	{
		float char_width = 0.0;
		float min_char_x, max_char_x;
		float half_char_width;

		for( string::size_type i = 0; i < value.size(); i++ )
		{
			//char_width = font.Width( value.substr( i, i ).c_str(), 1, 6 );
			min_char_x = min_x + 0.029 + ( i == 0 ? 0.0 : font.Width( value.substr( 0, i - 1 ).c_str(), 1, 6 ) );
			max_char_x = min_x + 0.029 + font.Width( value.substr( 0, i ).c_str(), 1, 6 );
			char_width = max_char_x - min_char_x;
			half_char_width = char_width / 2.0f;

			if( ( x >= min_char_x ) && ( x <= ( max_char_x - half_char_width ) ) )
			{
				cursor_pos_click = i - 1;
				break;
			}
			else if( ( x > ( max_char_x - half_char_width ) ) && ( x < max_char_x ) )
			{
				cursor_pos_click = i;
				break;
			}
		}

		if( cursor_pos_click == 10000 )
		{
			if( ( x >= min_x ) && ( x < min_x + 0.029 ) )
			{
				cursor_pos = 0;
			}
			else // if( ( x <= max_x ) && ( x > max_x - 0.05 ) )
			{
				cursor_pos = value.size();
			}
		}
		else
		{
			cursor_pos = cursor_pos_click;
		}

		if( ( highlight_start != 100000 ) && ( highlight_start != cursor_pos ) )
			highlight_end = cursor_pos;
	}
*/
	return ( x > min_x ) && ( x < max_x ) && ( y > min_y ) && ( y < max_y );
}

string TextBox::MousePress( float x, float y )
{
	string action = "";
	string::size_type cursor_pos_click = 10000;
	float min_x, min_y, max_x, max_y;
	float center_x = center.GetXPercent();
	float center_y = center.GetYPercent();
	float rel_width_half = rel_width / 2.0f;
	float rel_height_half = rel_height / 2.0f;
	min_x = center_x - rel_width_half + spacing;
	min_y = center_y - rel_height_half;
	max_x = center_x + rel_width_half;
	max_y = center_y + rel_height_half;

	if( ( x >= min_x ) && ( x <= max_x ) && ( y >= min_y ) && ( y <= max_y ) )
	{
		mbtn_down = true;
		float char_width = 0.0;
		float min_char_x, max_char_x;
		float half_char_width;

		for( string::size_type i = 0; i < value.size(); i++ )
		{
			//char_width = font.Width( value.substr( i, i ).c_str(), 1, 6 );
			min_char_x = min_x + 0.029 + ( i == 0 ? 0.0 : font.Width( value.substr( 0, i - 1 ).c_str(), 1, 6 ) );
			max_char_x = min_x + 0.029 + font.Width( value.substr( 0, i ).c_str(), 1, 6 );
			char_width = max_char_x - min_char_x;
			half_char_width = char_width / 2.0f;

			if( ( x >= min_char_x ) && ( x <= ( max_char_x - half_char_width ) ) )
			{
				//cout << "click press on this character" << endl;
				cursor_pos_click = i - 1;
				break;
			}
			else if( ( x > ( max_char_x - half_char_width ) ) && ( x < max_char_x ) )
			{
				//cout << "click press on next character" << endl;
				cursor_pos_click = i;
				break;
			}
		}

		if( cursor_pos_click == 10000 )
		{
			if( ( x >= min_x ) && ( x < min_x + 0.029 ) )
			{
				cursor_pos = 0;
			}
			else // if( ( x <= max_x ) && ( x > max_x - 0.05 ) )
			{
				cursor_pos = value.size();
			}
		}
		else
		{
			cursor_pos = cursor_pos_click;
		}

		highlight_start = cursor_pos;
	}

	return action;
}

string TextBox::MouseRelease( float x, float y )
{
	mbtn_down = false;
	string action = "";
	string::size_type cursor_pos_click = 10000;
	float min_x, min_y, max_x, max_y;
	float center_x = center.GetXPercent();
	float center_y = center.GetYPercent();
	float rel_width_half = rel_width / 2.0f;
	float rel_height_half = rel_height / 2.0f;
	min_x = center_x - rel_width_half + spacing;
	min_y = center_y - rel_height_half;
	max_x = center_x + rel_width_half;
	max_y = center_y + rel_height_half;

	//cout << "mouse was released" << endl;
	if( /* mbtn_down && */ ( x >= min_x ) && ( x <= max_x ) && ( y >= min_y ) && ( y <= max_y ) )
	{
		//cout << "release was after the mouse button was down" << endl;
		float char_width = 0.0;
		float min_char_x, max_char_x;
		float half_char_width;

		for( string::size_type i = 0; i < value.size(); i++ )
		{
			//char_width = font.Width( value.substr( i, i ).c_str(), 1, 6 );
			min_char_x = min_x + 0.029 + ( i == 0 ? 0.0 : font.Width( value.substr( 0, i - 1 ).c_str(), 1, 6 ) );
			max_char_x = min_x + 0.029 + font.Width( value.substr( 0, i ).c_str(), 1, 6 );
			char_width = max_char_x - min_char_x;
			half_char_width = char_width / 2.0f;

			if( ( x >= min_char_x ) && ( x <= ( max_char_x - half_char_width ) ) )
			{
				//cout << "click release on this character" << endl;
				cursor_pos_click = i - 1;
				break;
			}
			else if( ( x > ( max_char_x - half_char_width ) ) && ( x < max_char_x ) )
			{
				//cout << "click release on next character" << endl;
				cursor_pos_click = i;
				break;
			}
		}

		if( cursor_pos_click == 10000 )
		{
			if( ( x >= min_x ) && ( x < min_x + 0.029 ) )
			{
				cursor_pos = 0;
			}
			else // if( ( x <= max_x ) && ( x > max_x - 0.05 ) )
			{
				cursor_pos = value.size();
			}
		}
		else
		{
			cursor_pos = cursor_pos_click;
		}

		//cout << "this character: " << value[cursor_pos] << endl;
		if( ( cursor_pos != highlight_start ) && ( highlight_start != 10000 ) )
			highlight_end = cursor_pos;
		else
			highlight_start = highlight_end = 10000;
	}

	return action;
}
