class HudPhoneAvatarController extends HUDPhoneElement
{
	private editable var m_ContactAvatar : inkImageRef;
	private editable var m_HolocallRenderTexture : inkImageRef;
	private editable var m_SignalRangeIcon : inkImageRef;
	private editable var m_ContactName : inkTextRef;
	private editable var m_StatusText : inkTextRef;
	private editable var m_WaveformPlaceholder : inkCanvasRef;
	private editable var m_HolocallHolder : inkFlexRef;
	private editable var m_UnknownAvatarName : CName;
	default m_UnknownAvatarName = 'Unknown';
	private editable var m_DefaultPortraitColor : Color;
	private editable var m_DefaultImageSize : Vector2;
	private editable var m_blackWallEffectOnShow : Bool;
	default m_blackWallEffectOnShow = false;
	private editable var m_LoopAnimationName : CName;
	default m_LoopAnimationName = 'avatarHoloCallLoopAnimation';
	private editable var m_ShowingAnimationName : CName;
	default m_ShowingAnimationName = 'portraitIntro';
	private editable var m_HidingAnimationName : CName;
	default m_HidingAnimationName = 'portraitOutro';
	private editable var m_AudiocallShowingAnimationName : CName;
	default m_AudiocallShowingAnimationName = 'avatarAudiocallShowingAnimation';
	private editable var m_AudiocallHidingAnimationName : CName;
	default m_AudiocallHidingAnimationName = 'avatarAudiocallHidingAnimation';
	private editable var m_HolocallShowingAnimationName : CName;
	default m_HolocallShowingAnimationName = 'avatarHolocallShowingAnimation';
	private editable var m_HolocallHidingAnimationName : CName;
	default m_HolocallHidingAnimationName = 'avatarHolocallHidingAnimation';
	private var m_LoopAnimation : inkAnimProxy;
	private var m_JournalManager : IJournalManager;
	private var m_RootAnimation : inkAnimProxy;
	private var m_AudiocallAnimation : inkAnimProxy;
	private var m_HolocallAnimation : inkAnimProxy;
	private var m_Holder : inkWidgetRef;
	private var m_Owner : weak< GameObject >;
	private var m_CurrentMode : EHudAvatarMode;
	private var m_Minimized : Bool;
	default m_Minimized = false;
	private var m_showAvatar : Bool;
	default m_showAvatar = false;

	protected event OnInitialize()
	{
		var placeholder : inkWidgetRef;
		super.OnInitialize();
		placeholder = ( ( inkWidgetRef )( m_WaveformPlaceholder ) );
		SpawnFromLocal( inkWidgetRef.Get( placeholder ), 'waveform' );
		ShowAvatar( false );
	}

	public function SetJournalManager( journalManager : IJournalManager )
	{
		m_JournalManager = journalManager;
	}

	public function SetHolder( holder : inkWidgetRef )
	{
		m_Holder = holder;
	}

	public function SetOwner( playerPuppet : weak< GameObject > )
	{
		m_Owner = playerPuppet;
	}

	public function ShowIncomingContact( avatarID : TweakDBID, const contactName : ref< String > )
	{
		ShowAvatar( false );
		RefreshView( avatarID, contactName, EHudAvatarMode.Connecting );
	}

	public function ShowEndCallContact( avatarID : TweakDBID, const contactName : ref< String > )
	{
		if( m_CurrentMode == EHudAvatarMode.Holocall || m_CurrentMode == EHudAvatarMode.Audiocall )
		{
			m_Minimized = false;
			ShowAvatar( false );
			RefreshView( avatarID, contactName, EHudAvatarMode.Disconnecting );
		}
		else
		{
			Hide();
		}
	}

	public function StartAudiocall( avatarID : TweakDBID, const contactName : ref< String >, showAvatar : Bool )
	{
		ShowAvatar( showAvatar );
		RefreshView( avatarID, contactName, EHudAvatarMode.Audiocall );
	}

	private function ShowAvatar( showAvatar : Bool )
	{
		m_showAvatar = showAvatar;
		inkCanvasRef.SetMargin( m_WaveformPlaceholder, 0.0, ( ( m_showAvatar ) ? ( 450.0 ) : ( 0.0 ) ), 0.0, 0.0 );
	}

	public function StartHolocall( avatarID : TweakDBID, const contactName : ref< String > )
	{
		ShowAvatar( false );
		RefreshView( avatarID, contactName, EHudAvatarMode.Holocall );
	}

	public function ChangeMinimized( minimized : Bool )
	{
		if( minimized != m_Minimized )
		{
			m_Minimized = minimized;
			inkImageRef.SetVisible( m_SignalRangeIcon, m_CurrentMode == EHudAvatarMode.Audiocall || m_Minimized );
			inkCanvasRef.SetVisible( m_WaveformPlaceholder, m_CurrentMode == EHudAvatarMode.Audiocall || m_Minimized );
			PlayElementAnimations();
		}
	}

	public function SetStatusText( const statusText : ref< String > )
	{
		inkTextRef.SetLetterCase( m_StatusText, textLetterCase.UpperCase );
		inkTextRef.SetText( m_StatusText, statusText );
	}

	protected event OnStateChanged( widget : weak< inkWidget >, oldState : CName, newState : CName )
	{
		var currentState : EHudPhoneVisibility;
		var options : inkAnimOptions;
		StopRootAnimation();
		currentState = GetStateFromName( newState );
		if( currentState == EHudPhoneVisibility.Showing )
		{
			if( m_blackWallEffectOnShow )
			{
				GameObjectEffectHelper.StartEffectEvent( m_Owner, 'hacking_interference_shot' );
				GameObjectEffectHelper.StartEffectEvent( m_Owner, 'q301_holocall_blackwall' );
			}
			m_RootAnimation = PlayLibraryAnimation( m_ShowingAnimationName, options );
			m_RootAnimation.RegisterToCallback( inkanimEventType.OnFinish, this, 'OnRootAnimationFinished' );
		}
		else if( currentState == EHudPhoneVisibility.Visible )
		{
			options.loopType = inkanimLoopType.Cycle;
			options.loopInfinite = true;
			m_RootWidget.SetOpacity( 1.0 );
			if( !( m_LoopAnimation.IsPlaying() ) )
			{
				m_LoopAnimation = PlayLibraryAnimation( m_LoopAnimationName, options );
			}
		}
		else if( currentState == EHudPhoneVisibility.Hiding )
		{
			m_LoopAnimation.Stop();
			m_RootAnimation = PlayLibraryAnimation( m_HidingAnimationName, options );
			m_RootAnimation.RegisterToCallback( inkanimEventType.OnFinish, this, 'OnRootAnimationFinished' );
		}
		else if( currentState == EHudPhoneVisibility.Invisible )
		{
			m_RootWidget.SetOpacity( 0.0 );
			inkImageRef.SetTintColor( m_ContactAvatar, m_DefaultPortraitColor );
			inkImageRef.SetSize( m_ContactAvatar, m_DefaultImageSize );
			inkImageRef.SetSize( m_HolocallRenderTexture, m_DefaultImageSize );
			GetRootWidget().CallCustomCallback( 'OnAvatarControllerHidden' );
		}
	}

	private function RefreshView( avatarID : TweakDBID, const contactName : ref< String >, mode : EHudAvatarMode )
	{
		var statusText : String;
		m_CurrentMode = mode;
		inkImageRef.SetVisible( m_ContactAvatar, mode == EHudAvatarMode.Connecting || m_showAvatar );
		InkImageUtils.RequestAvatarOrUnknown( this, m_ContactAvatar, avatarID );
		inkTextRef.SetLetterCase( m_ContactName, textLetterCase.UpperCase );
		inkTextRef.SetText( m_ContactName, contactName );
		inkImageRef.SetVisible( m_SignalRangeIcon, mode == EHudAvatarMode.Audiocall || m_Minimized );
		inkCanvasRef.SetVisible( m_WaveformPlaceholder, mode == EHudAvatarMode.Audiocall || m_Minimized );
		inkImageRef.SetVisible( m_HolocallRenderTexture, mode == EHudAvatarMode.Holocall );
		switch( mode )
		{
			case EHudAvatarMode.Connecting:
				statusText = "Connecting";
			inkWidgetRef.SetOpacity( m_Holder, 1.0 );
			break;
			case EHudAvatarMode.Disconnecting:
				statusText = "Disconnecting";
			break;
			case EHudAvatarMode.Holocall:
				statusText = ( ( m_Minimized ) ? ( "Connection Status: Active Voice Call" ) : ( "Connection 541.44.10" ) );
			break;
			case EHudAvatarMode.Audiocall:
				statusText = "Connection Status: Active Voice Call";
			break;
			default:
				statusText = "Connected";
			break;
		}
		SetStatusText( statusText );
		Show();
		PlayElementAnimations();
		inkFlexRef.SetVisible( m_HolocallHolder, !( m_Minimized ) );
	}

	private function StopRootAnimation()
	{
		if( m_RootAnimation )
		{
			m_RootAnimation.UnregisterFromCallback( inkanimEventType.OnFinish, this, 'OnAnimationFinished' );
			m_RootAnimation.Stop();
			m_RootAnimation = NULL;
		}
	}

	private function StopAudiocallAnimation()
	{
		if( m_AudiocallAnimation )
		{
			m_AudiocallAnimation.UnregisterFromCallback( inkanimEventType.OnFinish, this, 'OnAudiocallAnimationFinished' );
			m_AudiocallAnimation.Stop();
			m_AudiocallAnimation = NULL;
		}
	}

	private function StopHolocallAnimation()
	{
		if( m_HolocallAnimation )
		{
			m_HolocallAnimation.UnregisterFromCallback( inkanimEventType.OnFinish, this, 'OnHolocallAnimationFinished' );
			m_HolocallAnimation.Stop();
			m_HolocallAnimation = NULL;
		}
	}

	private function PlayElementAnimations()
	{
		var isHolocall, isAudiocall, showAvatar, isMinimized : Bool;
		var animationName : CName;
		StopAudiocallAnimation();
		StopHolocallAnimation();
		isMinimized = m_Minimized;
		showAvatar = m_CurrentMode == EHudAvatarMode.Connecting || m_showAvatar;
		isHolocall = m_CurrentMode == EHudAvatarMode.Holocall;
		isAudiocall = m_CurrentMode == EHudAvatarMode.Audiocall;
		animationName = ( ( showAvatar || ( isHolocall && !( isMinimized ) ) ) ? ( m_HolocallShowingAnimationName ) : ( m_HolocallHidingAnimationName ) );
		if( animationName != '' )
		{
			m_HolocallAnimation = PlayLibraryAnimation( animationName );
			m_HolocallAnimation.RegisterToCallback( inkanimEventType.OnFinish, this, 'OnHolocallAnimationFinished' );
		}
		else
		{
			OnHolocallAnimationFinished( NULL );
		}
		animationName = ( ( isAudiocall || isMinimized ) ? ( m_AudiocallShowingAnimationName ) : ( m_AudiocallHidingAnimationName ) );
		if( animationName != '' )
		{
			m_AudiocallAnimation = PlayLibraryAnimation( animationName );
			m_AudiocallAnimation.RegisterToCallback( inkanimEventType.OnFinish, this, 'OnAudiocallAnimationFinished' );
		}
		else
		{
			OnAudiocallAnimationFinished( NULL );
		}
	}

	private function AreElementAnimationsComplete() : Bool
	{
		return ( !( m_AudiocallAnimation ) || !( m_AudiocallAnimation.IsPlaying() ) ) && ( !( m_HolocallAnimation ) || !( m_HolocallAnimation.IsPlaying() ) );
	}

	protected event OnHolocallAnimationFinished( anim : inkAnimProxy )
	{
		StopHolocallAnimation();
		OnElementAnimationsFinished();
	}

	protected event OnAudiocallAnimationFinished( anim : inkAnimProxy )
	{
		StopAudiocallAnimation();
		OnElementAnimationsFinished();
	}

	private function OnElementAnimationsFinished()
	{
		if( AreElementAnimationsComplete() )
		{
			if( m_CurrentMode == EHudAvatarMode.Disconnecting )
			{
				inkWidgetRef.SetOpacity( m_Holder, 0.0 );
				Hide();
			}
		}
	}

	protected event OnRootAnimationFinished( anim : inkAnimProxy )
	{
		var currentState : EHudPhoneVisibility;
		StopRootAnimation();
		currentState = GetState();
		if( currentState == EHudPhoneVisibility.Showing )
		{
			SetState( EHudPhoneVisibility.Visible );
		}
		else if( currentState == EHudPhoneVisibility.Hiding )
		{
			SetState( EHudPhoneVisibility.Invisible );
		}
	}

}

enum EHudAvatarMode
{
	Connecting = 0,
	Disconnecting = 1,
	Holocall = 2,
	Audiocall = 3,
}

