// Asura_Xbox360_Profile_GUIMenu.cpp
// Thomas Young - 13.10.08
// Copyright (C) 2008 Rebellion, All Rights Reserved.

// I N C L U D E S ///////////////////////////////////////////////////////////

#include "Core/Asura.h"

#include "ChunkSystem/Asura_Chunk_Loaders.h"
#include "Core/Asura_LocalisedText.h"
#include "Core/Asura_HashedLocalisedText.h"
#include "GUIMenu/Asura_GUIMenu_System.h"
#include "GUIMenu/Asura_GuiMenu_Menu_Page.h"
#include "GUIMenu/Asura_GUIMenu_MessagePump.h"
#include "GUIMenu/Asura_GUIMenu_Element_Text.h"
#include "GUIMenu/Asura_GUIMenu_Widget_Base.h"
#include "Rendering/Asura_Viewport.h"

#include "Core/Asura_Xbox360_Profile_System.h"
#include "GUIMenu/Asura_Xbox360_Profile_GUIMenu.h"

// S T A T I C   M E M B E R   V A R I A B L E S /////////////////////////////

Asura_Xbox360_Profile_State				Asura_Xbox360_Profile_GUIMenu::s_eSystemState	= ASURA_XBOX360_PROFILE_STATE_IDLE;
Asura_Xbox360_Profile_Error_State		Asura_Xbox360_Profile_GUIMenu::s_eErrorState	= ASURA_XBOX360_PROFILE_ERROR_NONE;
Asura_Xbox360_Profile_Query_State		Asura_Xbox360_Profile_GUIMenu::s_eQueryState	= ASURA_XBOX360_PROFILE_QUERY_NONE;

Asura_Xbox360_Profile_GUIMenu_Function	Asura_Xbox360_Profile_GUIMenu::s_apfnCallbacks	[ ASURA_XBOX360_PROFILE_GUIMENU_NUM_CALLBACKS ];

bool									Asura_Xbox360_Profile_GUIMenu::s_bPaused		= false;
bool									Asura_Xbox360_Profile_GUIMenu::s_bReturnToStart	= false;

// S T R U C T U R E S ///////////////////////////////////////////////////////

struct QueryResponseButtonLookup
{
	Asura_Xbox360_Profile_Query_State		eQueryState;
	int										iButton;
	Asura_Xbox360_Profile_QueryResponse		eQueryResponse;
};

struct ErrorTextLookup
{
	Asura_Xbox360_Profile_Error_State	eErrorState;
	Asura_Hash_ID						uTitleText;
	Asura_Hash_ID						uMainText;
};

// G L O B A L   V A R I A B L E S ///////////////////////////////////////////

//TODO: Prehash all of these strings

// GUIMenu constants

static Asura_Hash_ID g_uMenuPage					= Asura_GetHashID( "Xbox360_System_Page" );

static const Asura_Hash_ID g_uImage_Background		= Asura_GetHashID( "Image_Background" );
static const Asura_Hash_ID g_uImage_Animator		= Asura_GetHashID( "Image_Animator" );
static const Asura_Hash_ID g_uTextbox_Title			= Asura_GetHashID( "Textbox_Title" );
static const Asura_Hash_ID g_uTextbox_Main			= Asura_GetHashID( "Textbox_Main" );
static const Asura_Hash_ID g_uButton_1_FullHash		= Asura_GetHashID( "Button_1" );
static const Asura_Hash_ID g_uButton_1				= Asura_GetHashID( "Button_1" );
static const Asura_Hash_ID g_uButton_2				= Asura_GetHashID( "Button_2" );
static const Asura_Hash_ID g_uButton_3				= Asura_GetHashID( "Button_3" );
static const Asura_Hash_ID g_uText					= Asura_GetHashID( "Text" );

// Text constants

static const Asura_Hash_ID uMENU_TEXT_PAGE					= Asura_GetHashID( "Xbox360_System" );

static const Asura_Hash_ID g_uTXT_Common_Yes = Asura_GetHashID( "Common_Yes" );
static const Asura_Hash_ID g_uTXT_Common_No = Asura_GetHashID( "Common_No" );
static const Asura_Hash_ID g_uTXT_Common_Continue = Asura_GetHashID( "Common_Continue" );
static const Asura_Hash_ID g_uTXT_Title_Processing = Asura_GetHashID( "Title_Processing" );
static const Asura_Hash_ID g_uTXT_Title_Loading = Asura_GetHashID( "Title_Loading" );
static const Asura_Hash_ID g_uTXT_Title_Saving = Asura_GetHashID( "Title_Saving" );
static const Asura_Hash_ID g_uTXT_Title_DeviceError = Asura_GetHashID( "Title_DeviceError" );
static const Asura_Hash_ID g_uTXT_Title_NoDevice = Asura_GetHashID( "Title_NoDevice" );
static const Asura_Hash_ID g_uTXT_Title_NoProfile = Asura_GetHashID( "Title_NoProfile" );
static const Asura_Hash_ID g_uTXT_Title_CorruptData = Asura_GetHashID( "Title_CorruptData" );
static const Asura_Hash_ID g_uTXT_Title_AccessDenied = Asura_GetHashID( "Title_AccessDenied" );
static const Asura_Hash_ID g_uTXT_Title_Logout = Asura_GetHashID( "Title_Logout" );
static const Asura_Hash_ID g_uTXT_Title_DeviceRemoved = Asura_GetHashID( "Title_DeviceRemoved" );
static const Asura_Hash_ID g_uTXT_Query_SelectDevice = Asura_GetHashID( "Query_SelectDevice" );
static const Asura_Hash_ID g_uTXT_Query_Corrupt = Asura_GetHashID( "Query_Corrupt" );
static const Asura_Hash_ID g_uTXT_Error_NoDevice = Asura_GetHashID( "Error_NoDevice" );
static const Asura_Hash_ID g_uTXT_Error_NoUser = Asura_GetHashID( "Error_NoUser" );
static const Asura_Hash_ID g_uTXT_Error_DeviceFailure = Asura_GetHashID( "Error_DeviceFailure" );
static const Asura_Hash_ID g_uTXT_Error_Corrupt = Asura_GetHashID( "Error_Corrupt" );
static const Asura_Hash_ID g_uTXT_Error_WrongUser = Asura_GetHashID( "Error_WrongUser" );
static const Asura_Hash_ID g_uTXT_Error_Logout = Asura_GetHashID( "Error_Logout" );
static const Asura_Hash_ID g_uTXT_Error_DeviceRemoved = Asura_GetHashID( "Error_DeviceRemoved" );
static const Asura_Hash_ID g_uTXT_Button_Overwrite = Asura_GetHashID( "Button_Overwrite" );
static const Asura_Hash_ID g_uTXT_Button_SelectDevice = Asura_GetHashID( "Button_SelectDevice" );
static const Asura_Hash_ID g_uTXT_Button_Ignore = Asura_GetHashID( "Button_Ignore" );

															   
// Make a lookup table of button presses -> responses provided to the profile system

static const QueryResponseButtonLookup g_axResponseLookup[] = {	{	ASURA_XBOX360_PROFILE_QUERY_DEVICE_SELECT	, 1, ASURA_XBOX360_PROFILE_QUERY_DEVICE_SELECT_YES		},
																{	ASURA_XBOX360_PROFILE_QUERY_DEVICE_SELECT	, 2, ASURA_XBOX360_PROFILE_QUERY_DEVICE_SELECT_NO		},
																{	ASURA_XBOX360_PROFILE_QUERY_CORRUPT			, 1, ASURA_XBOX360_PROFILE_QUERY_CORRUPT_OVERWRITE		},
																{	ASURA_XBOX360_PROFILE_QUERY_CORRUPT			, 2, ASURA_XBOX360_PROFILE_QUERY_CORRUPT_SELECT_DEVICE	},
																{	ASURA_XBOX360_PROFILE_QUERY_CORRUPT			, 3, ASURA_XBOX360_PROFILE_QUERY_CORRUPT_IGNORE			},
																{	ASURA_XBOX360_PROFILE_QUERY_NONE			, 0, ASURA_XBOX360_PROFILE_QUERY_RESPONSE_NONE			}	};


// Make a lookup table of Error codes -> Error Text

static const ErrorTextLookup g_axErrorTextLookup[] =  {	{	ASURA_XBOX360_PROFILE_ERROR_NO_PROFILE_SELECTED		, g_uTXT_Title_NoProfile		, g_uTXT_Error_NoUser			},
														{	ASURA_XBOX360_PROFILE_ERROR_NO_DEVICE_SELECTED		, g_uTXT_Title_NoDevice			, g_uTXT_Error_NoDevice			},
														{	ASURA_XBOX360_PROFILE_ERROR_GENERIC_DEVICE_FAILURE	, g_uTXT_Title_DeviceError		, g_uTXT_Error_DeviceFailure	},
														{	ASURA_XBOX360_PROFILE_ERROR_CORRUPT					, g_uTXT_Title_CorruptData		, g_uTXT_Error_Corrupt			},
														{	ASURA_XBOX360_PROFILE_ERROR_WRONG_USER				, g_uTXT_Title_AccessDenied		, g_uTXT_Error_WrongUser		},
														{	ASURA_XBOX360_PROFILE_ERROR_LOGOUT					, g_uTXT_Title_Logout			, g_uTXT_Error_Logout			},
														{	ASURA_XBOX360_PROFILE_ERROR_DEVICE_REMOVED			, g_uTXT_Title_DeviceRemoved	, g_uTXT_Error_DeviceRemoved	},
														{	ASURA_XBOX360_PROFILE_ERROR_NONE					, ASURA_HASH_ID_UNSET			, ASURA_HASH_ID_UNSET			}	};

// F U N C T I O N   D E F I N I T I O N S ///////////////////////////////////

void Asura_Xbox360_Profile_GUIMenu::Initialise ( const char* const szMenuPage )
{
	if( szMenuPage )
	{
		g_uMenuPage = Asura_GetHashID( szMenuPage );
	}

	for( int iFunc = 0; iFunc < ASURA_XBOX360_PROFILE_GUIMENU_NUM_CALLBACKS; ++iFunc )
	{
		s_apfnCallbacks[ iFunc ] = 0;
	}

	s_bPaused			= false;
	s_bReturnToStart	= false;

	Asura_CommandConsole::AddCmd( L"Xbox360_System.ButtonPress", ConsoleCmd_Button, Asura_CommandConsole::REMOVE_AT_SHUTDOWN );
}


void Asura_Xbox360_Profile_GUIMenu::Update ()
{
	Asura_Xbox360_Profile_State			eSystemState;
	Asura_Xbox360_Profile_Query_State	eQueryState;
	Asura_Xbox360_Profile_Error_State	eErrorState;
	
	Asura_Xbox360_Profile_System::GetFullState( eSystemState, eQueryState, eErrorState );
	
	if( !StateHasChanged( eSystemState, eQueryState, eErrorState ) )
	{
		return;
	}

	s_eSystemState	= eSystemState;
	s_eQueryState	= eQueryState;
	s_eErrorState	= eErrorState;
		
	switch( s_eSystemState )
	{
		case ASURA_XBOX360_PROFILE_STATE_IDLE:
		{
			// The profile system is doing nothing, check if we need to close the menu
			if( Asura_GUIMenu_System::IsMenuPageHashActive( g_uMenuPage ) )
			{
				Asura_GUIMenu_System::CloseMenuPage( g_uMenuPage );
				// Restore the menu ordering, this could have been affected by the opening of our menu
				Asura_GUIMenu_Menu_Page* pxMenuPage = Asura_GUIMenu_System::GetMenuPageByID( g_uMenuPage );
				if( pxMenuPage )
				{
					Asura_GUIMenu_System::SetFocusedMenuByID( pxMenuPage->GetBackMenuHash() );
				}
			}
			if( s_bPaused )
			{
				Callback( ASURA_XBOX360_PROFILE_GUIMENU_CALLBACK_UNPAUSE );
			}
			if( s_bReturnToStart )
			{
				Callback( ASURA_XBOX360_PROFILE_GUIMENU_CALLBACK_RETURN_TO_START );
			}
		}
		break;

		case ASURA_XBOX360_PROFILE_STATE_PROCESSING:
		case ASURA_XBOX360_PROFILE_STATE_LOAD_PROFILE:
		case ASURA_XBOX360_PROFILE_STATE_SAVE_PROFILE:
		{
			if( !Asura_GUIMenu_System::IsMenuPageHashActive( g_uMenuPage ) )
			{
				Asura_GUIMenu_System::OpenMenuPage( g_uMenuPage, true, true );
			}

			Asura_GUIMenu_System::Update();

			HideAllWidgets();

			SetWidgetVisible	( g_uImage_Background	, true );
			SetWidgetVisible	( g_uImage_Animator		, true );
			SetWidgetVisible	( g_uTextbox_Title		, true );
			
			const float fAspectRatio = static_cast<float>( Asura_Viewport::GetHeight() ) / static_cast<float>( Asura_Viewport::GetWidth() );

			SetWidgetPosition	( g_uImage_Background	, 0.00f, 0.00f, 1.00f, 1.00f );
			SetWidgetPosition	( g_uTextbox_Title		, 0.65f, 0.65f, 0.95f, 1.00f );
			SetWidgetPosition	( g_uImage_Animator		, 0.55f, 0.60f, 0.55f + 0.10f * fAspectRatio, 0.70f );

			switch( s_eSystemState )
			{
				case ASURA_XBOX360_PROFILE_STATE_PROCESSING:	SetWidgetText ( g_uTextbox_Title, g_uTXT_Title_Processing);	break;
				case ASURA_XBOX360_PROFILE_STATE_LOAD_PROFILE:	SetWidgetText ( g_uTextbox_Title, g_uTXT_Title_Loading	);	break;
				case ASURA_XBOX360_PROFILE_STATE_SAVE_PROFILE:	SetWidgetText ( g_uTextbox_Title, g_uTXT_Title_Saving	);	break;
			}
		}
		break;

		case ASURA_XBOX360_PROFILE_STATE_ERROR:
		{
			// Format our menu page for a standard error message

			if( !Asura_GUIMenu_System::IsMenuPageHashActive( g_uMenuPage ) )
			{
				Asura_GUIMenu_System::OpenMenuPage( g_uMenuPage, true, true );
			}
			
			Asura_GUIMenu_System::Update();

			// Show a simple waiting screen for these states
			HideAllWidgets();

			SetWidgetVisible	( g_uImage_Background	, true );
			SetWidgetVisible	( g_uTextbox_Title		, true );
			SetWidgetVisible	( g_uTextbox_Main		, true );
			SetWidgetVisible	( g_uButton_1			, true );

			UpdateButtonNavLinks();

			// Set the focus to button 1
			Asura_GUIMenu_MessagePump::PostMessage( GetWidgetGUIMenuID( g_uButton_1 ), GetWidgetGUIMenuID( g_uMenuPage ), ASURA_GUIMENU_UI_MSG_ON_ROLL_IN, 0);
			Asura_GUIMenu_MessagePump::PostMessage( GetWidgetGUIMenuID( g_uMenuPage ), GetWidgetGUIMenuID( g_uMenuPage ), ASURA_GUIMENU_UI_MSG_ON_ROLL_OUT, 0);

			SetWidgetPosition	( g_uImage_Background	, 0.00f, 0.00f, 1.00f, 1.00f );
			SetWidgetPosition	( g_uTextbox_Title		, 0.20f, 0.25f, 0.70f, 0.40f );
			SetWidgetPosition	( g_uTextbox_Main		, 0.20f, 0.40f, 0.70f, 0.60f );
			SetWidgetPosition	( g_uButton_1			, 0.40f, 0.70f, 0.60f, 0.80f );
			
			SetPageTextForError( s_eErrorState );

			if( !s_bPaused )
			{
				Callback( ASURA_XBOX360_PROFILE_GUIMENU_CALLBACK_PAUSE );
				s_bPaused = true;
			}
			if( s_eErrorState == ASURA_XBOX360_PROFILE_ERROR_LOGOUT )
			{
				// If the user has logged out we should return to the start screen once the error is cleared
				s_bReturnToStart = true;
			}
		}
		break;
		
		case ASURA_XBOX360_PROFILE_STATE_QUERY:
		{
			// Format our menu page for a standard query

			if( !Asura_GUIMenu_System::IsMenuPageHashActive( g_uMenuPage ) )
			{
				Asura_GUIMenu_System::OpenMenuPage( g_uMenuPage, true, true );
			}

			Asura_GUIMenu_System::Update();

			// Show a simple waiting screen for these states
			HideAllWidgets();

			SetWidgetVisible	( g_uImage_Background	, true );
			SetWidgetVisible	( g_uTextbox_Title		, true );
			SetWidgetVisible	( g_uTextbox_Main		, true );

			SetWidgetPosition	( g_uImage_Background	, 0.00f, 0.00f, 1.00f, 1.00f );
			SetWidgetPosition	( g_uTextbox_Title		, 0.20f, 0.25f, 0.70f, 0.40f );
			SetWidgetPosition	( g_uTextbox_Main		, 0.20f, 0.40f, 0.70f, 0.60f );
			SetWidgetPosition	( g_uButton_1			, 0.40f, 0.70f, 0.60f, 0.80f );
			SetWidgetPosition	( g_uButton_2			, 0.40f, 0.80f, 0.60f, 0.90f );
			SetWidgetPosition	( g_uButton_3			, 0.40f, 0.90f, 0.60f, 1.00f );

			ConfigurePageForQuery( s_eQueryState );

			// Set the focus to button 1
			Asura_GUIMenu_MessagePump::PostMessage( GetWidgetGUIMenuID( g_uButton_1 ), GetWidgetGUIMenuID( g_uMenuPage ), ASURA_GUIMENU_UI_MSG_ON_ROLL_IN, 0);
			Asura_GUIMenu_MessagePump::PostMessage( GetWidgetGUIMenuID( g_uMenuPage ), GetWidgetGUIMenuID( g_uMenuPage ), ASURA_GUIMENU_UI_MSG_ON_ROLL_OUT, 0);

			if( !s_bPaused )
			{
				Callback( ASURA_XBOX360_PROFILE_GUIMENU_CALLBACK_PAUSE );
				s_bPaused = true;
			}
		}
		break;

		case ASURA_XBOX360_PROFILE_STATE_SAVE_CHECKPOINT:
		case ASURA_XBOX360_PROFILE_STATE_LOAD_CHECKPOINT:
		default:
		{
			// We aren't really interested in these cases, we could in theory show the
			// animator but in reality the project will be dealing with this already
		}
		break;
	}
}


void Asura_Xbox360_Profile_GUIMenu::Shutdown ()
{
	s_eSystemState	= ASURA_XBOX360_PROFILE_STATE_IDLE;
	s_eErrorState	= ASURA_XBOX360_PROFILE_ERROR_NONE;
	s_eQueryState	= ASURA_XBOX360_PROFILE_QUERY_NONE;
}


bool Asura_Xbox360_Profile_GUIMenu::StateHasChanged ( const Asura_Xbox360_Profile_State			eSystemState
													, const Asura_Xbox360_Profile_Query_State	eQueryState 
													, const Asura_Xbox360_Profile_Error_State	eErrorState	)
{
	// Check our state last frame against this frame
	
	bool bChanged = false;

	if( eSystemState != s_eSystemState )
	{
		bChanged = true;
	}
	else
	{
		switch( eSystemState )
		{
			case ASURA_XBOX360_PROFILE_STATE_ERROR:
			{
				if( eErrorState != s_eErrorState )
				{
					bChanged = true;
				}
			}
			break;

			case ASURA_XBOX360_PROFILE_STATE_QUERY:
			{
				if( eQueryState != s_eQueryState )
				{
					bChanged = true;
				}
			}
			break;
		}
	}
	
	return bChanged;
}

void Asura_Xbox360_Profile_GUIMenu::HideAllWidgets ()
{
	SetWidgetVisible( g_uImage_Background	, false );
	SetWidgetVisible( g_uImage_Animator		, false );
	SetWidgetVisible( g_uTextbox_Title		, false );
	SetWidgetVisible( g_uTextbox_Main		, false );
	SetWidgetVisible( g_uButton_1			, false );
	SetWidgetVisible( g_uButton_2			, false );
	SetWidgetVisible( g_uButton_3			, false );
}

void Asura_Xbox360_Profile_GUIMenu::SetWidgetVisible ( const Asura_Hash_ID uWidget, const bool bVisible )
{
	Asura_GUIMenu_Menu_Page* pxMenuPage = Asura_GUIMenu_System::GetMenuPageByID( g_uMenuPage );
	if( !pxMenuPage )
	{
		return;
	}
	Asura_GUIMenu_Root* pxRootObject = pxMenuPage->FindContainerItemByLocalNameHash( uWidget );
	
	if( pxRootObject )
	{
		if( !bVisible )
		{
			pxRootObject->SetRenderingDisabledFlag( true );
		}
		else
		{
			pxRootObject->SetRenderingDisabledFlag( pxRootObject->IsHiddenByConditionVar() );
		}
	}
}


void Asura_Xbox360_Profile_GUIMenu::SetWidgetText ( const Asura_Hash_ID uContainer, const Asura_Hash_ID uTextID )
{
	Asura_GUIMenu_Menu_Page* pxMenuPage = Asura_GUIMenu_System::GetMenuPageByID( g_uMenuPage );
	if( pxMenuPage )
	{
		Asura_GUIMenu_Root* pxRootObject = pxMenuPage->FindContainerItemByLocalNameHash( uContainer );
		if( pxRootObject )
		{
			Asura_GUIMenu_Element_Text* pxTextElement = reinterpret_cast<Asura_GUIMenu_Element_Text*>( pxRootObject->FindContainerItemByLocalNameHash( g_uText ) );

			if( pxTextElement )
			{
				pxTextElement->SetTextPageHash	( uMENU_TEXT_PAGE );
				pxTextElement->SetTextID		( uTextID );
			}
		}
	}
}

void Asura_Xbox360_Profile_GUIMenu::SetWidgetPosition ( const Asura_Hash_ID uContainer, const float fX1, const float fY1, const float fX2, const float fY2 )
{
	Asura_GUIMenu_Menu_Page* pxMenuPage = Asura_GUIMenu_System::GetMenuPageByID( g_uMenuPage );
	if( pxMenuPage )
	{
		Asura_GUIMenu_Root* pxRootObject = pxMenuPage->FindContainerItemByLocalNameHash( uContainer );
		if( pxRootObject )
		{
			// Convert our normalised coordinates to the screen space

			Asura_Bounding_Rectangle xBounds;
			xBounds.Set	( fX1 * Asura_Viewport::GetWidth ()
						, fY1 * Asura_Viewport::GetHeight()
						, fX2 * Asura_Viewport::GetWidth ()
						, fY2 * Asura_Viewport::GetHeight() );

			pxRootObject->Resize( xBounds );
		}
	}
}


void Asura_Xbox360_Profile_GUIMenu::ConfigurePageForQuery ( const Asura_Xbox360_Profile_Query_State eState )
{
	switch( eState )
	{
		case ASURA_XBOX360_PROFILE_QUERY_DEVICE_SELECT:
		{
			SetWidgetText ( g_uTextbox_Title,	g_uTXT_Title_DeviceError );
			SetWidgetText ( g_uTextbox_Main,	g_uTXT_Query_SelectDevice );

			SetWidgetVisible ( g_uButton_1, true );
			SetWidgetVisible ( g_uButton_2, true );

			SetWidgetText ( g_uButton_1, g_uTXT_Common_Yes );
			SetWidgetText ( g_uButton_2, g_uTXT_Common_No  );
		}
		break;

		case ASURA_XBOX360_PROFILE_QUERY_CORRUPT:
		{
			SetWidgetText ( g_uTextbox_Title,	g_uTXT_Title_CorruptData	);
			SetWidgetText ( g_uTextbox_Main,	g_uTXT_Query_Corrupt		);

			SetWidgetVisible ( g_uButton_1, true );
			SetWidgetVisible ( g_uButton_2, true );
			SetWidgetVisible ( g_uButton_3, true );

			SetWidgetText ( g_uButton_1, g_uTXT_Button_Overwrite	);
			SetWidgetText ( g_uButton_2, g_uTXT_Button_SelectDevice	);
			SetWidgetText ( g_uButton_3, g_uTXT_Button_Ignore		);
		}
		break;

		default:
		{
			Asura_Assert( false, "Unknown query state" );
		}
	}

	UpdateButtonNavLinks();
}


void Asura_Xbox360_Profile_GUIMenu::SetPageTextForError ( const Asura_Xbox360_Profile_Error_State eState )
{
	SetWidgetText ( g_uButton_1, g_uTXT_Common_Continue );

	int iEntry = 0;

	// Find this error code in our error text lookup table

	while( g_axErrorTextLookup[ iEntry ].eErrorState != ASURA_XBOX360_PROFILE_ERROR_NONE )
	{
		if( g_axErrorTextLookup[ iEntry ].eErrorState == eState )
		{
			SetWidgetText ( g_uTextbox_Title,	g_axErrorTextLookup[ iEntry ].uTitleText	);
			SetWidgetText ( g_uTextbox_Main,	g_axErrorTextLookup[ iEntry ].uMainText		);
			return;
		}
		++iEntry;
	}
	Asura_Assert( false, "Failed to find error code in lookup table" );
}


bool Asura_Xbox360_Profile_GUIMenu::ConsoleCmd_Button ( int iButton, bool bInterrogate, bool bHelp )
{
	switch( s_eSystemState )
	{
		case ASURA_XBOX360_PROFILE_STATE_ERROR:
		{
			// There is only one button on the error page, and it clears the error
			Asura_Xbox360_Profile_System::ClearErrorState ();
		}
		break;

		case ASURA_XBOX360_PROFILE_STATE_QUERY:
		{
			// Look up this button press in our lookup table
			int iEntry = 0;
			Asura_Xbox360_Profile_QueryResponse eResponse = ASURA_XBOX360_PROFILE_QUERY_RESPONSE_NONE;

			while( g_axResponseLookup[ iEntry ].eQueryState != ASURA_XBOX360_PROFILE_QUERY_NONE )
			{
				if( ( g_axResponseLookup[ iEntry ].eQueryState	== s_eQueryState	) &&
					( g_axResponseLookup[ iEntry ].iButton		== iButton			) )
				{
					eResponse = g_axResponseLookup[ iEntry ].eQueryResponse;
					break;
				}
				++iEntry;
			}
			Asura_Assert( eResponse != ASURA_XBOX360_PROFILE_QUERY_RESPONSE_NONE, "Failed to find button press in lookup table" );
			if( eResponse != ASURA_XBOX360_PROFILE_QUERY_RESPONSE_NONE )
			{
				// Pass the response to the profile system
				Asura_Xbox360_Profile_System::SetQueryResponse( eResponse );
			}
		}
		break;

		default:
		{
			Asura_Assert( false, "Did not expect a button press at this time" );
		}
	}

	return true;
}


bool Asura_Xbox360_Profile_GUIMenu::LoadResources ()
{
	// Load the GUI Menu page

	if(! Asura_ChunkLoading_System::LoadAsuraFile( "GUIMenu\\Xbox360_System." ASURA_GUIMENU_STANDARD_FILE_EXTENSION ) )
	{
		Asura_Assert( false, "Failed to find guimenu file 'Xbox360_System'" );
		return false;
	}

	// Load the localised text page

	char szTextFile[MAX_PATH];

	Asura_PrintfToBfr( szTextFile, "%s%s%s%s", MAX_PATH, true, "Misc\\Xbox360_System\\Xbox360_System_", Asura_LocalisedText::GetTwoCharCodeForCurLang(), "." , ASURA_STANDARD_FILE_EXTENSION_BE );

	if(! Asura_ChunkLoading_System::LoadAsuraFile( szTextFile ) )
	{
		Asura_Assert( false, ( "Failed to find localised text file %s", szTextFile ) );
		return false;
	}

	#ifdef ASURA_ASSERT
	ValidateResources();
	#endif

	return true;
}


#ifdef ASURA_ASSERT
void Asura_Xbox360_Profile_GUIMenu::ValidateResources ()
{
	//Do a load of checks to see that we have been provided with an appropriately configured GUIMenu page

	if( Asura_GUIMenu_System::DoesMenuPageExist( g_uMenuPage ) )
	{
		Asura_GUIMenu_Menu_Page* pxMenuPage = Asura_GUIMenu_System::GetMenuPageByID( g_uMenuPage );
		Asura_GUIMenu_Root* pxRootObject;

		// Images
		Asura_Assert( pxMenuPage->FindContainerItemByLocalNameHash( g_uImage_Background )	!= 0, "Missing widget on profile menu page: Image_Background" );
		Asura_Assert( pxMenuPage->FindContainerItemByLocalNameHash( g_uImage_Animator )	!= 0, "Missing widget on profile menu page: Image_Animator" );

		// Title text box
		pxRootObject = pxMenuPage->FindContainerItemByLocalNameHash( g_uTextbox_Title );
		if( pxRootObject )
		{
			pxRootObject = pxRootObject->FindContainerItemByLocalNameHash( g_uText );
			Asura_Assert( pxRootObject, " Missing widget on profile menu page: Textbox_Title -> Text" );
		}
		else
		{
			Asura_Assert( false, "Missing container on profile menu page: Textbox_Title" );
		}

		// Main text box
		pxRootObject = pxMenuPage->FindContainerItemByLocalNameHash( g_uTextbox_Main );
		if( pxRootObject )
		{
			pxRootObject = pxRootObject->FindContainerItemByLocalNameHash( g_uText );
			Asura_Assert( pxRootObject, " Missing widget on profile menu page: Textbox_Main -> Text" );
		}
		else
		{
			Asura_Assert( false, "Missing container on profile menu page: Textbox_Main" );
		}

		// Button 1
		pxRootObject = pxMenuPage->FindContainerItemByLocalNameHash( g_uButton_1 );
		if( pxRootObject )
		{
			pxRootObject = pxRootObject->FindContainerItemByLocalNameHash( g_uText );
			Asura_Assert( pxRootObject, " Missing widget on profile menu page: Button_1 -> Text" );
		}
		else
		{
			Asura_Assert( false, "Missing container on profile menu page: Button_1" );
		}

		// Button 2
		pxRootObject = pxMenuPage->FindContainerItemByLocalNameHash( g_uButton_2 );
		if( pxRootObject )
		{
			pxRootObject = pxRootObject->FindContainerItemByLocalNameHash( g_uText );
			Asura_Assert( pxRootObject, " Missing widget on profile menu page: Button_1 -> Text" );
		}
		else
		{
			Asura_Assert( false, "Missing container on profile menu page: Button_1" );
		}

		// Button 3
		pxRootObject = pxMenuPage->FindContainerItemByLocalNameHash( g_uButton_3 );
		if( pxRootObject )
		{
			pxRootObject = pxRootObject->FindContainerItemByLocalNameHash( g_uText );
			Asura_Assert( pxRootObject, " Missing widget on profile menu page: Button_1 -> Text" );
		}
		else
		{
			Asura_Assert( false, "Missing container on profile menu page: Button_1" );
		}
	}
	else
	{
		Asura_Assert( false, "Menu page for the 360 profile system does not exist. You must create a generic menu page for use with this system" );
	}

	// Check the localised text page exists

	const Asura_HashedLocalisedText_Page* pxPage = Asura_HashedLocalisedText::GetPage( uMENU_TEXT_PAGE );
	Asura_Assert( pxPage, "Localised text page does not exist, you must create a localised text page for use with this system" );
}
#endif

inline void Asura_Xbox360_Profile_GUIMenu::Callback ( const ASURA_XBOX360_PROFILE_GUIMENU_CALLBACK eCallbackType )
{
	if( ( eCallbackType < ASURA_XBOX360_PROFILE_GUIMENU_NUM_CALLBACKS ) && ( s_apfnCallbacks[ eCallbackType ] ) )
	{
		( s_apfnCallbacks[ eCallbackType ] )();
	}
}

void Asura_Xbox360_Profile_GUIMenu::RegisterCallback ( const ASURA_XBOX360_PROFILE_GUIMENU_CALLBACK eCallbackType, Asura_Xbox360_Profile_GUIMenu_Function pfnFunction )
{
	if( ( eCallbackType < ASURA_XBOX360_PROFILE_GUIMENU_NUM_CALLBACKS ) )
	{
		s_apfnCallbacks[ eCallbackType ] = pfnFunction;
	}
}

Asura_Hash_ID Asura_Xbox360_Profile_GUIMenu::GetWidgetGUIMenuID ( const Asura_Hash_ID uWidget )
{
	Asura_GUIMenu_Menu_Page* pxMenuPage = Asura_GUIMenu_System::GetMenuPageByID( g_uMenuPage );
	if( pxMenuPage )
	{
		Asura_GUIMenu_Root* pxRootObject = pxMenuPage->FindContainerItemByLocalNameHash( uWidget );
		
		if( pxRootObject )
		{
			return pxRootObject->GetID();
		}
	}
	
	return ASURA_HASH_ID_UNSET;
}

void Asura_Xbox360_Profile_GUIMenu::UpdateButtonNavLinks ( )
{
	// Manually update the nav links for the buttons based on their visiblities

	Asura_GUIMenu_Root* apxButtons[3] = {0};

	Asura_GUIMenu_Menu_Page* pxMenuPage = Asura_GUIMenu_System::GetMenuPageByID( g_uMenuPage );
	if( pxMenuPage )
	{
		apxButtons[0] = pxMenuPage->FindContainerItemByLocalNameHash( g_uButton_1 );
		apxButtons[1] = pxMenuPage->FindContainerItemByLocalNameHash( g_uButton_2 );
		apxButtons[2] = pxMenuPage->FindContainerItemByLocalNameHash( g_uButton_3 );
	}

	if( !apxButtons[0] || !apxButtons[1] || !apxButtons[2] )
	{
		return;
	}

	if( !apxButtons[0]->IsRenderingDisabled() )
	{
		Asura_GUIMenu_Widget_Base* pxBaseItem = reinterpret_cast<Asura_GUIMenu_Widget_Base*>( apxButtons[0] );
		
		Asura_Hash_ID uUp	= ASURA_HASH_ID_UNSET;
		Asura_Hash_ID uDown = apxButtons[1]->IsRenderingDisabled() ? ASURA_HASH_ID_UNSET : apxButtons[1]->GetID();
		
		pxBaseItem->SetNavExitIDs( uUp, uDown );
	}

	if( !apxButtons[1]->IsRenderingDisabled() )
	{
		Asura_GUIMenu_Widget_Base* pxBaseItem = reinterpret_cast<Asura_GUIMenu_Widget_Base*>( apxButtons[1] );

		Asura_Hash_ID uUp	= apxButtons[0]->IsRenderingDisabled() ? ASURA_HASH_ID_UNSET : apxButtons[0]->GetID();
		Asura_Hash_ID uDown = apxButtons[2]->IsRenderingDisabled() ? ASURA_HASH_ID_UNSET : apxButtons[2]->GetID();

		pxBaseItem->SetNavExitIDs( uUp, uDown );
	}

	if( !apxButtons[2]->IsRenderingDisabled() )
	{
		Asura_GUIMenu_Widget_Base* pxBaseItem = reinterpret_cast<Asura_GUIMenu_Widget_Base*>( apxButtons[2] );

		Asura_Hash_ID uUp	= apxButtons[1]->IsRenderingDisabled() ? ASURA_HASH_ID_UNSET : apxButtons[1]->GetID();
		Asura_Hash_ID uDown = ASURA_HASH_ID_UNSET;

		pxBaseItem->SetNavExitIDs( uUp, uDown );
	}
}

//eof
