enum PhoneDialerTabs
{
	Unread = 0,
	Contacts = 1,
}

class ContactSelectionChangedEvent extends Event
{
	var ContactData : weak< ContactData >;
}

class PhoneDialerLogicController extends inkLogicController
{
	editable var m_tabsContainer : inkWidgetRef;
	editable var m_titleContainer : inkWidgetRef;
	editable var m_titleTextWidget : inkTextRef;
	editable var m_acceptButtonLabel : inkTextRef;
	editable var m_action2ButtonLabel : inkTextRef;
	editable var m_inputHintsPanel : inkWidgetRef;
	editable var m_threadPanel : inkWidgetRef;
	editable var m_threadList : inkWidgetRef;
	editable var m_callsQuestFlag : inkWidgetRef;
	editable var m_arrow : inkWidgetRef;
	editable var m_threadTab : inkWidgetRef;
	editable var m_unreadTab : inkWidgetRef;
	editable var m_threadTabLabel : inkTextRef;
	editable var m_contactsList : inkWidgetRef;
	editable var m_avatarImage : inkImageRef;
	editable var m_contactAvatarsFluff : inkWidgetRef;
	editable var m_scrollArea : inkScrollAreaRef;
	editable var m_scrollControllerWidget : inkWidgetRef;
	editable var m_acceptButtonWidget : inkWidgetRef;
	editable var m_action2ButtonWidget : inkWidgetRef;
	editable var m_showAllButtonWidget : inkWidgetRef;
	editable var m_showAllLabel : inkTextRef;
	editable var m_nothingToReadMessageWidget : inkWidgetRef;
	editable var m_scrollBarWidget : inkWidgetRef;
	var m_listController : weak< inkVirtualListController >;
	var m_dataSource : ScriptableDataSource;
	var m_dataView : DialerContactDataView;
	var m_templateClassifier : DialerContactTemplateClassifier;
	var m_scrollController : weak< inkScrollController >;
	var m_switchAnimProxy : inkAnimProxy;
	var m_transitionAnimProxy : inkAnimProxy;
	var m_horizontalMoveAnimProxy : inkAnimProxy;
	var m_threadsController : weak< inkVirtualListController >;
	var m_dataSourceCache : ScriptableDataSource;
	var m_dataViewCache : DialerContactDataView;
	var m_moveBehindAnimProxy : inkAnimProxy;
	var m_hideContactAnimProxy : inkAnimProxy;
	var m_contactIndexCache : Uint32;
	default m_contactIndexCache = 0;
	var m_menuSelectorCtrl : weak< PhoneDialerSelectionController >;
	var m_firstInit : Bool;
	var m_indexToSelect : Uint32;
	default m_indexToSelect = 0;
	var m_hidingIndex : Uint32;
	var m_pulseAnim : PulseAnimation;
	var m_leftMargin : inkMargin;
	var m_rightMargin : inkMargin;
	var m_currentTab : PhoneDialerTabs;
	var m_callingEnabled : Bool;

	protected event OnInitialize()
	{
		GetRootWidget().SetVisible( false );
		InitVirtualList();
		inkScrollAreaRef.RegisterToCallback( m_scrollArea, 'OnScrollChanged', this, 'OnScrollChanged' );
		m_scrollController = ( ( inkScrollController )( inkWidgetRef.GetControllerByType( m_scrollControllerWidget, 'inkScrollController' ) ) );
		m_menuSelectorCtrl = ( ( PhoneDialerSelectionController )( inkWidgetRef.GetController( m_tabsContainer ) ) );
		m_leftMargin = inkMargin( 35.0, 10.0, 0.0, 0.0 );
		m_rightMargin = inkMargin( 1400.0, 10.0, 0.0, 0.0 );
		m_pulseAnim = new PulseAnimation;
		m_pulseAnim.Configure( inkWidgetRef.Get( m_callsQuestFlag ), 1.0, 0.2, 0.60000002 );
	}

	protected event OnUninitialize()
	{
		CleanVirtualList();
		CloseContactList();
	}

	protected event OnScrollChanged( value : Vector2 )
	{
		m_scrollController.UpdateScrollPositionFromScrollArea();
	}

	public function ShowInputHints( show : Bool )
	{
		inkWidgetRef.SetVisible( m_inputHintsPanel, show );
	}

	public function ShowCallsQuestIndicator( visible : Bool )
	{
		inkWidgetRef.SetVisible( m_callsQuestFlag, visible );
	}

	public function SetCallingEnabled( enabled : Bool )
	{
		m_callingEnabled = enabled;
	}

	public function SwtichTabs( tab : PhoneDialerTabs )
	{
		m_currentTab = tab;
		inkWidgetRef.SetVisible( m_acceptButtonWidget, false );
		inkWidgetRef.SetVisible( m_action2ButtonWidget, false );
		inkWidgetRef.SetVisible( m_showAllButtonWidget, false );
		switch( tab )
		{
			case PhoneDialerTabs.Unread:
				m_menuSelectorCtrl.ScrollTo( 0 );
			inkWidgetRef.SetVisible( m_nothingToReadMessageWidget, IsEmpty() );
			break;
			case PhoneDialerTabs.Contacts:
				m_menuSelectorCtrl.ScrollTo( 1 );
			inkWidgetRef.SetVisible( m_nothingToReadMessageWidget, false );
			break;
		}
	}

	public function IsEmpty() : Bool
	{
		return m_dataSource.Size() == ( ( Uint32 )( ( ( m_currentTab == PhoneDialerTabs.Unread ) ? ( 1 ) : ( 0 ) ) ) );
	}

	public function InitVirtualList()
	{
		m_templateClassifier = new DialerContactTemplateClassifier;
		m_dataView = new DialerContactDataView;
		m_dataSource = new ScriptableDataSource;
		m_dataView.Setup();
		m_dataView.SetSource( m_dataSource );
		m_listController = ( ( inkVirtualListController )( inkWidgetRef.GetControllerByType( m_contactsList, 'inkVirtualListController' ) ) );
		m_listController.SetClassifier( m_templateClassifier );
		m_listController.SetSource( m_dataView );
		m_listController.RegisterToCallback( 'OnItemSelected', this, 'OnItemSelected' );
		m_listController.RegisterToCallback( 'OnAllElementsSpawned', this, 'OnAllElementsSpawned' );
		m_dataViewCache = new DialerContactDataView;
		m_dataSourceCache = new ScriptableDataSource;
		m_dataViewCache.Setup();
		m_dataViewCache.SetSource( m_dataSourceCache );
		m_threadsController = ( ( inkVirtualListController )( inkWidgetRef.GetControllerByType( m_threadList, 'inkVirtualListController' ) ) );
		m_threadsController.SetClassifier( m_templateClassifier );
		m_threadsController.SetSource( m_dataViewCache );
	}

	public function SetSortMethod( sortMethod : ContactsSortMethod )
	{
		m_dataView.m_sortMethod = sortMethod;
	}

	public function HideTab( tab : PhoneDialerTabs )
	{
		m_menuSelectorCtrl.HideTab( ( ( Int32 )( tab ) ) );
	}

	public function ShowTitle( visible : Bool )
	{
		inkWidgetRef.SetVisible( m_arrow, visible );
		inkWidgetRef.SetVisible( m_threadTab, visible );
		inkWidgetRef.SetVisible( m_unreadTab, !( visible ) );
	}

	public function SetTitle( title : String )
	{
		inkTextRef.SetText( m_threadTabLabel, title );
	}

	public function UpdateShowAllButton( showAll : Bool )
	{
		if( showAll )
		{
			inkTextRef.SetLocalizedTextScript( m_showAllLabel, "LocKey#93929" );
		}
		else
		{
			inkTextRef.SetLocalizedTextScript( m_showAllLabel, "LocKey#93930" );
		}
	}

	public function CleanVirtualList()
	{
		m_listController.SetSource( NULL );
		m_listController.SetClassifier( NULL );
		m_dataView.SetSource( NULL );
		m_threadsController.SetSource( NULL );
		m_threadsController.SetClassifier( NULL );
		m_dataViewCache.SetSource( NULL );
		m_dataViewCache = NULL;
		m_dataSourceCache = NULL;
		m_dataView = NULL;
		m_dataSource = NULL;
		m_templateClassifier = NULL;
	}

	protected event OnItemSelected( previous : inkVirtualCompoundItemController, next : inkVirtualCompoundItemController )
	{
		var contactData : ContactData;
		var selectionChangeEvent : ContactSelectionChangedEvent;
		contactData = ( ( ContactData )( ( ( IScriptable )( next.GetData() ) ) ) );
		InkImageUtils.RequestAvatarOrUnknown( this, m_avatarImage, contactData.avatarID );
		if( m_switchAnimProxy )
		{
			m_switchAnimProxy.Stop();
			m_switchAnimProxy = NULL;
		}
		m_switchAnimProxy = PlayLibraryAnimation( 'switchContact' );
		RefreshInputHints( contactData );
		RefreshCallingEnabled( next );
		selectionChangeEvent = new ContactSelectionChangedEvent;
		selectionChangeEvent.ContactData = contactData;
		QueueEvent( selectionChangeEvent );
	}

	private function RefreshCallingEnabled( item : inkVirtualCompoundItemController )
	{
		( ( PhoneContactItemVirtualController )( item ) ).SetCallingEnabled( m_callingEnabled );
	}

	private function RefreshInputHints( contactData : weak< ContactData > )
	{
		if( m_currentTab == PhoneDialerTabs.Unread )
		{
			inkWidgetRef.SetVisible( m_acceptButtonWidget, false );
			inkWidgetRef.SetVisible( m_action2ButtonWidget, false );
			inkWidgetRef.SetVisible( m_showAllButtonWidget, true );
			inkTextRef.SetLocalizedTextScript( m_acceptButtonLabel, "LocKey#92248" );
		}
		else
		{
			inkWidgetRef.SetVisible( m_acceptButtonWidget, contactData.isCallable );
			inkWidgetRef.SetVisible( m_action2ButtonWidget, ( ( contactData.type == MessengerContactType.Contact ) ? ( contactData.hasMessages ) : ( true ) ) );
			inkWidgetRef.SetVisible( m_showAllButtonWidget, false );
			inkTextRef.SetLocalizedTextScript( m_acceptButtonLabel, "LocKey#22196" );
			inkTextRef.SetLocalizedTextScript( m_action2ButtonLabel, "LocKey#92247" );
			inkWidgetRef.SetVisible( m_acceptButtonWidget, false );
			inkWidgetRef.SetVisible( m_action2ButtonWidget, false );
			inkWidgetRef.SetVisible( m_showAllButtonWidget, false );
		}
	}

	public function Show()
	{
		GetRootWidget().SetVisible( true );
		m_pulseAnim.Start();
		if( m_transitionAnimProxy )
		{
			m_transitionAnimProxy.UnregisterFromCallback( inkanimEventType.OnFinish, this, 'OnHideAnimFinished' );
			m_transitionAnimProxy.Stop();
			m_transitionAnimProxy = NULL;
		}
		m_transitionAnimProxy = PlayLibraryAnimation( 'fadeIn' );
	}

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

	protected event OnHideAnimFinished( proxy : inkAnimProxy )
	{
		GetRootWidget().SetVisible( false );
	}

	protected event OnAllElementsSpawned()
	{
		if( m_firstInit )
		{
			m_firstInit = false;
			m_listController.SelectItem( m_indexToSelect );
			m_indexToSelect = 0;
		}
	}

	public function PopulateListData( const contactDataArray : ref< array< IScriptable > >, optional selectIndex : Uint32, optional itemHash : Int32 )
	{
		m_dataView.EnableSorting();
		m_dataSource.Reset( contactDataArray );
		m_dataView.DisableSorting();
		m_firstInit = true;
		m_indexToSelect = ( ( itemHash != 0 ) ? ( ContactDataHelper.IndexOfOrZero( m_dataView, itemHash ) ) : ( selectIndex ) );
	}

	public function PushList( const contactDataArray : ref< array< IScriptable > >, sortMethod : ContactsSortMethod )
	{
		m_contactIndexCache = m_listController.GetSelectedIndex();
		m_dataViewCache.m_sortMethod = m_dataView.m_sortMethod;
		m_dataViewCache.EnableSorting();
		m_dataSourceCache.Reset( m_dataSource.GetArray() );
		m_dataViewCache.DisableSorting();
		m_dataView.m_sortMethod = sortMethod;
		PopulateListData( contactDataArray, 0 );
		inkWidgetRef.SetVisible( m_contactsList, false );
		inkWidgetRef.SetVisible( m_threadPanel, true );
		if( m_moveBehindAnimProxy )
		{
			m_moveBehindAnimProxy.UnregisterFromAllCallbacks( inkanimEventType.OnFinish );
			m_moveBehindAnimProxy.Stop();
			m_moveBehindAnimProxy = NULL;
		}
		m_moveBehindAnimProxy = PlayLibraryAnimation( 'moveBehind' );
		m_moveBehindAnimProxy.RegisterToCallback( inkanimEventType.OnFinish, this, 'OnMoveBehindAnimFinished' );
	}

	protected event OnMoveBehindAnimFinished( proxy : inkAnimProxy )
	{
		inkWidgetRef.SetVisible( m_contactsList, true );
		m_moveBehindAnimProxy = NULL;
	}

	public function PopList()
	{
		var options : inkAnimOptions;
		inkWidgetRef.SetVisible( m_contactsList, false );
		m_dataView.m_sortMethod = m_dataViewCache.m_sortMethod;
		PopulateListData( m_dataSourceCache.GetArray(), m_contactIndexCache );
		m_contactIndexCache = 0;
		if( m_moveBehindAnimProxy )
		{
			m_moveBehindAnimProxy.UnregisterFromAllCallbacks( inkanimEventType.OnFinish );
			m_moveBehindAnimProxy.Stop();
			m_moveBehindAnimProxy = NULL;
		}
		options.playReversed = true;
		m_moveBehindAnimProxy = PlayLibraryAnimation( 'moveBehind', options );
		m_moveBehindAnimProxy.RegisterToCallback( inkanimEventType.OnFinish, this, 'OnMoveBehindReversedAnimFinished' );
	}

	protected event OnMoveBehindReversedAnimFinished( proxy : inkAnimProxy )
	{
		m_dataSourceCache.Clear();
		inkWidgetRef.SetVisible( m_contactsList, true );
		inkWidgetRef.SetVisible( m_threadPanel, false );
		m_moveBehindAnimProxy = NULL;
	}

	public function GetSelectedContactData() : weak< ContactData >
	{
		var item : PhoneContactItemVirtualController;
		item = ( ( PhoneContactItemVirtualController )( m_listController.GetSelectedItem() ) );
		return item.GetContactData();
	}

	public function GetSelectedContactHash() : Int32
	{
		var contact : weak< ContactData >;
		contact = GetSelectedContactData();
		return ContactDataHelper.FetchContactHash( contact );
	}

	public function GetContactWithUnreadHash() : Int32
	{
		var selectedIndex : Int32;
		var selectedContact : ContactData;
		selectedIndex = ( ( Int32 )( GetSelectedContactIndex() ) );
		if( selectedIndex == -1 )
		{
			return ( ( Int32 )( MessageHash.Invalid ) );
		}
		selectedContact = ( ( ContactData )( m_dataView.GetItem( ( ( Uint32 )( selectedIndex ) ) ) ) );
		if( ( ( ( selectedContact.unreadMessages.Size() > 0 ) || selectedContact.type == MessengerContactType.Fake_ShowAll ) || selectedContact.hasQuestImportantReply ) || selectedContact.playerCanReply )
		{
			return ContactDataHelper.FetchContactHash( selectedContact );
		}
		selectedContact = ContactDataHelper.FindClosestContactWithUnread( m_dataView, selectedIndex );
		return ContactDataHelper.FetchContactHash( selectedContact );
	}

	public function GetSelectedContactIndex() : Uint32
	{
		return m_listController.GetSelectedIndex();
	}

	public function HideSelectedItem()
	{
		( ( PhoneContactItemVirtualController )( m_listController.GetSelectedItem() ) ).Hide();
	}

	public function OpenSelectedItem()
	{
		( ( PhoneContactItemVirtualController )( m_listController.GetSelectedItem() ) ).OpenInChat();
	}

	public function RefreshSelectedContact()
	{
		( ( PhoneContactItemVirtualController )( m_listController.GetSelectedItem() ) ).Refresh( true );
	}

	protected event OnItemHidden( evt : PhoneContactHiddenEvent )
	{
		GetRootWidget().CallCustomCallback( 'OnContactHidden' );
		evt.HiddenItem.GetRootWidget().SetVisible( true );
	}

	protected event OnGotFocus( evt : FocusSmsMessagerEvent )
	{
		PlayLibraryAnimation( 'unfocus_left' );
	}

	protected event OnLostFocus( evt : UnfocusSmsMessagerEvent )
	{
		var playbackOptions : inkAnimOptions;
		playbackOptions.playReversed = true;
		PlayLibraryAnimation( 'unfocus_left', playbackOptions );
	}

	public function GotoMessengerMenu()
	{
		var evt : StartHubMenuEvent;
		var userData : MessageMenuAttachmentData;
		var contactData : ContactData;
		var item : PhoneContactItemVirtualController;
		item = ( ( PhoneContactItemVirtualController )( m_listController.GetSelectedItem() ) );
		contactData = item.GetContactData();
		if( contactData.playerCanReply || contactData.hasMessages )
		{
			userData = new MessageMenuAttachmentData;
			userData.m_entryHash = contactData.hash;
			evt = new StartHubMenuEvent;
			evt.SetStartMenu( 'phone', , userData );
			QueueBroadcastEvent( evt );
		}
		CloseContactList();
	}

	public function NavigateDown()
	{
		m_listController.Navigate( inkDiscreteNavigationDirection.Down );
		PlaySound( 'Holocall', 'Navigation' );
	}

	public function NavigateUp()
	{
		m_listController.Navigate( inkDiscreteNavigationDirection.Up );
		PlaySound( 'Holocall', 'Navigation' );
	}

	public function MoveContactPictures( moveToRight : Bool )
	{
		var horizantalMove : inkAnimDef;
		var marginInterpolator : inkAnimMargin;
		horizantalMove = new inkAnimDef;
		marginInterpolator = new inkAnimMargin;
		marginInterpolator.SetDuration( 0.5 );
		if( moveToRight )
		{
			marginInterpolator.SetStartMargin( m_leftMargin );
			marginInterpolator.SetEndMargin( m_rightMargin );
		}
		else
		{
			marginInterpolator.SetStartMargin( m_rightMargin );
			marginInterpolator.SetEndMargin( m_leftMargin );
		}
		marginInterpolator.SetType( inkanimInterpolationType.Quintic );
		marginInterpolator.SetMode( inkanimInterpolationMode.EasyInOut );
		horizantalMove.AddInterpolator( marginInterpolator );
		m_horizontalMoveAnimProxy = inkWidgetRef.PlayAnimation( m_contactAvatarsFluff, horizantalMove );
	}

	public function CloseContactList()
	{
		GetRootWidget().CallCustomCallback( 'OnCloseContactList' );
	}

}

