class TransferSaveSystemNotificationLogicController extends inkGenericSystemNotificationLogicController
{
	protected editable var m_contentBlock : inkWidgetRef;
	protected editable var m_spinnerBlock : inkWidgetRef;
	protected editable var m_errorBlock : inkWidgetRef;
	protected editable var m_saveImageContainer : inkWidgetRef;
	protected editable var m_saveImage : inkImageRef;
	protected editable var m_saveImageEmpty : inkWidgetRef;
	protected editable var m_saveImageSpinner : inkWidgetRef;
	protected editable var m_messageText : inkTextRef;
	protected editable var m_spinnerText : inkTextRef;
	protected editable var m_errorText : inkTextRef;
	protected editable var m_proceedButtonWidget : inkWidgetRef;
	protected editable var m_cancelButtonWidget : inkWidgetRef;
	private var m_systemRequestHandler : weak< inkISystemRequestsHandler >;
	private var m_transferSaveData : weak< TransferSaveData >;
	private var m_transferSaveDataSet : Bool;
	private var m_systemRequestsHandlerSet : Bool;
	private var m_cancelButtonHovered : Bool;
	private var m_currentState : TransferSaveState;

	protected event OnInitialize()
	{
		RegisterToCallback( 'OnDataSetByToken', this, 'OnDataSetByToken' );
		RegisterToGlobalInputCallback( 'OnPreOnRelease', this, 'OnGlobalPreRelease' );
		inkWidgetRef.RegisterToCallback( m_cancelButtonWidget, 'OnRelease', this, 'OnCancelClick' );
		inkWidgetRef.GetController( m_cancelButtonWidget ).RegisterToCallback( 'OnHoverOver', this, 'OnCancelHoverOver' );
		inkWidgetRef.GetController( m_cancelButtonWidget ).RegisterToCallback( 'OnHoverOut', this, 'OnCancelHoverOut' );
	}

	protected event OnUninitialize()
	{
		UnregisterFromCallback( 'OnDataSetByToken', this, 'OnDataSetByToken' );
		UnregisterFromGlobalInputCallback( 'OnPreOnRelease', this, 'OnGlobalPreRelease' );
		if( m_systemRequestHandler )
		{
			m_systemRequestHandler.UnregisterFromCallback( 'OnSaveTransferUpdate', this, 'OnSaveTransferUpdate' );
		}
	}

	protected event OnDataSetByToken()
	{
		m_transferSaveData = ( ( weak< weak< TransferSaveData > > )( GetScriptableData() ) );
		DisableDefaultInputHandler();
		m_transferSaveDataSet = true;
		SetupData();
	}

	protected event OnGlobalPreRelease( evt : inkPointerEvent )
	{
		if( CanCancelOrProceed() )
		{
			if( evt.IsAction( 'proceed_popup' ) && !( m_cancelButtonHovered ) )
			{
				HandleProceedClick();
			}
			else if( evt.IsAction( 'cancel_popup' ) || ( evt.IsAction( 'proceed_popup' ) && m_cancelButtonHovered ) )
			{
				TriggerCancel();
			}
		}
	}

	private function HandleProceedClick()
	{
		if( m_currentState == TransferSaveState.ExportConfirmation )
		{
			m_systemRequestHandler.ExportSavedGame( m_transferSaveData.saveIndex );
		}
		else
		{
			TriggerProceed();
		}
	}

	private function CanCancelOrProceed() : Bool
	{
		return m_currentState != TransferSaveState.ExportSpinner && m_currentState != TransferSaveState.ImportLoading;
	}

	protected event OnCancelClick( e : inkPointerEvent )
	{
		if( e.IsAction( 'click' ) && CanCancelOrProceed() )
		{
			TriggerCancel();
		}
	}

	protected event OnCancelHoverOver( evt : inkPointerEvent )
	{
		m_cancelButtonHovered = true;
	}

	protected event OnCancelHoverOut( evt : inkPointerEvent )
	{
		m_cancelButtonHovered = false;
	}

	public function SetSystemRequestHandler( handler : weak< inkISystemRequestsHandler > )
	{
		if( m_systemRequestHandler )
		{
			m_systemRequestHandler.UnregisterFromCallback( 'OnSaveTransferUpdate', this, 'OnSaveTransferUpdate' );
		}
		m_systemRequestHandler = handler;
		m_systemRequestHandler.RegisterToCallback( 'OnSaveTransferUpdate', this, 'OnSaveTransferUpdate' );
		m_systemRequestsHandlerSet = true;
		SetupData();
	}

	private function SetupData()
	{
		if( m_transferSaveDataSet && m_systemRequestsHandlerSet )
		{
			if( m_transferSaveData.action == TransferSaveAction.Export )
			{
				UpdateState( TransferSaveState.ExportConfirmation );
				SetSaveImage();
			}
			if( m_transferSaveData.action == TransferSaveAction.Import )
			{
				m_systemRequestHandler.ImportSavedGame();
			}
			m_transferSaveDataSet = false;
			m_systemRequestsHandlerSet = false;
		}
	}

	private function SetSaveImage()
	{
		if( inkImageRef.Get( m_saveImage ) )
		{
			m_systemRequestHandler.RequestSavedGameScreenshot( m_transferSaveData.saveIndex, ( ( weak< weak< inkImage > > )( inkImageRef.Get( m_saveImage ) ) ) );
		}
	}

	protected event OnSaveTransferUpdate( status : inkSaveTransferStatus )
	{
		if( status == inkSaveTransferStatus.ImportSuccess )
		{
			if( m_systemRequestHandler )
			{
				m_systemRequestHandler.RequestSavesForLoad();
			}
			TriggerProceed();
		}
		switch( status )
		{
			case inkSaveTransferStatus.ExportStarted:
				UpdateState( TransferSaveState.ExportSpinner );
			break;
			case inkSaveTransferStatus.ExportSuccess:
				UpdateState( TransferSaveState.ExportSuccess );
			break;
			case inkSaveTransferStatus.ExportFailed:
				UpdateState( TransferSaveState.ExportFailed );
			break;
			case inkSaveTransferStatus.ImportChecking:
				UpdateState( TransferSaveState.ImportSpinner );
			break;
			case inkSaveTransferStatus.ImportStarted:
				UpdateState( TransferSaveState.ImportLoading );
			break;
			case inkSaveTransferStatus.ImportNoSave:
				UpdateState( TransferSaveState.ImportNoSave );
			break;
			case inkSaveTransferStatus.ImportFailed:
				UpdateState( TransferSaveState.ImportFailed );
			break;
			case inkSaveTransferStatus.ImportNotEnoughSpace:
				UpdateState( TransferSaveState.ImportNotEnoughSpace );
			break;
		}
	}

	private function UpdateState( state : TransferSaveState )
	{
		m_currentState = state;
		UpdateText( state );
		UpdateStateVisibility( state );
		UpdateButtonsVisibility( state );
	}

	private function UpdateText( state : TransferSaveState )
	{
		switch( state )
		{
			case TransferSaveState.ExportConfirmation:
				inkTextRef.SetText( m_messageText, "UI-SystemNotification-SaveTransfer-ExportConfirmation" );
			break;
			case TransferSaveState.ExportSpinner:
				inkTextRef.SetText( m_messageText, "UI-SystemNotification-SaveTransfer-ExportSpinner" );
			break;
			case TransferSaveState.ExportSuccess:
				inkTextRef.SetText( m_messageText, "UI-SystemNotification-SaveTransfer-ExportSuccess" );
			break;
			case TransferSaveState.ExportFailed:
				inkTextRef.SetText( m_errorText, "UI-SystemNotification-SaveTransfer-ExportFailed" );
			break;
			case TransferSaveState.ImportSpinner:
				inkTextRef.SetText( m_spinnerText, "UI-SystemNotification-SaveTransfer-ImportSpinner" );
			break;
			case TransferSaveState.ImportLoading:
				inkTextRef.SetText( m_messageText, "UI-SystemNotification-SaveTransfer-ImportLoading" );
			break;
			case TransferSaveState.ImportNoSave:
				inkTextRef.SetText( m_errorText, "UI-SystemNotification-SaveTransfer-ImportNoSave" );
			break;
			case TransferSaveState.ImportFailed:
				inkTextRef.SetText( m_errorText, "UI-SystemNotification-SaveTransfer-ImportFailed" );
			break;
			case TransferSaveState.ImportNotEnoughSpace:
				inkTextRef.SetText( m_errorText, "UI-Notifications-SaveNotEnoughSpace" );
			break;
		}
	}

	private function UpdateButtonsVisibility( state : TransferSaveState )
	{
		switch( state )
		{
			case TransferSaveState.ExportConfirmation:
				inkWidgetRef.SetVisible( m_proceedButtonWidget, true );
			inkWidgetRef.SetVisible( m_cancelButtonWidget, true );
			break;
			case TransferSaveState.ExportSpinner:
			case TransferSaveState.ImportLoading:
				inkWidgetRef.SetVisible( m_proceedButtonWidget, false );
			inkWidgetRef.SetVisible( m_cancelButtonWidget, false );
			break;
			case TransferSaveState.ExportFailed:
			case TransferSaveState.ImportSpinner:
			case TransferSaveState.ImportNoSave:
			case TransferSaveState.ImportFailed:
			case TransferSaveState.ImportNotEnoughSpace:
				inkWidgetRef.SetVisible( m_proceedButtonWidget, false );
			inkWidgetRef.SetVisible( m_cancelButtonWidget, true );
			break;
			case TransferSaveState.ExportSuccess:
				inkWidgetRef.SetVisible( m_proceedButtonWidget, true );
			inkWidgetRef.SetVisible( m_cancelButtonWidget, false );
			break;
		}
	}

	private function UpdateStateVisibility( state : TransferSaveState )
	{
		var isError : Bool;
		isError = ( ( state == TransferSaveState.ImportNoSave || state == TransferSaveState.ImportFailed ) || state == TransferSaveState.ExportFailed ) || state == TransferSaveState.ImportNotEnoughSpace;
		GetRootWidget().SetState( ( ( isError ) ? ( 'Warning' ) : ( 'Default' ) ) );
		inkImageRef.SetOpacity( m_saveImage, ( ( state == TransferSaveState.ExportSpinner ) ? ( 0.60000002 ) : ( 1.0 ) ) );
		switch( state )
		{
			case TransferSaveState.ExportConfirmation:
			case TransferSaveState.ExportSuccess:
				inkWidgetRef.SetVisible( m_contentBlock, true );
			inkWidgetRef.SetVisible( m_spinnerBlock, false );
			inkWidgetRef.SetVisible( m_errorBlock, false );
			inkWidgetRef.SetVisible( m_saveImageContainer, true );
			inkWidgetRef.SetVisible( m_saveImageSpinner, false );
			inkWidgetRef.SetVisible( m_saveImageEmpty, false );
			break;
			case TransferSaveState.ExportSpinner:
				inkWidgetRef.SetVisible( m_contentBlock, true );
			inkWidgetRef.SetVisible( m_spinnerBlock, false );
			inkWidgetRef.SetVisible( m_errorBlock, false );
			inkWidgetRef.SetVisible( m_saveImageContainer, true );
			inkWidgetRef.SetVisible( m_saveImageSpinner, true );
			inkWidgetRef.SetVisible( m_saveImageEmpty, false );
			break;
			case TransferSaveState.ExportFailed:
			case TransferSaveState.ImportFailed:
			case TransferSaveState.ImportNoSave:
			case TransferSaveState.ImportNotEnoughSpace:
				inkWidgetRef.SetVisible( m_contentBlock, false );
			inkWidgetRef.SetVisible( m_spinnerBlock, false );
			inkWidgetRef.SetVisible( m_errorBlock, true );
			break;
			case TransferSaveState.ImportSpinner:
				inkWidgetRef.SetVisible( m_contentBlock, false );
			inkWidgetRef.SetVisible( m_spinnerBlock, true );
			inkWidgetRef.SetVisible( m_errorBlock, false );
			break;
			case TransferSaveState.ImportLoading:
				inkWidgetRef.SetVisible( m_contentBlock, true );
			inkWidgetRef.SetVisible( m_spinnerBlock, false );
			inkWidgetRef.SetVisible( m_errorBlock, false );
			inkWidgetRef.SetVisible( m_saveImageContainer, false );
			inkWidgetRef.SetVisible( m_saveImageSpinner, false );
			inkWidgetRef.SetVisible( m_saveImageEmpty, true );
			break;
		}
	}

}

class TransferSaveGameController extends inkGameController
{
	private editable var m_notificationController : inkWidgetRef;

	protected event OnInitialize()
	{
		var controller : weak< TransferSaveSystemNotificationLogicController >;
		controller = ( ( weak< weak< TransferSaveSystemNotificationLogicController > > )( inkWidgetRef.GetControllerByType( m_notificationController, 'TransferSaveSystemNotificationLogicController' ) ) );
		if( controller )
		{
			controller.SetSystemRequestHandler( GetSystemRequestsHandler() );
		}
	}

}

enum TransferSaveState
{
	ExportConfirmation = 0,
	ExportSpinner = 1,
	ExportSuccess = 2,
	ExportFailed = 3,
	ImportSpinner = 4,
	ImportLoading = 5,
	ImportNoSave = 6,
	ImportFailed = 7,
	ImportNotEnoughSpace = 8,
}

enum TransferSaveAction
{
	Export = 0,
	Import = 1,
}

class TransferSaveData
{
	var saveIndex : Int32;
	var action : TransferSaveAction;
}

