class ShardNotificationController extends inkGameController
{
	private editable var m_titleRef : inkTextRef;
	private editable var m_shortTextRef : inkTextRef;
	private editable var m_longTextRef : inkTextRef;
	private editable var m_shortTextHolderRef : inkWidgetRef;
	private editable var m_longTextHolderRef : inkWidgetRef;
	private editable var m_buttonHintsManagerRef : inkWidgetRef;
	private editable var m_buttonHintsManagerParentRef : inkWidgetRef;
	private editable var m_buttonHintsSecondaryManagerRef : inkWidgetRef;
	private editable var m_buttonHintsSecondaryManagerParentRef : inkWidgetRef;
	private editable var m_imageWidget : inkImageRef;
	private editable var m_scrollWidget : inkWidgetRef;
	private var m_data : ShardReadPopupData;
	private var m_longTextTrashold : Int32;
	default m_longTextTrashold = 1000;
	private var m_animationProxy : inkAnimProxy;
	private var m_player : weak< PlayerPuppet >;
	private var m_mingameBB : weak< IBlackboard >;
	private var m_scroll : weak< inkScrollController >;

	protected event OnInitialize()
	{
		var shardText : String;
		var iconRecord : UIIcon_Record;
		RegisterToGlobalInputCallback( 'OnPostOnRelease', this, 'OnRelease' );
		m_data = ( ( ShardReadPopupData )( GetRootWidget().GetUserData( 'ShardReadPopupData' ) ) );
		shardText = CodexUtils.GetShardTextString( m_data.isCrypted, m_data.text );
		inkTextRef.SetText( m_longTextRef, shardText );
		inkTextRef.SetText( m_titleRef, CodexUtils.GetShardTitleString( m_data.isCrypted, m_data.title ) );
		SetButtonHints();
		PlayAnim( 'intro', 'OnIntroComplete' );
		if( TDBID.IsValid( m_data.m_imageId ) )
		{
			iconRecord = TweakDBInterface.GetUIIconRecord( m_data.m_imageId );
			inkImageRef.SetVisible( m_imageWidget, true );
			inkImageRef.SetAtlasResource( m_imageWidget, iconRecord.AtlasResourcePath() );
			inkImageRef.SetTexturePart( m_imageWidget, iconRecord.AtlasPartName() );
		}
		else
		{
			inkImageRef.SetVisible( m_imageWidget, false );
		}
	}

	protected event OnUninitialize()
	{
		UnregisterFromGlobalInputCallback( 'OnPostOnRelease', this, 'OnRelease' );
		GetSystemRequestsHandler().UnpauseGame();
	}

	protected event OnPlayerAttach( playerPuppet : GameObject )
	{
		m_player = ( ( PlayerPuppet )( playerPuppet ) );
		PauseGameState( true );
	}

	protected event OnRelease( evt : inkPointerEvent )
	{
		if( evt.IsAction( 'OpenPauseMenu' ) )
		{
			evt.Handle();
			Close();
		}
		if( evt.IsAction( 'cancel' ) )
		{
			Close();
		}
		if( evt.IsAction( 'one_click_confirm' ) )
		{
			LaunchMinigame();
		}
	}

	protected event OnCloseClick( controller : weak< inkButtonController > )
	{
		Close();
	}

	protected event OnCrackClick( controller : weak< inkButtonController > )
	{
		LaunchMinigame();
	}

	protected event OnIntroComplete( anim : inkAnimProxy )
	{
		PlaySound( 'ShardPanel', 'OnOpen' );
	}

	private function Close()
	{
		if( m_animationProxy && m_animationProxy.IsPlaying() )
		{
			m_animationProxy.Stop();
			m_animationProxy.UnregisterFromCallback( inkanimEventType.OnFinish, this, 'OnIntroComplete' );
		}
		PlaySound( 'ShardPanel', 'OnClose' );
		PauseGameState( false );
		m_data.token.TriggerCallback( m_data );
	}

	private function PauseGameState( enable : Bool )
	{
		var uiSystem : UISystem;
		uiSystem = GameInstance.GetUISystem( m_player.GetGame() );
		if( enable )
		{
			GetSystemRequestsHandler().PauseGame();
			uiSystem.PushGameContext( UIGameContext.ModalPopup );
			uiSystem.RequestNewVisualState( 'inkModalPopupState' );
			PopupStateUtils.SetBackgroundBlur( this, true );
		}
		else
		{
			GetSystemRequestsHandler().UnpauseGame();
			uiSystem.PopGameContext( UIGameContext.ModalPopup );
			uiSystem.RestorePreviousVisualState( 'inkModalPopupState' );
			PopupStateUtils.SetBackgroundBlur( this, false );
		}
	}

	private function SetButtonHints()
	{
		AddButtonHints( 'cancel', 'Common-Access-Close', m_buttonHintsManagerParentRef, 'OnCloseClick' );
		inkWidgetRef.SetVisible( m_buttonHintsSecondaryManagerParentRef, m_data.isCrypted );
		if( m_data.isCrypted )
		{
			AddButtonHints( 'one_click_confirm', 'UI-Notifications-Crack', m_buttonHintsSecondaryManagerParentRef, 'OnCrackClick' );
		}
	}

	private function LaunchMinigame()
	{
		m_mingameBB = GameInstance.GetBlackboardSystem( m_player.GetGame() ).Get( GetAllBlackboardDefs().HackingMinigame );
		m_mingameBB.SetBool( GetAllBlackboardDefs().HackingMinigame.IsJournalTarget, false );
		ItemActionsHelper.PerformItemAction( m_player, m_data.itemID );
		Close();
	}

	private function AddButtonHints( actionName : CName, label : CName, buttonHintRef : inkWidgetRef, clickCallback : CName )
	{
		var buttonHint : LabelInputDisplayController;
		var widget : weak< inkWidget >;
		var buttonController : weak< inkButtonController >;
		buttonController = ( ( inkButtonController )( inkWidgetRef.GetController( buttonHintRef ) ) );
		buttonController.RegisterToCallback( 'OnButtonClick', this, clickCallback );
		widget = SpawnFromExternal( inkWidgetRef.Get( buttonHintRef ), R"base\gameplay\gui\common\buttons\base_buttons.inkwidget", 'inputDisplayLabelFlex' );
		buttonHint = ( ( LabelInputDisplayController )( widget.GetController() ) );
		buttonHint.SetInputActionLabel( actionName, GetLocalizedTextByKey( label ) );
		widget.SetHAlign( inkEHorizontalAlign.Center );
		widget.SetVAlign( inkEVerticalAlign.Center );
		widget.SetMargin( inkMargin( 20.0, 0.0, 20.0, 0.0 ) );
	}

	public function PlayAnim( animName : CName, optional callBack : CName )
	{
		if( m_animationProxy && m_animationProxy.IsPlaying() )
		{
			m_animationProxy.Stop();
		}
		m_animationProxy = PlayLibraryAnimation( animName );
		if( callBack != '' )
		{
			m_animationProxy.RegisterToCallback( inkanimEventType.OnFinish, this, callBack );
		}
	}

}

class NotifyShardRead extends Event
{
	var entry : JournalOnscreen;
	var title : String;
	var text : String;
	var isCrypted : Bool;
	var itemID : ItemID;
	var m_imageId : TweakDBID;
}

class ShardReadPopupData extends inkGameNotificationData
{
	var title : String;
	var text : String;
	var isCrypted : Bool;
	var itemID : ItemID;
	var m_imageId : TweakDBID;
}

