class QuickHackMappinController extends BaseInteractionMappinController
{
	private editable var m_bar : inkWidgetRef;
	private editable var m_header : inkTextRef;
	private editable var m_iconWidgetActive : inkImageRef;
	private var m_rootWidget : weak< inkWidget >;
	private var m_mappin : weak< IMappin >;
	private var m_data : GameplayRoleMappinData;
	private const editable var m_queueQuickHackWidgets : array< inkWidgetRef >;
	private var m_queueQuickHackControllers : array< weak< QuickHackQueueItem > >;
	private var m_mappinDataQueue : array< GameplayRoleMappinData >;
	private var m_animUpload : inkAnimProxy;
	private var m_animQueue : inkAnimProxy;

	protected event OnInitialize()
	{
		var i : Int32;
		m_rootWidget = GetRootWidget();
		for( i = 0; i < m_queueQuickHackWidgets.Size(); i += 1 )
		{
			m_queueQuickHackControllers.PushBack( ( ( QuickHackQueueItem )( inkWidgetRef.GetController( m_queueQuickHackWidgets[ i ] ) ) ) );
			m_queueQuickHackControllers[ i ].Hide();
		}
	}

	protected event OnIntro()
	{
		var translationAnimationCtrl : weak< inkTextReplaceController >;
		var localizedText : String;
		m_mappin = GetMappin();
		m_data = GetVisualData();
		HelperSetIcon( iconWidget, m_data.m_textureID );
		HelperSetIcon( m_iconWidgetActive, m_data.m_textureID );
		UpdateView();
		m_animUpload = PlayLibraryAnimation( 'upload' );
		localizedText = GetLocalizedText( "LocKey#11047" );
		translationAnimationCtrl = ( ( inkTextReplaceController )( inkTextRef.GetController( m_header ) ) );
		translationAnimationCtrl.SetBaseText( "..." );
		translationAnimationCtrl.SetTargetText( localizedText );
		translationAnimationCtrl.PlaySetAnimation();
	}

	public function UploadComplete()
	{
		m_animUpload = PlayLibraryAnimation( 'upload_complete' );
		m_animUpload.RegisterToCallback( inkanimEventType.OnFinish, this, 'OnUploadCompleteFinished' );
	}

	protected event OnUploadCompleteFinished( anim : inkAnimProxy )
	{
		UpdateQueue();
	}

	public function UpdateQueue()
	{
		m_animQueue = PlayLibraryAnimation( 'queue_move_up' );
		m_animQueue.RegisterToCallback( inkanimEventType.OnFinish, this, 'OnQueueMovedUp' );
	}

	protected event OnQueueMovedUp( anim : inkAnimProxy )
	{
		var i : Int32;
		m_animUpload = PlayLibraryAnimation( 'upload' );
		m_animUpload.GotoEndAndStop();
		m_animQueue = PlayLibraryAnimation( 'queue_move_up' );
		m_animQueue.GotoStartAndStop();
		m_data = m_mappinDataQueue[ 0 ];
		HelperSetIcon( iconWidget, m_data.m_textureID );
		HelperSetIcon( m_iconWidgetActive, m_data.m_textureID );
		UpdateView();
		for( i = 0; i < ( m_mappinDataQueue.Size() - 1 ); i += 1 )
		{
			m_queueQuickHackControllers[ i ].Setup( m_mappinDataQueue[ i + 1 ] );
		}
		m_queueQuickHackControllers[ m_mappinDataQueue.Size() - 1 ].Hide();
		m_mappinDataQueue.Erase( 0 );
	}

	protected event OnNameplate( isNameplateVisible : Bool, nameplateController : weak< NpcNameplateGameController > )
	{
		if( isNameplateVisible )
		{
			SetProjectToScreenSpace( false );
		}
		else
		{
			SetProjectToScreenSpace( true );
		}
	}

	protected event OnQueueQuickHackEvent( evt : QueueQuickHackEvent )
	{
		var queueController : weak< QuickHackQueueItem >;
		if( evt.mappinID != m_mappin.GetNewMappinID() )
		{
			return 0;
		}
		if( m_data.m_progressBarType == EProgressBarType.DURATION )
		{
			return 0;
		}
		m_mappinDataQueue.PushBack( evt.data );
		queueController = m_queueQuickHackControllers[ m_mappinDataQueue.Size() - 1 ];
		queueController.Setup( evt.data );
		queueController.Upload();
	}

	protected event OnDequeueQuickHackEvent( evt : DequeueQuickHackEvent )
	{
		if( evt.mappinID != m_mappin.GetNewMappinID() )
		{
			return 0;
		}
		if( m_data.m_progressBarType == EProgressBarType.DURATION )
		{
			return 0;
		}
		UploadComplete();
	}

	private export function OnStatsDataUpdated( progress : Float )
	{
		m_data = GetVisualData();
		if( m_data.m_progressBarType == EProgressBarType.UPLOAD )
		{
			inkWidgetRef.SetScale( m_bar, Vector2( 2.0, progress ) );
		}
		else if( m_data.m_progressBarType == EProgressBarType.DURATION )
		{
			inkWidgetRef.SetScale( m_bar, Vector2( 2.0, 1.0 - progress ) );
		}
		UpdateView();
	}

	private function UpdateView()
	{
		if( m_data.m_progressBarContext == EProgressBarContext.QuickHack )
		{
			if( m_data.m_progressBarType == EProgressBarType.UPLOAD )
			{
				inkTextRef.SetVisible( m_header, false );
				m_rootWidget.SetState( ( ( m_data.m_action.m_IsAppliedByMonowire ) ? ( 'Relic' ) : ( 'Upload' ) ) );
			}
			else if( m_data.m_progressBarType == EProgressBarType.DURATION )
			{
				m_rootWidget.SetState( 'Default' );
			}
		}
		else if( m_data.m_progressBarContext == EProgressBarContext.PhoneCall )
		{
			inkTextRef.SetText( m_header, "LocKey#2142" );
			m_rootWidget.SetState( 'Default' );
		}
	}

	public const override function GetVisualData() : GameplayRoleMappinData
	{
		var data : GameplayRoleMappinData;
		data = ( ( GameplayRoleMappinData )( m_mappin.GetScriptData() ) );
		return data;
	}

	public function Fold()
	{
		var animOptions : inkAnimOptions;
		animOptions.playReversed = true;
		PlayLibraryAnimation( 'unfold', animOptions );
	}

	public function Unfold()
	{
		PlayLibraryAnimation( 'unfold' );
	}

	private function HelperSetIcon( currImage : inkImageRef, iconID : TweakDBID )
	{
		if( TDBID.IsValid( iconID ) )
		{
			SetTexture( currImage, iconID );
		}
	}

}

class QuickHackQueueItem extends inkLogicController
{
	private editable var m_icon : inkImageRef;
	private var m_data : GameplayRoleMappinData;
	private var m_anim : inkAnimProxy;

	public function Setup( data : GameplayRoleMappinData )
	{
		m_data = data;
		SetTexture( m_icon, m_data.m_textureID );
	}

	public function Upload()
	{
		Show();
		m_anim = PlayLibraryAnimation( 'upload_queue' );
	}

	public function Show()
	{
		GetRootWidget().SetVisible( true );
	}

	public function Hide()
	{
		GetRootWidget().SetVisible( false );
	}

}

class QueueQuickHackEvent extends Event
{
	var mappinID : NewMappinID;
	var data : GameplayRoleMappinData;
}

class DequeueQuickHackEvent extends Event
{
	var mappinID : NewMappinID;
}

