import class TutorialPopupGameController extends inkGameController
{
	editable var m_actionHint : inkWidgetRef;
	editable var m_popupPanel : inkWidgetRef;
	editable var m_popupFullscreenPanel : inkWidgetRef;
	editable var m_popupBlockingPanel : inkWidgetRef;
	editable var m_popupFullscreenRightPanel : inkWidgetRef;
	private var m_data : weak< TutorialPopupData >;
	private var m_inputBlocked : Bool;
	private var m_gamePaused : Bool;
	private var m_isShownBbId : CallbackHandle;
	private var m_animIntroPopup : CName;
	default m_animIntroPopup = 'into_popup';
	private var m_animIntroPopupModal : CName;
	default m_animIntroPopupModal = 'into_popup_modal';
	private var m_animIntroFullscreenLeft : CName;
	default m_animIntroFullscreenLeft = 'into_fullscreen_left';
	private var m_animIntroFullscreenRight : CName;
	default m_animIntroFullscreenRight = 'into_fullscreen_right';
	private var m_animOutroPopup : CName;
	default m_animOutroPopup = 'outro_popup';
	private var m_animOutroPopupModal : CName;
	default m_animOutroPopupModal = 'outro_popup_modal';
	private var m_animOutroFullscreenLeft : CName;
	default m_animOutroFullscreenLeft = 'outro_fullscreen_left';
	private var m_animOutroFullscreenRight : CName;
	default m_animOutroFullscreenRight = 'outro_fullscreen_right';
	private var m_animIntro : CName;
	private var m_animOutro : CName;
	private var m_targetPopup : inkWidgetRef;
	private var m_animationProxy : inkAnimProxy;
	private var m_targetPosition : PopupPosition;
	private var m_onInputDeviceChangedCallbackID : CallbackHandle;

	private import function RequestVisualState();
	private import function RestorePreviousVisualState();
	private import function AdaptToScreenComposition();

	protected event OnInitialize()
	{
		RequestVisualState();
		m_data = ( ( TutorialPopupData )( GetRootWidget().GetUserData( 'TutorialPopupData' ) ) );
		m_targetPosition = m_data.position;
		if( m_data.closeAtInput )
		{
			BlockInput( true );
		}
		if( m_data.pauseGame )
		{
			PauseGame( true );
			PlaySound( 'GameMenu', 'OnOpen' );
		}
		SetupView();
	}

	protected event OnUninitialize()
	{
		RestorePreviousVisualState();
		if( m_inputBlocked )
		{
			BlockInput( false );
		}
		if( m_gamePaused )
		{
			PauseGame( false );
		}
	}

	protected event OnRelease( e : inkPointerEvent )
	{
		if( e.IsAction( 'close_tutorial' ) )
		{
			if( m_animationProxy != NULL )
			{
				m_animationProxy.UnregisterFromAllCallbacks( inkanimEventType.OnFinish );
				m_animationProxy.Stop();
				m_animationProxy = NULL;
			}
			m_animationProxy = PlayLibraryAnimationOnAutoSelectedTargets( m_animOutro, inkWidgetRef.Get( m_targetPopup ) );
			m_animationProxy.RegisterToCallback( inkanimEventType.OnFinish, this, 'OnOutro' );
			PlaySound( 'GameMenu', 'OnClose' );
		}
	}

	protected event OnPlayerAttach( playerPuppet : GameObject )
	{
		var owner : GameObject;
		m_onInputDeviceChangedCallbackID = GetBlackboardSystem().Get( GetAllBlackboardDefs().InputSchemes ).RegisterListenerUint( GetAllBlackboardDefs().InputSchemes.Device, this, 'OnInputDeviceChanged' );
		if( m_inputBlocked )
		{
			owner = GetPlayerControlledObject();
			owner.RegisterInputListener( this, 'UI_Apply' );
			owner.RegisterInputListener( this, 'UI_Cancel' );
			owner.RegisterInputListener( this, 'ChoiceApply' );
		}
	}

	protected event OnPlayerDetach( playerPuppet : GameObject )
	{
		if( m_onInputDeviceChangedCallbackID )
		{
			GetBlackboardSystem().Get( GetAllBlackboardDefs().InputSchemes ).UnregisterListenerUint( GetAllBlackboardDefs().InputSchemes.Device, m_onInputDeviceChangedCallbackID );
		}
		if( m_inputBlocked )
		{
			GetPlayerControlledObject().UnregisterInputListener( this );
		}
	}

	protected event OnInputDeviceChanged( value : Uint32 )
	{
		var popupController : TutorialPopupDisplayController;
		var inputDevice : InputDevice;
		var inputScheme : InputScheme;
		inputDevice = ( ( InputDevice )( ( ( Uint8 )( value ) ) ) );
		inputScheme = ( ( InputScheme )( ( ( Uint8 )( GetBlackboardSystem().Get( GetAllBlackboardDefs().InputSchemes ).GetUint( GetAllBlackboardDefs().InputSchemes.Scheme ) ) ) ) );
		if( inkWidgetRef.IsValid( m_targetPopup ) )
		{
			popupController = ( ( TutorialPopupDisplayController )( inkWidgetRef.GetController( m_targetPopup ) ) );
			popupController.Refresh( inputDevice, inputScheme );
		}
	}

	private function BlockInput( value : Bool )
	{
		if( m_inputBlocked != value )
		{
			m_inputBlocked = value;
			if( m_inputBlocked )
			{
				RegisterToGlobalInputCallback( 'OnPostOnRelease', this, 'OnRelease' );
			}
			else
			{
				UnregisterFromGlobalInputCallback( 'OnPostOnRelease', this, 'OnRelease' );
			}
		}
	}

	private function PauseGame( value : Bool )
	{
		if( m_gamePaused != value )
		{
			m_gamePaused = value;
			if( value )
			{
				GameInstance.GetTimeSystem( GetPlayerControlledObject().GetGame() ).SetTimeDilation( 'UI_TutorialPopup', 0.0 );
				GameInstance.GetAudioSystem( GetPlayerControlledObject().GetGame() ).Play( 'global_tutorial_open' );
			}
			else
			{
				GameInstance.GetTimeSystem( GetPlayerControlledObject().GetGame() ).UnsetTimeDilation( 'UI_TutorialPopup' );
				GameInstance.GetAudioSystem( GetPlayerControlledObject().GetGame() ).Play( 'ui_menu_tutorial_close' );
				GameInstance.GetAudioSystem( GetPlayerControlledObject().GetGame() ).Play( 'global_tutorial_close' );
			}
		}
	}

	private function SetupView()
	{
		var displayController : TutorialPopupDisplayController;
		var inputBB : IBlackboard;
		var inputDevice : InputDevice;
		var inputScheme : InputScheme;
		var targetMargin : inkMargin;
		inputBB = GetBlackboardSystem().Get( GetAllBlackboardDefs().InputSchemes );
		inputDevice = ( ( InputDevice )( ( ( Uint8 )( inputBB.GetUint( GetAllBlackboardDefs().InputSchemes.Device ) ) ) ) );
		inputScheme = ( ( InputScheme )( ( ( Uint8 )( inputBB.GetUint( GetAllBlackboardDefs().InputSchemes.Scheme ) ) ) ) );
		GetRootWidget().SetVisible( true );
		inkWidgetRef.SetVisible( m_popupPanel, false );
		inkWidgetRef.SetVisible( m_popupFullscreenPanel, false );
		inkWidgetRef.SetVisible( m_popupBlockingPanel, false );
		inkWidgetRef.SetVisible( m_popupFullscreenRightPanel, false );
		if( m_animationProxy != NULL )
		{
			m_animationProxy.UnregisterFromAllCallbacks( inkanimEventType.OnFinish );
			m_animationProxy.Stop();
			m_animationProxy = NULL;
		}
		if( m_data.isModal )
		{
			if( m_data.position == PopupPosition.UpperRight || m_data.position == PopupPosition.LowerRight )
			{
				m_targetPopup = m_popupFullscreenRightPanel;
				m_animIntro = m_animIntroFullscreenRight;
				m_animOutro = m_animOutroFullscreenRight;
			}
			else
			{
				m_targetPopup = m_popupFullscreenPanel;
				m_animIntro = m_animIntroFullscreenLeft;
				m_animOutro = m_animOutroFullscreenLeft;
			}
			inkWidgetRef.SetVisible( m_targetPopup, true );
			targetMargin = inkWidgetRef.GetMargin( m_targetPopup );
			targetMargin.left += m_data.margin.left;
			targetMargin.top += m_data.margin.top;
			targetMargin.right += m_data.margin.right;
			targetMargin.bottom += m_data.margin.bottom;
			inkWidgetRef.SetMargin( m_targetPopup, targetMargin );
		}
		else
		{
			if( m_data.closeAtInput )
			{
				m_targetPopup = m_popupBlockingPanel;
				m_animIntro = m_animIntroPopupModal;
				m_animOutro = m_animOutroPopupModal;
			}
			else
			{
				m_targetPopup = m_popupPanel;
				m_animIntro = m_animIntroPopup;
				m_animOutro = m_animOutroPopup;
			}
			inkWidgetRef.SetVisible( m_targetPopup, true );
			targetMargin = inkWidgetRef.GetMargin( m_targetPopup );
			targetMargin.left += m_data.margin.left;
			targetMargin.top += m_data.margin.top;
			targetMargin.right += m_data.margin.right;
			targetMargin.bottom += m_data.margin.bottom;
			inkWidgetRef.SetMargin( m_targetPopup, targetMargin );
			m_targetPosition = m_data.position;
			switch( m_targetPosition )
			{
				case PopupPosition.UpperRight:
					inkWidgetRef.SetAnchorPoint( m_targetPopup, 1.0, 0.0 );
				inkWidgetRef.SetAnchor( m_targetPopup, inkEAnchor.TopRight );
				break;
				case PopupPosition.UpperLeft:
					inkWidgetRef.SetAnchorPoint( m_targetPopup, 0.0, 0.0 );
				inkWidgetRef.SetAnchor( m_targetPopup, inkEAnchor.TopLeft );
				break;
				case PopupPosition.LowerLeft:
					inkWidgetRef.SetAnchorPoint( m_targetPopup, 0.0, 1.0 );
				inkWidgetRef.SetAnchor( m_targetPopup, inkEAnchor.BottomLeft );
				AdaptToDpadHints();
				break;
				case PopupPosition.LowerRight:
					inkWidgetRef.SetAnchorPoint( m_targetPopup, 1.0, 1.0 );
				inkWidgetRef.SetAnchor( m_targetPopup, inkEAnchor.BottomRight );
				break;
				case PopupPosition.Undefined:
				case PopupPosition.Center:
					inkWidgetRef.SetAnchorPoint( m_targetPopup, 0.5, 0.5 );
				inkWidgetRef.SetAnchor( m_targetPopup, inkEAnchor.Centered );
				break;
			}
		}
		displayController = ( ( TutorialPopupDisplayController )( inkWidgetRef.GetController( m_targetPopup ) ) );
		displayController.SetData( m_data, inputDevice, inputScheme );
		AdaptToScreenComposition();
		m_animationProxy = PlayLibraryAnimationOnAutoSelectedTargets( m_animIntro, inkWidgetRef.Get( m_targetPopup ) );
		m_animationProxy.RegisterToCallback( inkanimEventType.OnFinish, this, 'OnIntro' );
	}

	private export function AdaptToBlackBars( offset : Float )
	{
		var popupTranslation : Vector2;
		popupTranslation = inkWidgetRef.GetTranslation( m_targetPopup );
		switch( m_targetPosition )
		{
			case PopupPosition.UpperLeft:
			case PopupPosition.LowerLeft:
				popupTranslation.X += offset;
			inkWidgetRef.SetTranslation( m_targetPopup, popupTranslation );
			break;
			case PopupPosition.LowerRight:
			case PopupPosition.UpperRight:
				popupTranslation.X -= offset;
			inkWidgetRef.SetTranslation( m_targetPopup, popupTranslation );
			break;
			case PopupPosition.Undefined:
			case PopupPosition.Center:
				return;
		}
	}

	private export function AdaptToHudSafezones( safezones : Vector2 )
	{
		var targetMargin : inkMargin;
		targetMargin = inkWidgetRef.GetMargin( m_targetPopup );
		targetMargin.left += m_data.margin.left;
		targetMargin.top += m_data.margin.top;
		targetMargin.right += m_data.margin.right;
		targetMargin.bottom += m_data.margin.bottom;
		switch( m_targetPosition )
		{
			case PopupPosition.UpperLeft:
				targetMargin.left += safezones.X;
			targetMargin.top += safezones.Y;
			break;
			case PopupPosition.LowerLeft:
				targetMargin.left += safezones.X;
			targetMargin.bottom += safezones.Y;
			break;
			case PopupPosition.LowerRight:
				targetMargin.right += safezones.X;
			targetMargin.bottom += safezones.Y;
			break;
			case PopupPosition.UpperRight:
				targetMargin.right += safezones.X;
			targetMargin.top += safezones.Y;
			break;
			default:
				break;
		}
		inkWidgetRef.SetMargin( m_targetPopup, targetMargin );
	}

	private function AdaptToDpadHints()
	{
		var isBiggerHudEnabled : Bool;
		var targetMargin : inkMargin;
		isBiggerHudEnabled = GameInstance.GetUISystem( GetPlayerControlledObject().GetGame() ).GetHudScalingOverride() > 1.0;
		targetMargin = inkWidgetRef.GetMargin( m_targetPopup );
		if( targetMargin.bottom > 0.0 )
		{
			targetMargin.bottom += ( ( isBiggerHudEnabled ) ? ( 150.0 ) : ( 100.0 ) );
			inkWidgetRef.SetMargin( m_targetPopup, targetMargin );
		}
	}

	protected event OnIntro( anim : inkAnimProxy )
	{
		if( m_gamePaused )
		{
			GameInstance.GetAudioSystem( GetPlayerControlledObject().GetGame() ).Play( 'ui_menu_tutorial_open' );
		}
	}

	protected event OnOutro( anim : inkAnimProxy )
	{
		m_data.token.TriggerCallback( m_data );
	}

}

