#include "Utility/UI/CheckBox.h"
#include "Mix/Graphics.h"

namespace Utility{ namespace UI {

CheckBox::CheckBox( void ) :
m_bCheck( False ),
m_bCheckDown( False )
{
}

CheckBox::~CheckBox( void )
{
}

void CheckBox::SetText( const wchar_t* pText )
{
	m_Text = pText;
}

const wchar_t* CheckBox::GetText( void ) const
{
	return m_Text.GetConstPtr();
}

void CheckBox::SetState( Boolean state )
{
	m_bCheck = state;
}

Boolean CheckBox::GetState( void ) const
{
	return m_bCheck;
}

void CheckBox::Update( const Control::UPDATE_EVENT_ARGS& args )
{
	const Mix::Vector2& pos = GetPosition();
	const Mix::Vector2& size = GetSize();

	Float32 fontHeight = static_cast<Float32>( args.pFont->GetHeight() );
	Float32 fontHalfHeight = fontHeight * 0.5f;

	m_Rect.x = args.offset.x + pos.x;
	m_Rect.y = args.offset.y + pos.y;
	m_Rect.width = size.x;
	m_Rect.height = size.y;

	m_BackgroundRect.x = m_Rect.x + 1.0f;
	m_BackgroundRect.y = m_Rect.y + 1.0f;
	m_BackgroundRect.width = m_Rect.width - 2.0f;
	m_BackgroundRect.height = m_Rect.height - 2.0f;

	m_BoxFrameRect.x = m_BackgroundRect.x;
	m_BoxFrameRect.y = m_BackgroundRect.y + ( m_BackgroundRect.height - fontHeight ) * 0.5f;
	m_BoxFrameRect.width = fontHeight;
	m_BoxFrameRect.height = fontHeight;

	m_BoxRect.x = m_BoxFrameRect.x + 1.0f;
	m_BoxRect.y = m_BoxFrameRect.y + 1.0f;
	m_BoxRect.width = m_BoxFrameRect.width - 2.0f;
	m_BoxRect.height = m_BoxFrameRect.height - 2.0f;

	m_CheckRect.x = m_BoxRect.x + ( m_BoxRect.width - fontHalfHeight ) * 0.5f;
	m_CheckRect.y = m_BoxRect.y + ( m_BoxRect.height - fontHalfHeight ) * 0.5f;
	m_CheckRect.width = fontHalfHeight;
	m_CheckRect.height = fontHalfHeight;

	if( m_Text.GetNum() > 0 )
	{
		Mix::Vector2 textSize = Mix::Graphics::Utility::MeasureString( args.pFont, m_Text.GetConstPtr() );

		m_TextRect.x = m_BoxRect.GetRight() + fontHalfHeight;
		m_TextRect.y = m_BackgroundRect.y + 2.0f;
		m_TextRect.width = m_BackgroundRect.width - m_BoxRect.width - 4.0f;
		m_TextRect.height = m_BackgroundRect.height - 4.0f;

		m_TextPos.x = m_TextRect.x;
		m_TextPos.y = ( m_TextRect.height >= textSize.y )? ( m_TextRect.y + ( m_TextRect.height - textSize.y ) * 0.5f ) : m_TextRect.y;
	}
	else
	{
		m_TextPos = Mix::Vector2( 0.0f, 0.0f );
		m_TextRect = Mix::RectangleF( 0.0f, 0.0f, 0.0f, 0.0f );
	}
}

const Mix::RectangleF& CheckBox::GetRectangle( void ) const
{
	return m_Rect;
}

void CheckBox::OnMouseDown( Mix::HID::IMouse* pMouse )
{
	if( m_BoxRect.Contains( pMouse->GetPos() ) == True )
	{
		m_bCheckDown = True;
	}
}

void CheckBox::OnMouseUp( Mix::HID::IMouse* pMouse )
{
	if( ( m_bCheckDown == True ) &&
		( m_BoxRect.Contains( pMouse->GetPos() ) == True ) )
	{
		m_bCheck = ( m_bCheck == True )? False : True;
		m_bCheckDown = False;

		GetParent()->OnCheckBox_Click( this );
	}
}

void CheckBox::OnDraw( const Control::DRAW_EVENT_ARGS& args )
{
	args.pCanvasRenderer->SetColor( args.borderColor );
	args.pCanvasRenderer->AddRectangle( m_BoxFrameRect );

	args.pCanvasRenderer->SetColor( args.backgroundColor );
	args.pCanvasRenderer->AddFillRectangle( m_BoxRect );

	if( m_bCheck == True )
	{
		args.pCanvasRenderer->SetColor( args.textColor );
		args.pCanvasRenderer->AddFillRectangle( m_CheckRect );
	}

	if( m_Text.GetNum() > 0 )
	{
		args.pCanvasRenderer->SetClip( m_TextRect );
		args.pCanvasRenderer->SetColor( args.textColor );
		args.pCanvasRenderer->AddString( m_TextPos, m_Text.GetConstPtr() );
	}
}

}}
