class OpenExpansionPopupEvent extends Event
{
	var m_type : ExpansionPopupType;
	var m_state : ExpansionStatus;
	var m_forcibly : Bool;
}

class ExpansionPopupData extends inkGameNotificationData
{
	var m_type : ExpansionPopupType;
	var m_state : ExpansionStatus;
}

enum ExpansionPopupType
{
	Default = 0,
	Features = 1,
	ThankYou = 2,
	Reloading = 3,
	PreOrder = 4,
}

class ExpansionStatePopupGameController extends inkGameController
{
	private editable var m_statusRef : inkTextRef;
	private editable var m_animationName : CName;
	default m_animationName = 'popupAnim';

	protected event OnInitialize()
	{
		var animProxy : inkAnimProxy;
		SetupData();
		animProxy = PlayLibraryAnimation( m_animationName );
		animProxy.RegisterToCallback( inkanimEventType.OnFinish, this, 'OnAnimFinished' );
	}

	protected event OnUninitialize() {}

	protected event OnAnimFinished( proxy : inkAnimProxy )
	{
		var data : ExpansionPopupData;
		if( proxy )
		{
			proxy.UnregisterFromAllCallbacks( inkanimEventType.OnFinish );
		}
		data = ( ( ExpansionPopupData )( GetRootWidget().GetUserData( 'ExpansionPopupData' ) ) );
		if( data )
		{
			data.token.TriggerCallback( data );
		}
	}

	private function SetupData()
	{
		var data : ExpansionPopupData;
		data = ( ( ExpansionPopupData )( GetRootWidget().GetUserData( 'ExpansionPopupData' ) ) );
		if( data )
		{
			switch( data.m_state )
			{
				case ExpansionStatus.Owned:
					inkTextRef.SetText( m_statusRef, "DOWNLOAD STARTED" );
				break;
				case ExpansionStatus.Downloaded:
					inkTextRef.SetText( m_statusRef, "DOWNLOAD FINISHED" );
				break;
				case ExpansionStatus.Reloading:
					inkTextRef.SetText( m_statusRef, "RELOADING FINISHED" );
				break;
			}
		}
	}

}

class ExpansionPopupGameController extends inkGameController
{
	private editable var m_popupCanvasAnchor : inkWidgetRef;
	private editable var m_expansionScreenName : CName;
	private editable var m_thankYouScreenName : CName;
	private editable var m_reloadingScreenName : CName;
	private editable var m_preOrderScreenName : CName;
	private editable var m_closeButtonRef : inkWidgetRef;
	private editable var m_introAnimationName : CName;
	default m_introAnimationName = 'intro';
	private var m_uiSystem : UISystem;
	private var m_data : ExpansionPopupData;
	private var m_requestHandler : weak< inkISystemRequestsHandler >;
	private var m_showThankYouPanel : Bool;
	private var m_introAnimProxy : inkAnimProxy;
	private var m_featuresExpansionPopupController : weak< FeaturesExpansionPopupController >;
	private var m_preOrderPopupController : weak< PreOrderPopupController >;
	private var m_reloadingPopupController : weak< ReloadingExpansionPopupController >;
	private var m_buyButton : inkWidgetRef;
	private var m_preOrderButton : inkWidgetRef;
	private var m_isProcessingPurchase : Bool;

	protected event OnInitialize()
	{
		var widget : weak< inkWidget >;
		var panelName : CName;
		m_uiSystem = GameInstance.GetUISystem( GetPlayerControlledObject().GetGame() );
		m_requestHandler = GetSystemRequestsHandler();
		RegisterToGlobalInputCallback( 'OnPostOnRelease', this, 'OnRelease' );
		inkWidgetRef.RegisterToCallback( m_closeButtonRef, 'OnPress', this, 'OnPressClose' );
		SetupData();
		panelName = GetPanelName();
		if( panelName == '' || panelName == 'none' )
		{
			Close();
		}
		else
		{
			widget = SpawnFromLocal( inkWidgetRef.Get( m_popupCanvasAnchor ), panelName );
			if( widget )
			{
				if( panelName == m_expansionScreenName )
				{
					m_featuresExpansionPopupController = ( ( FeaturesExpansionPopupController )( widget.GetController() ) );
					if( m_featuresExpansionPopupController )
					{
						m_featuresExpansionPopupController.SetIsEp1Released( m_requestHandler.IsAdditionalContentReleased( 'EP1' ) );
						m_featuresExpansionPopupController.SetState( m_data.m_state );
						m_buyButton = m_featuresExpansionPopupController.GetButtonRef();
						if( m_data.m_state == ExpansionStatus.Available )
						{
							m_requestHandler.LogPreorderPopupImpression( 'EP1' );
						}
						inkWidgetRef.RegisterToCallback( m_buyButton, 'OnPress', this, 'OnPressBuy' );
						m_requestHandler.RegisterToCallback( 'OnAdditionalContentPurchaseResult', this, 'OnAdditionalContentPurchaseResult_PopUp' );
					}
				}
				else if( panelName == m_preOrderScreenName )
				{
					m_preOrderPopupController = ( ( PreOrderPopupController )( widget.GetController() ) );
					if( m_preOrderPopupController )
					{
						m_preOrderButton = m_preOrderPopupController.GetButtonRef();
						if( m_data.m_state == ExpansionStatus.PreOrder )
						{
							m_requestHandler.LogPreorderPopupImpression( 'EP1' );
						}
						inkWidgetRef.RegisterToCallback( m_preOrderButton, 'OnPress', this, 'OnPressPreOrder' );
						m_preOrderPopupController.SetPreOrderSate( m_data.m_state == ExpansionStatus.PreOrderOwned );
					}
				}
				else if( panelName == m_reloadingScreenName )
				{
					m_reloadingPopupController = ( ( ReloadingExpansionPopupController )( widget.GetController() ) );
					m_requestHandler.RegisterToCallback( 'OnAdditionalContentDataReloadProgressCallback', this, 'OnAdditionalContentDataReloadProgress_PopUp' );
					RegisterToCallback( 'OnReloadingExpansionPopupCloseEvent', this, 'OnReloadingExpansionPopupCloseEvent' );
				}
				inkWidgetRef.SetVisible( m_closeButtonRef, panelName != m_reloadingScreenName );
				m_introAnimProxy = PlayLibraryAnimation( m_introAnimationName );
			}
		}
	}

	protected event OnUninitialize()
	{
		UnregisterFromGlobalInputCallback( 'OnPostOnRelease', this, 'OnRelease' );
		inkWidgetRef.UnregisterFromCallback( m_closeButtonRef, 'OnPress', this, 'OnPressClose' );
		inkWidgetRef.UnregisterFromCallback( m_buyButton, 'OnPress', this, 'OnPressBuy' );
		inkWidgetRef.UnregisterFromCallback( m_preOrderButton, 'OnPress', this, 'OnPressPreOrder' );
		m_requestHandler.UnregisterFromCallback( 'OnAdditionalContentDataReloadProgressCallback', this, 'OnAdditionalContentDataReloadProgress_PopUp' );
		m_requestHandler.UnregisterFromCallback( 'OnAdditionalContentPurchaseResult', this, 'OnAdditionalContentPurchaseResult_PopUp' );
	}

	protected event OnRelease( evt : inkPointerEvent )
	{
		if( ( evt.IsAction( 'close_popup' ) && !( m_isProcessingPurchase ) ) && !( m_introAnimProxy.IsPlaying() ) )
		{
			Close();
		}
		else if( m_featuresExpansionPopupController && evt.IsAction( 'popup_purchase' ) )
		{
			BuyPressed();
		}
		else if( ( m_preOrderPopupController && m_data.m_state == ExpansionStatus.PreOrder ) && evt.IsAction( 'popup_purchase' ) )
		{
			OpenStorePage();
		}
	}

	protected event OnPressClose( evt : inkPointerEvent )
	{
		if( evt.IsAction( 'click' ) && !( m_introAnimProxy.IsPlaying() ) )
		{
			Close();
		}
	}

	protected event OnPressPreOrder( evt : inkPointerEvent )
	{
		if( evt.IsAction( 'click' ) && m_data.m_state == ExpansionStatus.PreOrder )
		{
			OpenStorePage();
		}
	}

	protected event OnPressBuy( evt : inkPointerEvent )
	{
		if( evt.IsAction( 'click' ) )
		{
			BuyPressed();
		}
	}

	private function SetupData()
	{
		m_data = ( ( ExpansionPopupData )( GetRootWidget().GetUserData( 'ExpansionPopupData' ) ) );
	}

	private function GetPanelName() : CName
	{
		switch( m_data.m_type )
		{
			case ExpansionPopupType.Features:
				return m_expansionScreenName;
			break;
			case ExpansionPopupType.ThankYou:
				return m_thankYouScreenName;
			break;
			case ExpansionPopupType.Reloading:
				return m_reloadingScreenName;
			break;
			case ExpansionPopupType.PreOrder:
				return m_preOrderScreenName;
			break;
		}
		return '';
	}

	private function BuyPressed()
	{
		if( m_requestHandler.IsPurchaseThroughAppEnabled() )
		{
			OpenStorePage();
		}
		else
		{
			m_uiSystem.QueueMenuEvent( 'OnRequetPurchaseDisabledError' );
			Close();
		}
	}

	private function OpenStorePage()
	{
		m_requestHandler.RequestAdditionalContentPurchase( 'EP1' );
		m_requestHandler.LogPreorderClick( 'EP1' );
		m_featuresExpansionPopupController.SetState( ExpansionStatus.Processing );
		m_isProcessingPurchase = true;
		inkWidgetRef.SetVisible( m_closeButtonRef, false );
	}

	private function Close()
	{
		var playbackOptions : inkAnimOptions;
		PlaySound( 'Button', 'OnPress' );
		playbackOptions.playReversed = true;
		m_introAnimProxy = PlayLibraryAnimation( m_introAnimationName, playbackOptions );
		m_introAnimProxy.RegisterToCallback( inkanimEventType.OnFinish, this, 'OnOutroAnimationFinished' );
	}

	public function OnAdditionalContentPurchaseResult_PopUp( id : CName, success : Bool )
	{
		m_isProcessingPurchase = false;
		inkWidgetRef.SetVisible( m_closeButtonRef, true );
		Close();
	}

	protected event OnOutroAnimationFinished( proxy : inkAnimProxy )
	{
		if( m_uiSystem.IsPatchIntroNeeded( gameuiPatchIntro.Patch2000 ) || m_uiSystem.IsPatchIntroNeeded( gameuiPatchIntro.Patch2100 ) )
		{
			m_uiSystem.QueueMenuEvent( 'OnRequetCloseExpansionPopup' );
		}
		m_introAnimProxy.UnregisterFromCallback( inkanimEventType.OnFinish, this, 'OnOutroAnimationFinished' );
		m_data.token.TriggerCallback( m_data );
	}

	protected event OnAdditionalContentDataReloadProgress_PopUp( progress : Float )
	{
		if( m_reloadingPopupController )
		{
			m_reloadingPopupController.UpdateProgress( progress );
		}
	}

	protected event OnReloadingExpansionPopupCloseEvent( evt : ReloadingExpansionPopupCloseEvent )
	{
		Close();
	}

}

class FeaturesExpansionPopupController extends inkLogicController
{
	[ category = "Main" ]
	private editable var m_hoverAnimationName : CName;
	[ category = "Main" ]
	private editable var m_hoverArrow : inkImageRef;
	[ category = "Buy Button" ]
	private editable var m_buyButtonRef : inkWidgetRef;
	[ category = "Buy Button" ]
	private editable var m_buyButtonText : inkTextRef;
	[ category = "Buy Button" ]
	private editable var m_buyButtonInputIcon : inkWidgetRef;
	[ category = "Buy Button" ]
	private editable var m_buyButtonSpinner : inkWidgetRef;
	[ category = "Buy Button" ]
	private editable var m_locKey_Buy : CName;
	default m_locKey_Buy = 'UI-DLC-EP1-PurchaseFlow-EP1Popup-BuyNow';
	[ category = "Buy Button" ]
	private editable var m_locKey_PreOrder : CName;
	default m_locKey_PreOrder = 'UI-DLC-EP1-PurchaseFlow-MainMenuBanner-PreOrderNow';
	[ category = "Video Selector" ]
	private editable var m_slectorContainerRef : inkWidgetRef;
	[ category = "Video Selector" ]
	private editable var m_slectorArrowLeftRef : inkWidgetRef;
	[ category = "Video Selector" ]
	private editable var m_slectorArrowRightRef : inkWidgetRef;
	[ category = "Videos" ]
	private editable var m_videoCarouselRef : inkWidgetRef;
	[ category = "Videos" ]
	private editable var m_videoContainerRef : inkWidgetRef;
	[ category = "Videos" ]
	private const editable var m_videoCarouselData : array< VideoCarouselData >;
	private var m_videoCarouselController : weak< VideoCarouselController >;
	private var m_buyButtonController : weak< inkButtonController >;
	private var m_hoverAnimation : inkAnimProxy;
	private var m_hoverAnimationOptions : inkAnimOptions;
	private var m_isEp1Released : Bool;

	protected event OnInitialize()
	{
		m_buyButtonController = ( ( inkButtonController )( inkWidgetRef.GetControllerByType( m_buyButtonRef, 'inkButtonController' ) ) );
		m_videoCarouselController = ( ( VideoCarouselController )( inkWidgetRef.GetController( m_videoCarouselRef ) ) );
		m_videoCarouselController.PopulateVideos( m_videoCarouselData );
		inkWidgetRef.RegisterToCallback( m_videoContainerRef, 'OnHoverOver', this, 'OnHoverVideo' );
		inkWidgetRef.RegisterToCallback( m_videoContainerRef, 'OnHoverOut', this, 'OnHoverOutVideo' );
		inkWidgetRef.RegisterToCallback( m_slectorContainerRef, 'OnHoverOver', this, 'OnHoverSelector' );
		inkWidgetRef.RegisterToCallback( m_slectorContainerRef, 'OnHoverOut', this, 'OnHoverOutSelector' );
		inkWidgetRef.SetVisible( m_slectorArrowLeftRef, false );
		inkWidgetRef.SetVisible( m_slectorArrowRightRef, false );
		SetState( ExpansionStatus.Available );
	}

	protected event OnUninitialize()
	{
		inkWidgetRef.UnregisterFromCallback( m_videoContainerRef, 'OnHoverOver', this, 'OnHoverVideo' );
		inkWidgetRef.UnregisterFromCallback( m_videoContainerRef, 'OnHoverOut', this, 'OnHoverOutVideo' );
		inkWidgetRef.UnregisterFromCallback( m_slectorContainerRef, 'OnHoverOver', this, 'OnHoverSelector' );
		inkWidgetRef.UnregisterFromCallback( m_slectorContainerRef, 'OnHoverOut', this, 'OnHoverOutSelector' );
	}

	public function SetState( state : ExpansionStatus )
	{
		if( state == ExpansionStatus.Processing )
		{
			inkTextRef.SetText( m_buyButtonText, GetLocalizedTextByKey( 'UI-DLC-EP1-PurchaseFlow-Processing' ) );
			inkWidgetRef.SetVisible( m_buyButtonInputIcon, false );
			m_buyButtonController.SetEnabled( false );
			inkWidgetRef.SetInteractive( m_buyButtonRef, false );
			inkWidgetRef.SetVisible( m_buyButtonSpinner, true );
			PlaySpinAnimation();
		}
		else
		{
			inkTextRef.SetText( m_buyButtonText, GetLocalizedTextByKey( ( ( m_isEp1Released ) ? ( m_locKey_Buy ) : ( m_locKey_PreOrder ) ) ) );
			inkWidgetRef.SetVisible( m_buyButtonInputIcon, true );
			m_buyButtonController.SetEnabled( true );
			inkWidgetRef.SetInteractive( m_buyButtonRef, true );
			inkWidgetRef.SetVisible( m_buyButtonSpinner, false );
			PlaySpinAnimation();
		}
	}

	private function PlaySpinAnimation()
	{
		var playbackOptions : inkAnimOptions;
		playbackOptions.loopInfinite = true;
		playbackOptions.loopType = inkanimLoopType.Cycle;
		PlayLibraryAnimation( 'spin', playbackOptions );
	}

	public function GetButtonRef() : inkWidgetRef
	{
		return m_buyButtonRef;
	}

	public function SetIsEp1Released( isEp1Released : Bool )
	{
		m_isEp1Released = isEp1Released;
	}

	protected event OnHoverVideo( e : inkPointerEvent )
	{
		m_videoCarouselController.PauseVideo( true );
		if( m_hoverAnimation )
		{
			m_hoverAnimation.GotoEndAndStop();
		}
		m_hoverAnimationOptions.playReversed = false;
		m_hoverAnimation = PlayLibraryAnimation( m_hoverAnimationName, m_hoverAnimationOptions );
		inkImageRef.SetBrushMirrorType( m_hoverArrow, inkBrushMirrorType.Vertical );
	}

	protected event OnHoverOutVideo( e : inkPointerEvent )
	{
		m_videoCarouselController.PauseVideo( false );
		if( m_hoverAnimation )
		{
			m_hoverAnimation.GotoEndAndStop();
		}
		m_hoverAnimationOptions.playReversed = true;
		m_hoverAnimation = PlayLibraryAnimation( m_hoverAnimationName, m_hoverAnimationOptions );
		inkImageRef.SetBrushMirrorType( m_hoverArrow, inkBrushMirrorType.NoMirror );
	}

	protected event OnHoverSelector( e : inkPointerEvent )
	{
		inkWidgetRef.SetVisible( m_slectorArrowLeftRef, true );
		inkWidgetRef.SetVisible( m_slectorArrowRightRef, true );
	}

	protected event OnHoverOutSelector( e : inkPointerEvent )
	{
		inkWidgetRef.SetVisible( m_slectorArrowLeftRef, false );
		inkWidgetRef.SetVisible( m_slectorArrowRightRef, false );
	}

}

class ReloadingExpansionPopupController extends inkLogicController
{
	private editable var m_progressBarRef : inkWidgetRef;
	private editable var m_titleTextRef : inkTextRef;
	private editable var m_descriptionTextRef : inkTextRef;
	private editable var m_warningTextRef : inkTextRef;
	private var m_progressBarController : weak< LoadingScreenProgressBarController >;
	private var m_animProxy : inkAnimProxy;

	protected event OnInitialize()
	{
		m_progressBarController = ( ( LoadingScreenProgressBarController )( inkWidgetRef.GetController( m_progressBarRef ) ) );
		SetPlatformSpecificText();
	}

	public function UpdateProgress( progress : Float )
	{
		if( m_progressBarController )
		{
			m_progressBarController.SetProgress( progress );
		}
		if( progress >= 1.0 )
		{
			m_animProxy = PlayLibraryAnimation( 'reloadingFinished' );
			m_animProxy.RegisterToCallback( inkanimEventType.OnFinish, this, 'OnReloadingAnimationFinished' );
		}
	}

	private function SetPlatformSpecificText()
	{
		var platform : String;
		platform = GetPlatformShortName();
		if( platform == "xseriesx" || platform == "xseriess" )
		{
			inkTextRef.SetText( m_titleTextRef, GetLocalizedTextByKey( 'UI-DLC-EP1-Reloading-AdjustingSystemsBreach_XSX' ) );
			inkTextRef.SetText( m_descriptionTextRef, GetLocalizedTextByKey( 'UI-DLC-EP1-Reloading-AdjustingSystemsPopup_XSX' ) );
			inkTextRef.SetText( m_warningTextRef, GetLocalizedTextByKey( 'UI-DLC-EP1-Reloading-AdjustingSystemsPopupNote_XSX' ) );
		}
		else if( platform == "ps5" )
		{
			inkTextRef.SetText( m_titleTextRef, GetLocalizedTextByKey( 'UI-DLC-EP1-Reloading-AdjustingSystemsBreach_PS5' ) );
			inkTextRef.SetText( m_descriptionTextRef, GetLocalizedTextByKey( 'UI-DLC-EP1-Reloading-AdjustingSystemsPopup_PS5' ) );
			inkTextRef.SetText( m_warningTextRef, GetLocalizedTextByKey( 'UI-DLC-EP1-Reloading-AdjustingSystemsPopupNote_PS5' ) );
		}
		else
		{
			inkTextRef.SetText( m_titleTextRef, GetLocalizedTextByKey( 'UI-DLC-EP1-AdjustingSystemsBreach' ) );
			inkTextRef.SetText( m_descriptionTextRef, GetLocalizedTextByKey( 'UI-DLC-EP1-AdjustingSystemsPopup' ) );
			inkTextRef.SetText( m_warningTextRef, GetLocalizedTextByKey( 'UI-DLC-EP1-AdjustingSystemsPopupNote' ) );
		}
	}

	protected event OnReloadingAnimationFinished( proxy : inkAnimProxy )
	{
		var evt : ReloadingExpansionPopupCloseEvent;
		evt = new ReloadingExpansionPopupCloseEvent;
		QueueBroadcastEvent( evt );
	}

}

class ReloadingExpansionPopupCloseEvent extends Event
{
}

class PreOrderPopupController extends inkLogicController
{
	private editable var m_preOrderButtonRef : inkWidgetRef;
	private editable var m_preOrderButtonText : inkTextRef;
	private editable var m_preOrderButtonInputIcon : inkWidgetRef;
	private editable var m_releaseDateContainer : inkWidgetRef;
	private var m_buttonController : weak< inkButtonController >;

	protected event OnInitialize()
	{
		m_buttonController = ( ( inkButtonController )( inkWidgetRef.GetControllerByType( m_preOrderButtonRef, 'inkButtonController' ) ) );
	}

	public function GetButtonRef() : inkWidgetRef
	{
		return m_preOrderButtonRef;
	}

	public function SetPreOrderSate( isPreOredOwned : Bool )
	{
		if( isPreOredOwned )
		{
			inkTextRef.SetText( m_preOrderButtonText, GetLocalizedTextByKey( 'UI-DLC-EP1-PurchaseFlow-EP1Popup-Purchased' ) );
			inkWidgetRef.SetVisible( m_preOrderButtonInputIcon, false );
			m_buttonController.SetEnabled( false );
			inkWidgetRef.SetInteractive( m_preOrderButtonRef, false );
			inkWidgetRef.SetVisible( m_releaseDateContainer, true );
		}
		else
		{
			inkTextRef.SetText( m_preOrderButtonText, GetLocalizedTextByKey( 'UI-DLC-EP1-PurchaseFlow-MainMenuBanner-PreOrderNow' ) );
			inkWidgetRef.SetVisible( m_preOrderButtonInputIcon, true );
			m_buttonController.SetEnabled( true );
			inkWidgetRef.SetInteractive( m_preOrderButtonRef, true );
			inkWidgetRef.SetVisible( m_releaseDateContainer, false );
		}
	}

}

