enum UIObjectiveEntryType
{
	Invalid = 0,
	Quest = 1,
	Objective = 2,
	SubObjective = 3,
}

struct UIObjectiveEntryData
{
	var m_name : String;
	var m_counter : String;
	var m_type : UIObjectiveEntryType;
	var m_state : gameJournalEntryState;
	var m_isTracked : Bool;
	var m_isOptional : Bool;
}

class ObjectiveEntryLogicController extends inkLogicController
{
	editable var m_blinkInterval : Float;
	default m_blinkInterval = 0.8f;
	editable var m_blinkTotalTime : Float;
	default m_blinkTotalTime = 5.0f;
	editable var m_texturePart_Tracked : CName;
	default m_texturePart_Tracked = 'tracked_left';
	editable var m_texturePart_Untracked : CName;
	default m_texturePart_Untracked = 'untracked_left';
	editable var m_texturePart_Succeeded : CName;
	default m_texturePart_Succeeded = 'succeeded';
	editable var m_texturePart_Failed : CName;
	default m_texturePart_Failed = 'failed';
	editable var m_isLargeUpdateWidget : Bool;
	default m_isLargeUpdateWidget = false;
	private var m_entryName : weak< inkText >;
	private var m_entryOptional : weak< inkText >;
	private var m_stateIcon : weak< inkImage >;
	private var m_trackedIcon : weak< inkImage >;
	private var m_blinkWidget : weak< inkWidget >;
	private var m_root : weak< inkWidget >;
	private var m_animBlinkDef : inkAnimDef;
	private var m_animBlink : inkAnimProxy;
	private var m_animFadeDef : inkAnimDef;
	private var m_animFade : inkAnimProxy;
	private var m_entryId : Int32;
	private var m_type : UIObjectiveEntryType;
	private var m_state : gameJournalEntryState;
	private var m_parentEntry : weak< ObjectiveEntryLogicController >;
	private var m_childCount : Int32;
	default m_childCount = 0;
	private var m_updated : Bool;
	private var m_isTracked : Bool;
	var m_isOptional : Bool;

	protected event OnInitialize()
	{
		m_root = GetRootWidget();
		m_blinkWidget = ( ( inkWidget )( GetWidget( 'temp_blinker' ) ) );
		m_stateIcon = ( ( inkImage )( GetWidget( 'temp_blinker/stateIcon' ) ) );
		m_entryName = ( ( inkText )( GetWidget( 'entryFlex/entryName' ) ) );
		m_entryOptional = ( ( inkText )( GetWidget( 'entryOptional' ) ) );
		m_trackedIcon = ( ( inkImage )( GetWidget( 'tracked' ) ) );
		CreateAnimations();
		m_blinkWidget.SetVisible( false );
		m_root.SetVisible( false );
	}

	public function SetUpdated( updated : Bool )
	{
		m_updated = updated;
	}

	public function IsUpdated() : Bool
	{
		return m_updated;
	}

	public function IsTracked() : Bool
	{
		return m_isTracked;
	}

	public function GetEntryType() : UIObjectiveEntryType
	{
		return m_type;
	}

	public function GetEntryState() : gameJournalEntryState
	{
		return m_state;
	}

	public function GetEntryId() : Int32
	{
		return m_entryId;
	}

	public function SetEntryId( id : Int32 )
	{
		m_entryId = id;
	}

	public function SetEntryData( const data : ref< UIObjectiveEntryData > )
	{
		var stateIconTexturePart : CName;
		var stateName : CName;
		m_root.SetVisible( false );
		SetUpdated( true );
		StopFadeAnimation();
		m_state = data.m_state;
		m_type = data.m_type;
		m_isTracked = data.m_isTracked;
		m_isOptional = data.m_isOptional;
		if( m_state == gameJournalEntryState.Inactive || data.m_name == "" )
		{
			NotifyForRemoval();
			return;
		}
		m_entryName.SetLetterCase( textLetterCase.UpperCase );
		if( m_isOptional )
		{
			m_entryName.SetText( ( ( m_type == UIObjectiveEntryType.Quest ) ? ( data.m_name ) : ( ( ( ( GetLocalizedText( data.m_name ) + ( ( String )( data.m_counter ) ) ) + " [" ) + GetLocalizedText( "UI-ScriptExports-Optional0" ) ) + "]" ) ) );
		}
		else
		{
			m_entryName.SetText( ( ( m_type == UIObjectiveEntryType.Quest ) ? ( data.m_name ) : ( GetLocalizedText( data.m_name ) + ( ( String )( data.m_counter ) ) ) ) );
		}
		stateIconTexturePart = GetStateIconTexturePart( m_state, data.m_isTracked );
		if( stateIconTexturePart == '' )
		{
			m_stateIcon.SetVisible( false );
		}
		else
		{
			m_stateIcon.SetTexturePart( stateIconTexturePart );
		}
		stateName = QuestUIUtils.GetJournalStateName( m_state, m_isTracked );
		m_trackedIcon.SetVisible( m_isTracked );
		m_entryName.SetState( stateName );
		m_entryOptional.SetState( stateName );
		GetRootWidget().SetState( stateName );
		if( m_state == gameJournalEntryState.Succeeded || m_state == gameJournalEntryState.Failed )
		{
			if( m_type != UIObjectiveEntryType.Quest )
			{
				if( m_state == gameJournalEntryState.Succeeded )
				{
					m_animBlink = PlayLibraryAnimation( 'ObjectiveEntryComplete' );
				}
				if( m_state == gameJournalEntryState.Failed )
				{
					m_animBlink = PlayLibraryAnimation( 'ObjectiveEntryFailed' );
				}
				m_animBlink.RegisterToCallback( inkanimEventType.OnFinish, this, 'OnAnimationComplete' );
			}
		}
		else if( m_state == gameJournalEntryState.Active )
		{
			Show();
		}
	}

	private function GetStateIconTexturePart( state : gameJournalEntryState, isTracked : Bool ) : CName
	{
		switch( state )
		{
			case gameJournalEntryState.Active:
				return ( ( isTracked ) ? ( m_texturePart_Tracked ) : ( m_texturePart_Untracked ) );
			case gameJournalEntryState.Succeeded:
				return m_texturePart_Succeeded;
			case gameJournalEntryState.Failed:
				return m_texturePart_Failed;
		}
		return '';
	}

	private function CreateAnimations()
	{
		var fadeOutInterp : inkAnimTransparency;
		var fadeInInterp : inkAnimTransparency;
		var fadeInterp : inkAnimTransparency;
		m_animBlinkDef = new inkAnimDef;
		fadeOutInterp = new inkAnimTransparency;
		fadeOutInterp.SetStartTransparency( 0.2 );
		fadeOutInterp.SetEndTransparency( 3.0 );
		fadeOutInterp.SetDuration( m_blinkInterval / 2.0 );
		fadeOutInterp.SetType( inkanimInterpolationType.Linear );
		m_animBlinkDef.AddInterpolator( fadeOutInterp );
		fadeInInterp = new inkAnimTransparency;
		fadeInInterp.SetStartTransparency( 0.2 );
		fadeInInterp.SetEndTransparency( 3.0 );
		fadeInInterp.SetDuration( m_blinkInterval / 2.0 );
		fadeInInterp.SetType( inkanimInterpolationType.Linear );
		m_animBlinkDef.AddInterpolator( fadeInInterp );
		m_animFadeDef = new inkAnimDef;
		fadeInterp = new inkAnimTransparency;
		fadeInterp.SetStartTransparency( 1.0 );
		fadeInterp.SetEndTransparency( 1.0 );
		fadeInterp.SetDuration( 0.0 );
		fadeInterp.SetDirection( inkanimInterpolationDirection.To );
		fadeInterp.SetType( inkanimInterpolationType.Linear );
		m_animFadeDef.AddInterpolator( fadeInterp );
	}

	public function IsReadyToRemove() : Bool
	{
		return !( m_state == gameJournalEntryState.Active );
	}

	protected event OnAnimationComplete( anim : inkAnimProxy )
	{
		m_root.SetVisible( false );
		NotifyForRemoval();
	}

	private function NotifyForRemoval()
	{
		CallCustomCallback( 'OnReadyToRemove' );
	}

	public function Hide()
	{
		if( m_type == UIObjectiveEntryType.Quest )
		{
			m_root.SetVisible( false );
			NotifyForRemoval();
			return;
		}
		if( m_state == gameJournalEntryState.Succeeded || m_state == gameJournalEntryState.Failed )
		{
			return;
		}
		if( m_animBlink.IsPlaying() )
		{
			m_animBlink.Stop();
		}
		m_animBlink = PlayLibraryAnimation( 'ObjectiveEntryFadeOut' );
		m_animBlink.RegisterToCallback( inkanimEventType.OnFinish, this, 'OnAnimationComplete' );
	}

	private function StopFadeAnimation()
	{
		if( m_animBlink && m_animBlink.IsPlaying() )
		{
			m_animBlink.UnregisterFromCallback( inkanimEventType.OnFinish, this, 'OnAnimationComplete' );
			m_animBlink.Stop();
		}
		if( m_animFade && m_animFade.IsPlaying() )
		{
			m_animFade.UnregisterFromCallback( inkanimEventType.OnFinish, this, 'OnAnimationComplete' );
			m_animFade.Stop();
		}
		m_root.SetOpacity( 1.0 );
	}

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

	public function AttachToParent( parentEntry : weak< ObjectiveEntryLogicController > )
	{
		m_parentEntry = parentEntry;
		m_parentEntry.IncrementChildCount();
	}

	public function DetachFromParent()
	{
		m_parentEntry.DecrementChildCount();
		m_parentEntry = NULL;
	}

	public function IncrementChildCount()
	{
		m_childCount += 1;
	}

	public function DecrementChildCount()
	{
		m_childCount -= 1;
	}

}

