// ------------------------------------------------------------------------
/*
	\author: Jaap Suter
   
	Copyright (C) Electronic Arts Canada Inc. 2002.  All rights reserved.	
*/
// ------------------------------------------------------------------------

/*! \file */

#include "reveal/impl/indexed_check_box_control.h"
#include "reveal/impl/gui_metrics.h"
#include "reveal/gui_colors.h"

#include "reveal/input_state.h"
#include "reveal/renderer.h"

#include "reveal/impl/menu.h"
#include "reveal/impl/util.h"

#include "reveal/impl/tree.h"

namespace Reveal {
	namespace Impl {

		// -------------------------------------------------------------------------------
		void IndexedCheckBoxControl::DoRender( const Renderer& renderer, const GuiColors& guiColors ) const
		{
			Reveal::uint32_t bgColor= guiColors.mWidgetBackgroundColor;
			if ( GetTree().GetWidgetWithFocus() && GetTree().GetWidgetWithFocus()->Parent() == Parent() ) bgColor= guiColors.mWidgetSameLevelBackgroundColor;
			if ( HasFocus() ) bgColor= guiColors.mWidgetHighlightedBackgroundColor;

			renderer.Bar( X(), Y(), Width(), Height(), bgColor );
			renderer.String( X() + GuiMetrics::TEXT_BORDER_WIDTH, Y() + GuiMetrics::TEXT_BORDER_HEIGHT, Name(), guiColors.mTextColor );

			int xCheckBox = X() + Width() - GuiMetrics::GetItemSize() - GuiMetrics::BORDER_WIDTH;
			int yCheckBox = Y() + GuiMetrics::BORDER_HEIGHT;

			renderer.Bar( xCheckBox, yCheckBox, GuiMetrics::GetItemSize(), GuiMetrics::GetItemSize(), guiColors.mInteractiveBackgroundColor );

			if ( mValue )
			{
				renderer.Line( xCheckBox, yCheckBox, xCheckBox + GuiMetrics::GetItemSize(), yCheckBox + GuiMetrics::GetItemSize(), guiColors.mInteractiveForegroundColor );
				renderer.Line( xCheckBox + GuiMetrics::GetItemSize(), yCheckBox, xCheckBox, yCheckBox + GuiMetrics::GetItemSize(), guiColors.mInteractiveForegroundColor );
			}

			DrawBorder( renderer, guiColors );
		}

		// -------------------------------------------------------------------------------
		Widget* IndexedCheckBoxControl::DoHandle( const InputState& inputState )
		{ 
			Widget* widgetThatHandledTheInput = NULL;

			if (  mCallbackFromGame.Valid() ) mValue = mCallbackFromGame(mIndex);

			if ( HasFocus() )
			{
				widgetThatHandledTheInput = this;

				if ( inputState.Released( InputState::CONFIRM | InputState::LEFT_MOUSE ) ) 
				{
					mValue = !mValue;
					mCallbackToGame( mIndex, mValue );
					MakeParentMostRecentlyUsed();
				}
				else
					if ( inputState.Released( InputState::DOWN ) ) 
					{
						if ( Parent() ) widgetThatHandledTheInput = Parent()->GiveFocusToNextWidget( this );
					}
					else
						if ( inputState.Released( InputState::UP ) ) 
						{					
							if ( Parent() ) widgetThatHandledTheInput = Parent()->GiveFocusToPrevWidget( this );
						}
						else
							if ( inputState.Released( InputState::BACK | InputState::LEFT ) ) 
							{					
								widgetThatHandledTheInput = GiveFocusToParent();
							}
			}

			return widgetThatHandledTheInput;
		}

		// -------------------------------------------------------------------------------
		size_t IndexedCheckBoxControl::DoToString( const char* path, char* buffer, size_t size ) const
		{
			const size_t pathAndNameLength = PathAndNameToString( path, buffer, size );
			assert( size >= pathAndNameLength );
			size -= pathAndNameLength; 
			buffer += pathAndNameLength;	

			if ( size >= 1 )
			{
				*buffer++ = '\"';
				--size;
			}
			else return pathAndNameLength;

			const size_t valueLength = Util::ToString( mValue, buffer, size );
			assert( size >= valueLength );
			size -= valueLength;
			buffer += valueLength;

			if ( size >= 1 )
			{
				*buffer++ = '\"';
				--size;
			} else return valueLength + pathAndNameLength + 1;

			*buffer = '\n';

			return pathAndNameLength + valueLength + 3;
		}

// -------------------------------------------------------------------------------
void IndexedCheckBoxControl::Update()
{
	if (  mCallbackFromGame.Valid() ) mValue = mCallbackFromGame(mIndex);
}

// -------------------------------------------------------------------------------

	} // Namespace Impl;
} // Namespace Reveal;

