class DelayedHighlightUpdateEvent extends Event
{
}

class PhoneDialerSelectionController extends SelectorController
{
	protected editable var m_leftArrowWidget : inkWidgetRef;
	protected editable var m_rightArrowWidget : inkWidgetRef;
	protected editable var m_container : inkCompoundRef;
	protected editable var m_line : inkWidgetRef;
	protected var m_leftArrowController : weak< inkInputDisplayController >;
	protected var m_rightArrowController : weak< inkInputDisplayController >;
	protected var m_widgetsControllers : array< weak< HubMenuLabelContentContainer > >;
	private var m_lineTranslationAnimProxy : inkAnimProxy;
	private var m_lineSizeAnimProxy : inkAnimProxy;
	private var m_animationsRetryDiv : Float;
	private var m_highlightInitialized : Bool;
	private var m_currentIndex : Int32;

	protected event OnInitialize()
	{
		m_leftArrowController = ( ( inkInputDisplayController )( inkWidgetRef.GetController( m_leftArrowWidget ) ) );
		m_rightArrowController = ( ( inkInputDisplayController )( inkWidgetRef.GetController( m_rightArrowWidget ) ) );
		m_currentIndex = -1;
		m_highlightInitialized = false;
		SetupWidgets();
	}

	public function SetupWidgets()
	{
		var i : Int32;
		var widget : weak< inkWidget >;
		var controller : HubMenuLabelContentContainer;
		for( i = 0; i < inkCompoundRef.GetNumChildren( m_container ); i += 1 )
		{
			widget = inkCompoundRef.GetWidget( m_container, i );
			controller = ( ( HubMenuLabelContentContainer )( widget.GetController() ) );
			m_widgetsControllers.PushBack( controller );
		}
		UpdateArrowsVisibility();
	}

	public function HideTab( index : Int32 )
	{
		inkCompoundRef.GetWidget( m_container, index ).SetVisible( false );
		QueueEvent( new DelayedHighlightUpdateEvent );
	}

	private function UpdateArrowsVisibility()
	{
		m_leftArrowController.SetVisible( inkCompoundRef.GetNumChildren( m_container ) > 1 );
		m_rightArrowController.SetVisible( inkCompoundRef.GetNumChildren( m_container ) > 1 );
	}

	public function ScrollTo( index : Int32, optional instant : Bool )
	{
		m_currentIndex = index;
		QueueEvent( new DelayedHighlightUpdateEvent );
	}

	protected virtual function UpdateHightlight( index : Int32, optional instant : Bool )
	{
		var width : Float;
		var position : Vector2;
		var time : Float;
		width = m_widgetsControllers[ index ].GetWidth() + 2.0;
		if( !( m_highlightInitialized ) && ( width > 2.0 ) )
		{
			m_highlightInitialized = true;
		}
		position = ( ( weak< weak< inkCompoundWidget > > )( inkCompoundRef.Get( m_container ) ) ).GetChildPosition( m_widgetsControllers[ index ].GetRootWidget() );
		UpdateLabelsStates( index );
		if( instant )
		{
			m_animationsRetryDiv = 0.0;
			m_lineTranslationAnimProxy.Stop();
			m_lineSizeAnimProxy.Stop();
			inkWidgetRef.SetTranslation( m_line, Vector2( position.X, 0.0 ) );
			inkWidgetRef.SetSize( m_line, Vector2( width, inkWidgetRef.GetHeight( m_line ) ) );
		}
		else
		{
			m_animationsRetryDiv += 0.5;
			time = 0.44999999 / MaxF( m_animationsRetryDiv, 1.0 );
			time = MaxF( time, 0.2 );
			AnimateLineTranslation( inkWidgetRef.Get( m_line ), position.X, time );
			AnimateLineSize( inkWidgetRef.Get( m_line ), width, time );
		}
	}

	protected virtual function UpdateLabelsStates( currentIndex : Int32 )
	{
		var i, limit : Int32;
		for( i = 0, limit = m_widgetsControllers.Size(); i < limit; i += 1 )
		{
			m_widgetsControllers[ i ].SetTextState( ( ( i == currentIndex ) ? ( 'Selected' ) : ( 'Default' ) ) );
		}
	}

	protected virtual function AnimateLineTranslation( targetWidget : weak< inkWidget >, targetX : Float, time : Float )
	{
		var translationsAnimDef : inkAnimDef;
		var translationInterpolator : inkAnimTranslation;
		var currentTranslation : Vector2;
		m_lineTranslationAnimProxy.Stop();
		currentTranslation = targetWidget.GetTranslation();
		translationsAnimDef = new inkAnimDef;
		translationInterpolator = new inkAnimTranslation;
		translationInterpolator.SetType( inkanimInterpolationType.Quartic );
		translationInterpolator.SetMode( inkanimInterpolationMode.EasyInOut );
		translationInterpolator.SetDirection( inkanimInterpolationDirection.FromTo );
		translationInterpolator.SetStartTranslation( targetWidget.GetTranslation() );
		translationInterpolator.SetEndTranslation( Vector2( targetX, currentTranslation.Y ) );
		translationInterpolator.SetDuration( time );
		translationsAnimDef.AddInterpolator( translationInterpolator );
		m_lineTranslationAnimProxy = targetWidget.PlayAnimation( translationsAnimDef );
		m_lineTranslationAnimProxy.RegisterToCallback( inkanimEventType.OnFinish, this, 'OnLineAnimationFinished' );
	}

	protected virtual function AnimateLineSize( targetWidget : weak< inkWidget >, targetWidth : Float, time : Float )
	{
		var sizeAnimDef : inkAnimDef;
		var sizeInterpolator : inkAnimSize;
		var currentSize : Vector2;
		m_lineSizeAnimProxy.Stop();
		currentSize = targetWidget.GetSize();
		sizeAnimDef = new inkAnimDef;
		sizeInterpolator = new inkAnimSize;
		sizeInterpolator.SetType( inkanimInterpolationType.Quartic );
		sizeInterpolator.SetMode( inkanimInterpolationMode.EasyInOut );
		sizeInterpolator.SetDirection( inkanimInterpolationDirection.FromTo );
		sizeInterpolator.SetStartSize( targetWidget.GetSize() );
		sizeInterpolator.SetEndSize( Vector2( targetWidth, currentSize.Y ) );
		sizeInterpolator.SetDuration( time );
		sizeAnimDef.AddInterpolator( sizeInterpolator );
		m_lineSizeAnimProxy = targetWidget.PlayAnimation( sizeAnimDef );
	}

	protected event OnLineAnimationFinished( anim : inkAnimProxy )
	{
		m_animationsRetryDiv = 0.0;
	}

	protected event OnArrangeChildrenComplete()
	{
		if( !( m_highlightInitialized ) && ( m_currentIndex != -1 ) )
		{
			UpdateHightlight( m_currentIndex, true );
		}
	}

	protected event OnDelayedHighlightUpdate( evt : DelayedHighlightUpdateEvent )
	{
		UpdateHightlight( m_currentIndex, false );
		UpdateArrowsVisibility();
	}

}

