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

namespace Utility{ namespace UI {

const Float32 Color::TILE_SIZE = 8.0f;

Color::Color( void ) :
m_bAlphaEnabled( True ),
m_Value( 1.0f, 1.0f, 1.0f, 1.0f )
{
}

Color::~Color( void )
{
}

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

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

void Color::SetAlphaEnabled( Boolean state )
{
	m_bAlphaEnabled = state;
}

Boolean Color::GetAlphaEnabled( void ) const
{
	return m_bAlphaEnabled;
}

void Color::SetValue( const Mix::Vector4& value )
{
	Mix::Vector4 preValue = m_Value;
	Utility::UI::Dialog* pParent = GetParent();

	m_Value = value.ToSaturate();

	if( ( pParent != NULL ) &&
		( m_Value != preValue ) )
	{
		pParent->OnColor_ValueChanged( this );
	}
}

const Mix::Vector4& Color::GetValue( void ) const
{
	return m_Value;
}

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

	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;

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

		m_TextRect.x = m_BackgroundRect.x + 2.0f;
		m_TextRect.y = m_BackgroundRect.y + 2.0f;
		m_TextRect.width = m_BackgroundRect.width - 4.0f;
		m_TextRect.height = m_BackgroundRect.height - 4.0f;

		m_TextPos.x = ( m_TextRect.width >= textSize.x )? ( m_TextRect.x + ( m_TextRect.width - textSize.x ) * 0.5f ) : 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& Color::GetRectangle( void ) const
{
	return m_Rect;
}

void Color::OnDraw( const Control::DRAW_EVENT_ARGS& args )
{
	Mix::Vector4 color;

	args.pCanvasRenderer->SetColor( args.borderColor );
	args.pCanvasRenderer->AddRectangle( m_Rect );

	if( m_bAlphaEnabled == True )
	{
		Int32 xCount = static_cast<Int32>( m_BackgroundRect.width / Color::TILE_SIZE ) + 1;
		Int32 yCount = static_cast<Int32>( m_BackgroundRect.height / Color::TILE_SIZE ) + 1;

		Mix::RectangleF rect( 0.0f, 0.0f, Color::TILE_SIZE, Color::TILE_SIZE );

		args.pCanvasRenderer->PushClip();
		args.pCanvasRenderer->SetClip( m_BackgroundRect );

		for( Int32 y = 0; y < yCount; y++ )
		{
			Int32 elmIndex = y % 2;

			rect.y = m_BackgroundRect.y + Color::TILE_SIZE * static_cast<Float32>( y );

			for( Int32 x = 0; x < xCount; x++ )
			{
				Float32 elm = static_cast<Float32>( elmIndex % 2 );
				Mix::Vector4 color = Mix::Vector4( elm, elm, elm, 1.0f ) * args.backgroundColor;

				rect.x = m_BackgroundRect.x + Color::TILE_SIZE * static_cast<Float32>( x );

				args.pCanvasRenderer->SetColor( color );
				args.pCanvasRenderer->AddFillRectangle( rect );

				elmIndex++;
			}
		}

		args.pCanvasRenderer->PopClip();

		color = m_Value;
	}
	else
	{
		color = m_Value;
		color.a = 1.0f;
	}

	args.pCanvasRenderer->SetColor( color );
	args.pCanvasRenderer->AddFillRectangle( m_BackgroundRect );

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

}}
