
//
// SS2_HUD.cpp
//
// Created by SK - 8/11/2007
//
// Copyright (C) 2007 Rebellion, All Rights Reserved.
//
// Platform specific hud code
//

#include "Core/Asura.h"

#include "LoadAndSave/AVP_Platform_SaveState.h"

#include "Core/Asura_HashedLocalisedText.h"
#include "Core/Asura_Timers.h"
#include "GUImenu/Asura_GUIMenu_System.h"
#include "Input/Asura_PlatformInput.h"
#include "Input/Asura_PS3_USBPad.h"
#include "Interface/Asura_CommandConsole.h"
#include "utility/Asura_PS3_MsgBox.h"
#include "utility/Asura_PS3_SaveLoad.h"

AVP_PS3_SaveState::STATE AVP_PS3_SaveState::s_eState = AVP_PS3_SaveState::VOID;
AVP_PS3_SaveState::STATE AVP_PS3_SaveState::s_eNextState = AVP_PS3_SaveState::VOID;
void* AVP_PS3_SaveState::s_pxLastData = 0;
Asura_StaticSaveBlock* AVP_PS3_SaveState::s_pxLastSaveBlock = 0;
u_int AVP_PS3_SaveState::s_uNumProfiles = 0;
AVP_Profile_SaveData AVP_PS3_SaveState::s_xProfileSaveBackup;

Asura_UnicodeChar* g_text = L"lsdfjsldkfj";

bool AVP_PS3_SaveState::Update()
{
	bool bUsingDisplay = false;
	switch( s_eState )
	{
		default:
		{
			// if we dont have a state assert then fall through to idle. 
			Asura_Assert( 0, "AVP_PS3_SaveState::Update\n unhandled ps3 save state" );
		}
		case IDLE:
		{
			switch( s_eNextState )
			{
				case AUTOSAVING:
				{
					if( ! Save(false, s_pxLastData, s_pxLastSaveBlock ) )
					{
						s_eState = IDLE;
						//SS2_PlayerProfile_System::SetLastOperationResult(SS2_PLAYER_PROFILE_RESULT_FAIL);
					}
					break;
				}
				case SAVING:
				{
					if( ! Save(true, s_pxLastData, s_pxLastSaveBlock ) )
					{
						s_eState = IDLE;
						//SS2_PlayerProfile_System::SetLastOperationResult(SS2_PLAYER_PROFILE_RESULT_FAIL);
					}
					break;
				}
				case LOADING:
				{
					if( ! Load(s_pxLastData, s_pxLastSaveBlock ) )
					{
						s_eState = IDLE;
						//SS2_PlayerProfile_System::SetLastOperationResult(SS2_PLAYER_PROFILE_RESULT_FAIL);
					}
					break;
				}
				default:
				{
					break;
				}
			}
			s_eNextState = VOID;
			break;
		}
		case VOID:
		{
			if( Asura_PS3_SaveLoad::CountProfiles() )
			{
				// if a load thread can be created set state to counting for next update
				s_eState = COUNTING;
			}
			else
			{
				// if a load thread can not be created set6 state to IDLE so we try agian in a couple updates. 
				s_eState = IDLE;
			}
			break;
		}
		case SAVING:
		case AUTOSAVING:
		{
			bUsingDisplay = ( s_eState == SAVING ) || ! Asura_PS3_SaveLoad::CanAutosave();

			if( Asura_PS3_SaveLoad::GetStatus() == Asura_PS3_SaveLoad::STATUS_SAVED )
			{
				// if we have finished the save we are int the saving state for then continue with wrapping up the procedure. 
				if( Asura_PS3_SaveLoad::FreeSpaceFailOnLastSave() )
				{
					// if we ran out of space ont he last save we'll need to prompt the user to delete old saves. 
					//if( Asura_PS3_MsgBox::DisplayQuestion( Asura_HashedLocalisedText::GetString( uASURA_HASHEDTEXTPAGE_MENU, 0xa6ac6740 /*"PS3_ASK_DELETE"*/ ), true ) )
					if( Asura_PS3_MsgBox::DisplayQuestion( L"No disk space for save do you want to try again", true ) )
					{
						s_eState = ASKINGDELETE;
					}
					else
					{
						// (NY - 21.02.2008) what to do if we can't ask the question? if we stay in this state, we'll retry ever frame...
						Asura_Assert(0, "AVP_PS3_SaveState::Update\n Unable to ask delete question");
					}
				}
				else if( Asura_PS3_SaveLoad::ErrorOnLastOperation() )
				{
					// if the save failed for any reason ask if user wants to retry the save
					//if( Asura_PS3_MsgBox::DisplayQuestion( Asura_HashedLocalisedText::GetString( uASURA_HASHEDTEXTPAGE_MENU, 0xd2308a70 /*"PS3_ASK_RETRYSAVE"*/), true ) )
					if( Asura_PS3_MsgBox::DisplayQuestion( L"Save Failed, do you want to try again:", true ) )
					{
						s_eState = ASKINGRETRY;
					}
					else
					{
						// (NY - 21.02.2008) what to do if we can't ask the question? if we stay in this state, we'll retry ever frame...
						Asura_Assert( 0, "AVP_PS3_SaveState::Update\n Unable to ask retry save question" );
					}
				}
				else
				{
					// else the save worked or it was cancelled. either way its done so carry on. 
					if( Asura_PS3_SaveLoad::CountProfiles() )
					{
						s_eState = COUNTING;
					}
					else
					{
						s_eState = IDLE;
					}

					//bool bCancelled = Asura_PS3_SaveLoad::LastOperationCanceled();
					//SS2_PlayerProfile_System::SetLastOperationResult(bCancelled?SS2_PLAYER_PROFILE_RESULT_OK_NO_ACTION:SS2_PLAYER_PROFILE_RESULT_OK_SAVE);
				}
			}
			break;
		}
		case LOADING:
		{
			bUsingDisplay = true;
			if( Asura_PS3_SaveLoad::GetStatus() == Asura_PS3_SaveLoad::STATUS_LOADED )
			{
				s_eState = IDLE;
				//SS2_PlayerProfile_System::SetLastOperationResult(Asura_PS3_SaveLoad::LastOperationCanceled()?SS2_PLAYER_PROFILE_RESULT_OK_NO_ACTION:SS2_PLAYER_PROFILE_RESULT_OK_LOAD);
				if( ( Asura_PS3_SaveLoad::ErrorOnLastOperation() ) || ( Asura_PS3_SaveLoad::LastOperationCanceled() ) )
				{
					// if the load failed or was cancelled 
				}
				else
				{
					// if it was successful then raise a flag to copy data back to the profile on the next AVP_Profile_LoadAndSave Update
					AVP_Profile_LoadAndSave::SetLoadState( AVP_PROFILELOAD_STATE_JUSTLOADED );
				}
			}
			break;
		}
		case ASKINGDELETE:
		{
			bUsingDisplay = true;
			if( ! Asura_PS3_MsgBox::IsDisplaying() )
			{
				if( Asura_PS3_MsgBox::LastQuestionAnswer() )
				{
					if( Asura_PS3_SaveLoad::DeleteProfiles() )
					{
						// if we dont already have a message box, and the answer to the last box was yes to delete, and we can delete set the state. 
						s_eState = DELETING;
					}
					else
					{
						// (NY - 21.02.2008) what to do if we can't delete? if we stay in this state, we'll retry ever frame...
						Asura_Assert( 0, "AVP_PS3_SaveState::Update\n Unable to delete?" );
					}
				}
				else
				{
					// if they dont wasnt to delete anything do they want to retry the save?
					//if( Asura_PS3_MsgBox::DisplayQuestion( Asura_HashedLocalisedText::GetString( uASURA_HASHEDTEXTPAGE_MENU, 0xd2308a70 /*"PS3_ASK_RETRYSAVE"*/), true ) )
					if( Asura_PS3_MsgBox::DisplayQuestion( L"Do you want to retry the save 1", true ) )
					{
						s_eState = ASKINGRETRY;
					}
					else
					{
						// (NY - 21.02.2008) what to do if we can't ask the question? if we stay in this state, we'll retry ever frame...
						Asura_Assert( 0, "AVP_PS3_SaveState::Update\n Unable to ask delete question" );
					}
				}
			}
			break;
		}
		case DELETING:
		{
			bUsingDisplay = true;
			if( Asura_PS3_SaveLoad::GetStatus() == Asura_PS3_SaveLoad::STATUS_DELETED )
			{
				//if( Asura_PS3_MsgBox::DisplayQuestion( Asura_HashedLocalisedText::GetString( uASURA_HASHEDTEXTPAGE_MENU, 0xd2308a70 /*"PS3_ASK_RETRYSAVE"*/), true ) )
				if( Asura_PS3_MsgBox::DisplayQuestion( L"Do you want to retry the save 2", true ) )
				{
					s_eState = ASKINGRETRY;
				}
				else
				{
					// (NY - 21.02.2008) what to do if we can't ask the question? if we stay in this state, we'll retry ever frame...
					Asura_Assert( 0, "AVP_PS3_SaveState::Update\n Unable to ask delete question" );
				}
			}
			break;
		}
		case ASKINGRETRY:
		{
			bUsingDisplay = true;
			if( ! Asura_PS3_MsgBox::IsDisplaying() )
			{
				if( Asura_PS3_MsgBox::LastQuestionAnswer() )
				{
					s_eState = IDLE;
					if( ! Save( true, s_pxLastData, s_pxLastSaveBlock ) )
					{
						s_eState = IDLE;
						//SS2_PlayerProfile_System::SetLastOperationResult(SS2_PLAYER_PROFILE_RESULT_FAIL);
					}
				}
				else
				{
					s_eState = IDLE;
					//SS2_PlayerProfile_System::SetLastOperationResult(SS2_PLAYER_PROFILE_RESULT_OK_SAVE);
				}
			}
			break;
		}
		case COUNTING:
		{
			if( Asura_PS3_SaveLoad::GetStatus() == Asura_PS3_SaveLoad::STATUS_COUNTED )
			{
				s_uNumProfiles = Asura_PS3_SaveLoad::LastProfileCountResult();
				s_eState = IDLE;
			}
			break;
		}
	}
	return bUsingDisplay;
}

bool AVP_PS3_SaveState::Load( void* pxData, Asura_StaticSaveBlock* pxSaveBlock )
{
	s_pxLastData = pxData;
	s_pxLastSaveBlock = pxSaveBlock;

	if( s_eState == COUNTING || s_eState == AUTOSAVING )
	{
		s_eNextState = LOADING;
		return true;
	}
	else if( s_eState != IDLE )
	{
		return false;
	}

	if( Asura_PS3_SaveLoad::LoadProfile( pxData, AVP_Profile_LoadAndSave::GetMaxSaveSize(), pxSaveBlock ) )
	{
		s_eState = LOADING;
		return true;
	}

	return false;
}

bool AVP_PS3_SaveState::GetShouldOfferLoad()
{
	if( s_eState == COUNTING )
	{
		return true;
	}
	if( s_uNumProfiles )
	{
		return true;
	}
	return false;
}

bool AVP_PS3_SaveState::CheckProfile( const void* pProfile )
{
	return true;
}

bool AVP_PS3_SaveState::Save( bool bForceManual, void* pxData, Asura_StaticSaveBlock* pxSaveBlock )
{
	s_pxLastData = pxData;
	s_pxLastSaveBlock = pxSaveBlock;

	if( s_eState == COUNTING || s_eState == AUTOSAVING )
	{
		s_eNextState = bForceManual ? SAVING : AUTOSAVING;
		return true;
	}
	else if( s_eState != IDLE )
	{
		return false;
	}

	Asura_PS3_SaveLoad::SetDontOverwriteSaveBlock(false);

	if( bForceManual )
	{
		if( Asura_PS3_SaveLoad::ManualSaveProfile( pxData, AVP_Profile_LoadAndSave::GetMaxSaveSize(), pxSaveBlock ) )
		{
			s_eState = SAVING;
			return true;
		}

		return false;
	}

	Asura_PS3_SaveLoad::SetDontOverwriteSaveBlock( Asura_PS3_SaveLoad::CanAutosave() );

	if( Asura_PS3_SaveLoad::SaveProfile( pxData, AVP_Profile_LoadAndSave::GetMaxSaveSize(), pxSaveBlock ) )
	{
		s_eState = Asura_PS3_SaveLoad::CanAutosave() ? AUTOSAVING : SAVING;
		return true;
	}

	return false;
}
