class NcartMetroMapController extends CustomAnimationsHudGameController
{
	private editable var m_playerMarkerPane : inkWidgetRef;
	private const editable var m_playerCurrentPositionReferences : array< metroMapPlayerPositionReferences >;
	private var m_questsSystem : QuestsSystem;
	private var m_selectedDestinationButtonListner : Uint32;
	private var m_selectionMenuShouldBeActiveListener : Uint32;
	private var m_previousAnimatioNumber : Int32;
	private var m_directionAnimProxy : inkAnimProxy;
	private var m_startupAnimProxy : inkAnimProxy;
	private var m_playerPostionMarkerAnimProxy : inkAnimProxy;
	private var m_mapOpen : Bool;
	private const var LineOffOpacity : Float;
	default LineOffOpacity = 0.04f;
	private const var LineOnOpacity : Float;
	default LineOnOpacity = 0.55f;

	protected event OnInitialize()
	{
		var ownerObject : GameObject;
		super.OnInitialize();
		ownerObject = ( ( GameObject )( GetOwnerEntity() ) );
		m_questsSystem = GameInstance.GetQuestsSystem( ownerObject.GetGame() );
		m_selectionMenuShouldBeActiveListener = m_questsSystem.RegisterListener( 'ue_metro_enable_line_section_ui', this, 'OnMetroMapControlFactChangeEvent' );
		m_root = ( ( inkCompoundWidget )( GetRootWidget() ) );
	}

	protected event OnMetroMapControlFactChangeEvent( factValue : Int32 )
	{
		if( factValue > 0 )
		{
			m_startupAnimProxy = PlayLibraryAnimation( 'startup' );
			m_startupAnimProxy.RegisterToCallback( inkanimEventType.OnFinish, this, 'OnStartupAnimationDone' );
			UpdateAvialableLines();
			m_mapOpen = true;
		}
		else
		{
			if( m_mapOpen )
			{
				UpdatePlayerLocationMarker( false );
				HideDirectionPanes();
				SwitchActiveButton( 0 );
				m_directionAnimProxy.Stop();
				m_previousAnimatioNumber = 0;
				PlayLibraryAnimation( 'close' );
				m_questsSystem.UnregisterListener( 'ue_metro_station_highlight', m_selectedDestinationButtonListner );
				m_mapOpen = false;
			}
		}
	}

	protected event OnStartupAnimationDone( proxy : inkAnimProxy )
	{
		var factValue : Int32;
		factValue = m_questsSystem.GetFact( 'ue_metro_station_highlight' );
		if( factValue > 0 )
		{
			SwitchActiveButton( factValue );
		}
		UpdatePlayerLocationMarker( true );
		m_startupAnimProxy.UnregisterFromAllCallbacks( inkanimEventType.OnFinish );
		m_selectedDestinationButtonListner = m_questsSystem.RegisterListener( 'ue_metro_station_highlight', this, 'OnMetroMapSelectionChangedEvent' );
	}

	protected event OnMetroMapSelectionChangedEvent( factValue : Int32 )
	{
		SwitchActiveButton( factValue );
	}

	private function ProcessButtonAnimation( buttonNumber : Int32, animSetup : inkAnimOptions )
	{
		switch( buttonNumber )
		{
			case 1:
				PlayLibraryAnimation( 'SelectA1', animSetup );
			break;
			case 2:
				PlayLibraryAnimation( 'SelectA2', animSetup );
			break;
			case 3:
				PlayLibraryAnimation( 'SelectB1', animSetup );
			break;
			case 4:
				PlayLibraryAnimation( 'SelectB2', animSetup );
			break;
			case 5:
				PlayLibraryAnimation( 'SelectC1', animSetup );
			break;
			case 6:
				PlayLibraryAnimation( 'SelectC2', animSetup );
			break;
			case 7:
				PlayLibraryAnimation( 'SelectD', animSetup );
			break;
			case 8:
				PlayLibraryAnimation( 'SelectD', animSetup );
			break;
			case 9:
				PlayLibraryAnimation( 'SelectE1', animSetup );
			break;
			case 10:
				PlayLibraryAnimation( 'SelectE2', animSetup );
			break;
		}
	}

	private function SetupDirectionWidget( buttonNumber : Int32 )
	{
		var widget : weak< inkCompoundWidget >;
		var markerWidget : weak< inkImage >;
		var rootWidget : inkCompoundWidget;
		rootWidget = GetRootCompoundWidget();
		widget = ( ( inkCompoundWidget )( rootWidget.GetWidgetByPath( inkWidgetPath.Build( 'DirectionMasks', 'LineAMaskPane' ) ) ) );
		if( ( buttonNumber == 1 ) || ( buttonNumber == 2 ) )
		{
			widget.SetOpacity( 1.0 );
			markerWidget = ( ( inkImage )( rootWidget.GetWidgetByPath( inkWidgetPath.Build( 'DirectionMasks', 'LineAMaskPane', 'LineADirectionPoint' ) ) ) );
			markerWidget.SetOpacity( 1.0 );
		}
		else
		{
			widget.SetOpacity( 0.0 );
		}
		widget = ( ( inkCompoundWidget )( rootWidget.GetWidgetByPath( inkWidgetPath.Build( 'DirectionMasks', 'LineBMaskPane' ) ) ) );
		if( ( buttonNumber == 3 ) || ( buttonNumber == 4 ) )
		{
			widget.SetOpacity( 1.0 );
			markerWidget = ( ( inkImage )( rootWidget.GetWidgetByPath( inkWidgetPath.Build( 'DirectionMasks', 'LineBMaskPane', 'LineBDirectionPoint' ) ) ) );
			markerWidget.SetOpacity( 1.0 );
		}
		else
		{
			widget.SetOpacity( 0.0 );
		}
		widget = ( ( inkCompoundWidget )( rootWidget.GetWidgetByPath( inkWidgetPath.Build( 'DirectionMasks', 'LineCMaskPane' ) ) ) );
		if( ( buttonNumber == 5 ) || ( buttonNumber == 6 ) )
		{
			widget.SetOpacity( 1.0 );
			markerWidget = ( ( inkImage )( rootWidget.GetWidgetByPath( inkWidgetPath.Build( 'DirectionMasks', 'LineCMaskPane', 'LineCDirectionPoint' ) ) ) );
			markerWidget.SetOpacity( 1.0 );
		}
		else
		{
			widget.SetOpacity( 0.0 );
		}
		widget = ( ( inkCompoundWidget )( rootWidget.GetWidgetByPath( inkWidgetPath.Build( 'DirectionMasks', 'LineDMaskPane' ) ) ) );
		if( ( buttonNumber == 7 ) || ( buttonNumber == 8 ) )
		{
			widget.SetOpacity( 1.0 );
			markerWidget = ( ( inkImage )( rootWidget.GetWidgetByPath( inkWidgetPath.Build( 'DirectionMasks', 'LineDMaskPane', 'LineDDirectionPoint' ) ) ) );
			markerWidget.SetOpacity( 1.0 );
		}
		else
		{
			widget.SetOpacity( 0.0 );
		}
		widget = ( ( inkCompoundWidget )( rootWidget.GetWidgetByPath( inkWidgetPath.Build( 'DirectionMasks', 'LineEMaskPane' ) ) ) );
		if( ( buttonNumber == 9 ) || ( buttonNumber == 10 ) )
		{
			widget.SetOpacity( 1.0 );
			markerWidget = ( ( inkImage )( rootWidget.GetWidgetByPath( inkWidgetPath.Build( 'DirectionMasks', 'LineEMaskPane', 'LineEDirectionPoint' ) ) ) );
			markerWidget.SetOpacity( 1.0 );
		}
		else
		{
			widget.SetOpacity( 0.0 );
		}
	}

	private function HideDirectionPanes()
	{
		var widget : weak< inkCompoundWidget >;
		var rootWidget : inkCompoundWidget;
		rootWidget = GetRootCompoundWidget();
		widget = ( ( inkCompoundWidget )( rootWidget.GetWidgetByPath( inkWidgetPath.Build( 'DirectionMasks', 'LineAMaskPane' ) ) ) );
		widget.SetOpacity( 0.0 );
		widget = ( ( inkCompoundWidget )( rootWidget.GetWidgetByPath( inkWidgetPath.Build( 'DirectionMasks', 'LineBMaskPane' ) ) ) );
		widget.SetOpacity( 0.0 );
		widget = ( ( inkCompoundWidget )( rootWidget.GetWidgetByPath( inkWidgetPath.Build( 'DirectionMasks', 'LineCMaskPane' ) ) ) );
		widget.SetOpacity( 0.0 );
		widget = ( ( inkCompoundWidget )( rootWidget.GetWidgetByPath( inkWidgetPath.Build( 'DirectionMasks', 'LineDMaskPane' ) ) ) );
		widget.SetOpacity( 0.0 );
		widget = ( ( inkCompoundWidget )( rootWidget.GetWidgetByPath( inkWidgetPath.Build( 'DirectionMasks', 'LineEMaskPane' ) ) ) );
		widget.SetOpacity( 0.0 );
	}

	private function UpdateDirectionDisplay( buttonNumber : Int32 )
	{
		var animSetup : inkAnimOptions;
		animSetup.loopInfinite = true;
		animSetup.loopType = inkanimLoopType.Cycle;
		animSetup.dependsOnTimeDilation = false;
		animSetup.playReversed = false;
		m_directionAnimProxy.Stop();
		SetupDirectionWidget( buttonNumber );
		switch( buttonNumber )
		{
			case 1:
			{
				animSetup.playReversed = true;
				m_directionAnimProxy = PlayLibraryAnimation( 'LineADirection', animSetup );
			}
			break;
			case 2:
			{
				m_directionAnimProxy = PlayLibraryAnimation( 'LineADirection', animSetup );
			}
			break;
			case 3:
			{
				m_directionAnimProxy = PlayLibraryAnimation( 'LineBDirection', animSetup );
			}
			break;
			case 4:
			{
				animSetup.playReversed = true;
				m_directionAnimProxy = PlayLibraryAnimation( 'LineBDirection', animSetup );
			}
			break;
			case 5:
			{
				animSetup.playReversed = true;
				m_directionAnimProxy = PlayLibraryAnimation( 'LineCDirection', animSetup );
			}
			break;
			case 6:
			{
				m_directionAnimProxy = PlayLibraryAnimation( 'LineCDirection', animSetup );
			}
			break;
			case 7:
			{
				m_directionAnimProxy = PlayLibraryAnimation( 'LineDDirection', animSetup );
			}
			break;
			case 8:
			{
				m_directionAnimProxy = PlayLibraryAnimation( 'LineDDirection', animSetup );
			}
			break;
			case 9:
			{
				animSetup.playReversed = true;
				m_directionAnimProxy = PlayLibraryAnimation( 'LineEDirection', animSetup );
			}
			break;
			case 10:
			{
				m_directionAnimProxy = PlayLibraryAnimation( 'LineEDirection', animSetup );
			}
			break;
		}
	}

	private function SwitchActiveButton( currentButtonFact : Int32 )
	{
		var animSetup : inkAnimOptions;
		animSetup.loopInfinite = false;
		animSetup.loopType = inkanimLoopType.None;
		animSetup.dependsOnTimeDilation = false;
		if( currentButtonFact == 0 )
		{
			animSetup.playReversed = true;
			ProcessButtonAnimation( m_previousAnimatioNumber, animSetup );
			return;
		}
		if( m_previousAnimatioNumber > 0 )
		{
			animSetup.playReversed = true;
			ProcessButtonAnimation( m_previousAnimatioNumber, animSetup );
		}
		animSetup.playReversed = false;
		ProcessButtonAnimation( currentButtonFact, animSetup );
		UpdateDirectionDisplay( currentButtonFact );
		m_previousAnimatioNumber = currentButtonFact;
	}

	private function UpdatePlayerLocationMarker( show : Bool )
	{
		var ownerObject : GameObject;
		var widget, targetWidget : weak< inkWidget >;
		var activeMetroStation : Int32;
		var i : Int32;
		var animSetup : inkAnimOptions;
		ownerObject = ( ( GameObject )( GetOwnerEntity() ) );
		widget = inkWidgetRef.Get( m_playerMarkerPane );
		activeMetroStation = GameInstance.GetQuestsSystem( ownerObject.GetGame() ).GetFact( 'ue_metro_active_station' );
		for( i = 0; i < m_playerCurrentPositionReferences.Size(); i += 1 )
		{
			if( m_playerCurrentPositionReferences[ i ].m_lineNumber == ( ( Uint32 )( activeMetroStation ) ) )
			{
				if( show )
				{
					targetWidget = inkWidgetRef.Get( m_playerCurrentPositionReferences[ i ].m_positionRefWidget );
					widget.SetMargin( targetWidget.GetMargin() );
					widget.UpdateMargin( -17.0, -8.0, 0.0, 0.0 );
					animSetup.loopInfinite = true;
					animSetup.loopType = inkanimLoopType.Cycle;
					PlayLibraryAnimation( 'player_marker_show' );
					m_playerPostionMarkerAnimProxy = PlayLibraryAnimation( 'player_marker_loop', animSetup );
				}
				else
				{
					animSetup.playReversed = true;
					animSetup.loopInfinite = false;
					animSetup.loopType = inkanimLoopType.None;
					m_playerPostionMarkerAnimProxy.Stop();
					PlayLibraryAnimation( 'player_marker_show', animSetup );
				}
			}
		}
	}

	private function UpdateAvialableLines()
	{
		var buttonWidget, LineContainerWidget, station14Widget : weak< inkWidget >;
		var ShowLineA, ShowLineB, ShowLineC, ShowLineD, ShowLineE : Bool;
		buttonWidget = ( ( inkCompoundWidget )( m_root.GetWidgetByPath( inkWidgetPath.Build( 'ButtonHolder', 'ButtonFlex', 'ButtonPane', 'ButtonLineA1' ) ) ) );
		if( m_questsSystem.GetFact( 'ue_metro_show_line_a1' ) )
		{
			buttonWidget.SetVisible( true );
			ShowLineA = true;
		}
		else
		{
			buttonWidget.SetVisible( false );
		}
		buttonWidget = ( ( inkCompoundWidget )( m_root.GetWidgetByPath( inkWidgetPath.Build( 'ButtonHolder', 'ButtonFlex', 'ButtonPane', 'ButtonLineA2' ) ) ) );
		if( m_questsSystem.GetFact( 'ue_metro_show_line_a2' ) )
		{
			buttonWidget.SetVisible( true );
			ShowLineA = true;
		}
		else
		{
			buttonWidget.SetVisible( false );
		}
		buttonWidget = ( ( inkCompoundWidget )( m_root.GetWidgetByPath( inkWidgetPath.Build( 'ButtonHolder', 'ButtonFlex', 'ButtonPane', 'ButtonLineB1' ) ) ) );
		if( m_questsSystem.GetFact( 'ue_metro_show_line_b1' ) )
		{
			buttonWidget.SetVisible( true );
			ShowLineB = true;
		}
		else
		{
			buttonWidget.SetVisible( false );
		}
		buttonWidget = ( ( inkCompoundWidget )( m_root.GetWidgetByPath( inkWidgetPath.Build( 'ButtonHolder', 'ButtonFlex', 'ButtonPane', 'ButtonLineB2' ) ) ) );
		if( m_questsSystem.GetFact( 'ue_metro_show_line_b2' ) )
		{
			buttonWidget.SetVisible( true );
			ShowLineB = true;
		}
		else
		{
			buttonWidget.SetVisible( false );
		}
		buttonWidget = ( ( inkCompoundWidget )( m_root.GetWidgetByPath( inkWidgetPath.Build( 'ButtonHolder', 'ButtonFlex', 'ButtonPane', 'ButtonLineC1' ) ) ) );
		if( m_questsSystem.GetFact( 'ue_metro_show_line_c1' ) )
		{
			buttonWidget.SetVisible( true );
			ShowLineC = true;
		}
		else
		{
			buttonWidget.SetVisible( false );
		}
		buttonWidget = ( ( inkCompoundWidget )( m_root.GetWidgetByPath( inkWidgetPath.Build( 'ButtonHolder', 'ButtonFlex', 'ButtonPane', 'ButtonLineC2' ) ) ) );
		if( m_questsSystem.GetFact( 'ue_metro_show_line_c2' ) )
		{
			buttonWidget.SetVisible( true );
			ShowLineC = true;
		}
		else
		{
			buttonWidget.SetVisible( false );
		}
		buttonWidget = ( ( inkCompoundWidget )( m_root.GetWidgetByPath( inkWidgetPath.Build( 'ButtonHolder', 'ButtonFlex', 'ButtonPane', 'ButtonLineD' ) ) ) );
		if( m_questsSystem.GetFact( 'ue_metro_show_line_d1' ) )
		{
			buttonWidget.SetVisible( true );
			ShowLineD = true;
		}
		else
		{
			buttonWidget.SetVisible( false );
		}
		buttonWidget = ( ( inkCompoundWidget )( m_root.GetWidgetByPath( inkWidgetPath.Build( 'ButtonHolder', 'ButtonFlex', 'ButtonPane', 'ButtonLineD' ) ) ) );
		if( m_questsSystem.GetFact( 'ue_metro_show_line_d2' ) || ShowLineD )
		{
			buttonWidget.SetVisible( true );
			ShowLineD = true;
		}
		else
		{
			buttonWidget.SetVisible( false );
		}
		buttonWidget = ( ( inkCompoundWidget )( m_root.GetWidgetByPath( inkWidgetPath.Build( 'ButtonHolder', 'ButtonFlex', 'ButtonPane', 'ButtonLineE1' ) ) ) );
		if( m_questsSystem.GetFact( 'ue_metro_show_line_e1' ) )
		{
			buttonWidget.SetVisible( true );
			ShowLineE = true;
		}
		else
		{
			buttonWidget.SetVisible( false );
		}
		buttonWidget = ( ( inkCompoundWidget )( m_root.GetWidgetByPath( inkWidgetPath.Build( 'ButtonHolder', 'ButtonFlex', 'ButtonPane', 'ButtonLineE2' ) ) ) );
		if( m_questsSystem.GetFact( 'ue_metro_show_line_e2' ) )
		{
			buttonWidget.SetVisible( true );
			ShowLineE = true;
		}
		else
		{
			buttonWidget.SetVisible( false );
		}
		LineContainerWidget = ( ( inkCompoundWidget )( m_root.GetWidgetByPath( inkWidgetPath.Build( 'MapHolder', 'MainMap', 'LineAContainer' ) ) ) );
		station14Widget = ( ( inkCompoundWidget )( m_root.GetWidgetByPath( inkWidgetPath.Build( 'MapHolder', 'MainMap', 'Station14Dots', 'Line_A_Station_14' ) ) ) );
		if( ShowLineA )
		{
			LineContainerWidget.SetOpacity( LineOnOpacity );
			station14Widget.SetOpacity( LineOnOpacity );
		}
		else
		{
			LineContainerWidget.SetOpacity( LineOffOpacity );
			station14Widget.SetOpacity( LineOffOpacity );
		}
		LineContainerWidget = ( ( inkCompoundWidget )( m_root.GetWidgetByPath( inkWidgetPath.Build( 'MapHolder', 'MainMap', 'LineBContainer' ) ) ) );
		if( ShowLineB )
		{
			LineContainerWidget.SetOpacity( LineOnOpacity );
		}
		else
		{
			LineContainerWidget.SetOpacity( LineOffOpacity );
		}
		LineContainerWidget = ( ( inkCompoundWidget )( m_root.GetWidgetByPath( inkWidgetPath.Build( 'MapHolder', 'MainMap', 'LineCContainer' ) ) ) );
		station14Widget = ( ( inkCompoundWidget )( m_root.GetWidgetByPath( inkWidgetPath.Build( 'MapHolder', 'MainMap', 'Station14Dots', 'Line_C_Station_14' ) ) ) );
		if( ShowLineC )
		{
			LineContainerWidget.SetOpacity( LineOnOpacity );
			station14Widget.SetOpacity( LineOnOpacity );
		}
		else
		{
			LineContainerWidget.SetOpacity( LineOffOpacity );
			station14Widget.SetOpacity( LineOffOpacity );
		}
		LineContainerWidget = ( ( inkCompoundWidget )( m_root.GetWidgetByPath( inkWidgetPath.Build( 'MapHolder', 'MainMap', 'LineDContainer' ) ) ) );
		station14Widget = ( ( inkCompoundWidget )( m_root.GetWidgetByPath( inkWidgetPath.Build( 'MapHolder', 'MainMap', 'Station14Dots', 'Line_D_Station_14' ) ) ) );
		if( ShowLineD )
		{
			LineContainerWidget.SetOpacity( LineOnOpacity );
			station14Widget.SetOpacity( LineOnOpacity );
		}
		else
		{
			LineContainerWidget.SetOpacity( LineOffOpacity );
			station14Widget.SetOpacity( LineOffOpacity );
		}
		LineContainerWidget = ( ( inkCompoundWidget )( m_root.GetWidgetByPath( inkWidgetPath.Build( 'MapHolder', 'MainMap', 'LineEContainer' ) ) ) );
		station14Widget = ( ( inkCompoundWidget )( m_root.GetWidgetByPath( inkWidgetPath.Build( 'MapHolder', 'MainMap', 'Station14Dots', 'Line_E_Station_14' ) ) ) );
		if( ShowLineE )
		{
			LineContainerWidget.SetOpacity( LineOnOpacity );
			station14Widget.SetOpacity( LineOnOpacity );
		}
		else
		{
			LineContainerWidget.SetOpacity( LineOffOpacity );
			station14Widget.SetOpacity( LineOffOpacity );
		}
	}

}

struct metroMapPlayerPositionReferences
{
	editable var m_lineNumber : Uint32;
	editable var m_positionRefWidget : inkWidgetRef;
}

