class BriefingScreen extends inkHUDGameController
{
	editable var m_logicControllerRef : inkWidgetRef;
	protected var m_journalManager : weak< JournalManager >;
	private var m_bbOpenerEventID : CallbackHandle;
	private var m_bbSizeEventID : CallbackHandle;
	private var m_bbAlignmentEventID : CallbackHandle;

	protected event OnInitialize()
	{
		m_journalManager = GameInstance.GetJournalManager( ( ( GameObject )( GetPlayerControlledObject() ) ).GetGame() );
		m_bbOpenerEventID = GetBlackboardSystem().Get( GetAllBlackboardDefs().UI_Briefing ).RegisterDelayedListenerString( GetAllBlackboardDefs().UI_Briefing.BriefingToOpen, this, 'OnBriefingOpenerCalled' );
		m_bbSizeEventID = GetBlackboardSystem().Get( GetAllBlackboardDefs().UI_Briefing ).RegisterDelayedListenerVariant( GetAllBlackboardDefs().UI_Briefing.BriefingSize, this, 'OnBriefingSizeCalled' );
		m_bbAlignmentEventID = GetBlackboardSystem().Get( GetAllBlackboardDefs().UI_Briefing ).RegisterDelayedListenerVariant( GetAllBlackboardDefs().UI_Briefing.BriefingAlignment, this, 'OnBriefingAlignmentCalled' );
	}

	protected event OnBriefingOpenerCalled( value : String )
	{
		var context : JournalRequestContext;
		var entries : array< weak< JournalEntry > >;
		var childEntries : array< weak< JournalEntry > >;
		var logicController : BriefingScreenLogic;
		var parent : String;
		var target : String;
		var parentEntry : weak< JournalEntry >;
		var targetEntry : weak< JournalEntry >;
		StrSplitLast( StrLower( value ), "/", parent, target );
		context.stateFilter.active = true;
		m_journalManager.GetBriefings( context, entries );
		parentEntry = FindEntry( parent, entries );
		m_journalManager.GetChildren( parentEntry, context.stateFilter, childEntries );
		targetEntry = FindEntry( target, childEntries );
		logicController = ( ( BriefingScreenLogic )( inkWidgetRef.GetController( m_logicControllerRef ) ) );
		logicController.ShowBriefing( targetEntry );
	}

	protected event OnBriefingSizeCalled( value : Variant )
	{
		var logicController : BriefingScreenLogic;
		logicController = ( ( BriefingScreenLogic )( inkWidgetRef.GetController( m_logicControllerRef ) ) );
		logicController.SetSize( ( ( questJournalSizeEventType )value ) );
	}

	protected event OnBriefingAlignmentCalled( value : Variant )
	{
		var logicController : BriefingScreenLogic;
		logicController = ( ( BriefingScreenLogic )( inkWidgetRef.GetController( m_logicControllerRef ) ) );
		logicController.SetAlignment( ( ( questJournalAlignmentEventType )value ) );
	}

	private function FindEntry( const toFind : ref< String >, const entries : ref< array< weak< JournalEntry > > > ) : JournalEntry
	{
		var i : Int32;
		for( i = 0; i < entries.Size(); i += 1 )
		{
			if( entries[ i ].GetId() == toFind )
			{
				return entries[ i ];
			}
		}
		return NULL;
	}

	protected event OnUninitialize()
	{
		GetBlackboardSystem().Get( GetAllBlackboardDefs().UI_Briefing ).UnregisterDelayedListener( GetAllBlackboardDefs().UI_Briefing.BriefingToOpen, m_bbOpenerEventID );
		GetBlackboardSystem().Get( GetAllBlackboardDefs().UI_Briefing ).UnregisterDelayedListener( GetAllBlackboardDefs().UI_Briefing.BriefingSize, m_bbSizeEventID );
		GetBlackboardSystem().Get( GetAllBlackboardDefs().UI_Briefing ).UnregisterDelayedListener( GetAllBlackboardDefs().UI_Briefing.BriefingAlignment, m_bbAlignmentEventID );
	}

}

class BriefingScreenLogic extends inkLogicController
{
	protected var m_lastSizeSet : Vector2;
	protected var m_isBriefingVisible : Bool;
	protected var m_briefingToOpen : weak< JournalEntry >;
	private editable var m_videoWidget : inkVideoRef;
	private editable var m_mapWidget : inkWidgetRef;
	private editable var m_paperdollWidget : inkWidgetRef;
	private editable var m_animatedWidget : inkWidgetRef;
	private editable var m_fadeDuration : Float;
	private editable var m_InterpolationType : inkanimInterpolationType;
	private editable var m_InterpolationMode : inkanimInterpolationMode;
	private editable var m_minimizedSize : Vector2;
	private editable var m_maximizedSize : Vector2;

	protected event OnInitialize()
	{
		HideAll();
		m_lastSizeSet = m_minimizedSize;
		m_isBriefingVisible = false;
	}

	public function ShowBriefing( briefingToOpen : weak< JournalEntry > )
	{
		m_briefingToOpen = briefingToOpen;
		if( m_isBriefingVisible )
		{
			Fade( 1.0, 0.0, 'OnFadeOutEnd' );
		}
		else
		{
			SetBriefing();
		}
	}

	private function SetBriefing()
	{
		var toOpen : JournalBriefingBaseSection;
		HideAll();
		if( m_briefingToOpen )
		{
			toOpen = ( ( JournalBriefingBaseSection )( m_briefingToOpen ) );
			switch( toOpen.GetType() )
			{
				case gameJournalBriefingContentType.MapLocation:
					ProcessMap( ( ( JournalBriefingMapSection )( m_briefingToOpen ) ) );
				break;
				case gameJournalBriefingContentType.VideoContent:
					ProcessVideo( ( ( JournalBriefingVideoSection )( m_briefingToOpen ) ) );
				break;
				case gameJournalBriefingContentType.Paperdoll:
					ProcessPaperdoll( ( ( JournalBriefingPaperDollSection )( m_briefingToOpen ) ) );
				break;
			}
			Fade( 0.0, 1.0, 'OnFadeInEnd' );
			m_briefingToOpen = NULL;
		}
	}

	protected event OnFadeInEnd( proxy : inkAnimProxy )
	{
		m_isBriefingVisible = true;
	}

	protected event OnFadeOutEnd( proxy : inkAnimProxy )
	{
		m_isBriefingVisible = false;
		SetBriefing();
	}

	private function ProcessMap( toProcess : JournalBriefingMapSection )
	{
		GetRootWidget().SetVisible( true );
		inkWidgetRef.SetVisible( m_mapWidget, true );
	}

	private function ProcessVideo( toProcess : JournalBriefingVideoSection )
	{
		GetRootWidget().SetVisible( true );
		inkVideoRef.SetVisible( m_videoWidget, true );
		inkVideoRef.SetVideoPath( m_videoWidget, toProcess.GetVideoPath() );
		inkVideoRef.Play( m_videoWidget );
	}

	private function ProcessPaperdoll( toProcess : JournalBriefingPaperDollSection )
	{
		GetRootWidget().SetVisible( true );
		inkWidgetRef.SetVisible( m_paperdollWidget, true );
	}

	private function Fade( startValue : Float, endValue : Float, callbackName : CName )
	{
		var animProxy : inkAnimProxy;
		var anim : inkAnimDef;
		var alphaInterpolator : inkAnimTransparency;
		anim = new inkAnimDef;
		alphaInterpolator = new inkAnimTransparency;
		alphaInterpolator.SetDuration( m_fadeDuration );
		alphaInterpolator.SetStartTransparency( startValue );
		alphaInterpolator.SetEndTransparency( endValue );
		alphaInterpolator.SetMode( m_InterpolationMode );
		alphaInterpolator.SetType( m_InterpolationType );
		anim.AddInterpolator( alphaInterpolator );
		animProxy = inkWidgetRef.PlayAnimation( m_animatedWidget, anim );
		animProxy.RegisterToCallback( inkanimEventType.OnFinish, this, callbackName );
	}

	public function SetSize( sizeToSet : questJournalSizeEventType )
	{
		var anim : inkAnimDef;
		var sizeInterpolator : inkAnimSize;
		var targetSize : Vector2;
		anim = new inkAnimDef;
		sizeInterpolator = new inkAnimSize;
		switch( sizeToSet )
		{
			case questJournalSizeEventType.Maximize:
				targetSize = m_maximizedSize;
			break;
			case questJournalSizeEventType.Minimize:
				targetSize = m_minimizedSize;
			break;
		}
		sizeInterpolator.SetStartSize( m_lastSizeSet );
		sizeInterpolator.SetEndSize( targetSize );
		sizeInterpolator.SetDuration( m_fadeDuration );
		sizeInterpolator.SetMode( m_InterpolationMode );
		sizeInterpolator.SetType( m_InterpolationType );
		anim.AddInterpolator( sizeInterpolator );
		inkWidgetRef.PlayAnimation( m_animatedWidget, anim );
		m_lastSizeSet = targetSize;
	}

	public function SetAlignment( alignmentToSet : questJournalAlignmentEventType )
	{
		var targetAnchor : inkEAnchor;
		var xAnchorPoint : Float;
		switch( alignmentToSet )
		{
			case questJournalAlignmentEventType.Left:
				targetAnchor = inkEAnchor.TopLeft;
			xAnchorPoint = 0.0;
			break;
			case questJournalAlignmentEventType.Center:
				targetAnchor = inkEAnchor.TopCenter;
			xAnchorPoint = 0.5;
			break;
			case questJournalAlignmentEventType.Right:
				targetAnchor = inkEAnchor.TopRight;
			xAnchorPoint = 1.0;
			break;
		}
		inkWidgetRef.SetAnchor( m_animatedWidget, targetAnchor );
		inkWidgetRef.SetAnchorPoint( m_animatedWidget, xAnchorPoint, 0.0 );
	}

	private function HideAll()
	{
		GetRootWidget().SetVisible( false );
		inkVideoRef.SetVisible( m_videoWidget, false );
		inkWidgetRef.SetVisible( m_mapWidget, false );
		inkWidgetRef.SetVisible( m_paperdollWidget, false );
	}

}

