class ElevatorInkGameController extends DeviceInkGameControllerBase
{
	[ category = "Widget Refs" ]
	private editable var m_verticalPanel : inkVerticalPanelRef;
	[ category = "Widget Refs" ]
	private editable var m_currentFloorTextWidget : inkTextRef;
	[ category = "Widget Refs" ]
	private editable var m_openCloseButtonWidgets : inkCanvasRef;
	[ category = "Widget Refs" ]
	private editable var m_elevatorUpArrowsWidget : inkFlexRef;
	[ category = "Widget Refs" ]
	private editable var m_elevatorDownArrowsWidget : inkFlexRef;
	[ category = "Widget Refs" ]
	private editable var m_waitingStateWidget : inkCanvasRef;
	[ category = "Widget Refs" ]
	private editable var m_dataScanningWidget : inkCanvasRef;
	[ category = "Widget Refs" ]
	private editable var m_elevatorStoppedWidget : inkCanvasRef;
	protected var m_isPlayerScanned : Bool;
	protected var m_isPaused : Bool;
	protected var m_isAuthorized : Bool;
	protected var m_animProxy : inkAnimProxy;
	protected const editable var m_buttonSizes : array< Float >;
	private var m_onChangeFloorListener : CallbackHandle;
	private var m_onPlayerScannedListener : CallbackHandle;
	private var m_onPausedChangeListener : CallbackHandle;

	protected override function SetupWidgets()
	{
		if( !( m_isInitialized ) )
		{
			InitializeCurrentFloorName();
		}
	}

	protected function InitializeCurrentFloorName()
	{
		var lift : LiftDevice;
		lift = ( ( LiftDevice )( GetOwner() ) );
		if( lift )
		{
			SetCurrentFloorOnUI( lift.GetBlackboard().GetString( lift.GetBlackboardDef().CurrentFloor ) );
		}
	}

	public override function UpdateActionWidgets( const widgetsData : ref< array< SActionWidgetPackage > > )
	{
		var i : Int32;
		var widget : inkWidget;
		var isListEmpty : Bool;
		var isMoving : Int32;
		var isPowered : Bool;
		var isOn : Bool;
		var isAuthorized : Bool;
		var animOptions : inkAnimOptions;
		HideActionWidgets();
		inkFlexRef.SetVisible( m_elevatorDownArrowsWidget, false );
		inkFlexRef.SetVisible( m_elevatorUpArrowsWidget, false );
		inkCanvasRef.SetVisible( m_waitingStateWidget, false );
		inkCanvasRef.SetVisible( m_dataScanningWidget, false );
		inkCanvasRef.SetVisible( m_elevatorStoppedWidget, false );
		m_animProxy.Pause();
		animOptions.loopType = inkanimLoopType.Cycle;
		animOptions.loopInfinite = true;
		if( GetOwner() )
		{
			isMoving = GetOwner().GetMovingMode();
			isPowered = GetOwner().GetDevicePS().IsPowered();
			isOn = GetOwner().GetDevicePS().IsON();
			isAuthorized = GetOwner().GetDevicePS().IsPlayerAuthorized();
		}
		if( m_isPaused )
		{
			inkCanvasRef.SetVisible( m_elevatorStoppedWidget, true );
			m_animProxy = PlayLibraryAnimation( 'elevator_stopped', animOptions );
			return;
		}
		if( ( !( m_isPlayerScanned ) && isPowered ) && isOn )
		{
			m_isPlayerScanned = GetOwner().GetBlackboard().GetBool( GetAllBlackboardDefs().ElevatorDeviceBlackboard.isPlayerScanned );
			if( !( m_isPlayerScanned ) )
			{
				inkCanvasRef.SetVisible( m_dataScanningWidget, true );
				m_animProxy = PlayLibraryAnimation( 'data_scanning', animOptions );
				return;
			}
		}
		for( i = 0; i < widgetsData.Size(); i += 1 )
		{
			widget = GetActionWidget( widgetsData[ i ] );
			if( widget == NULL )
			{
				CreateActionWidgetAsync( inkVerticalPanelRef.Get( m_verticalPanel ), widgetsData[ i ] );
			}
			else
			{
				RefreshFloor( widget, widgetsData[ i ], i, widgetsData.Size() );
			}
		}
		if( !( isAuthorized ) )
		{
			( ( DeviceButtonLogicControllerBase )( widget.GetController() ) ).SetButtonSize( 100.0, m_buttonSizes[ 0 ] );
			return;
		}
		isListEmpty = widgetsData.Size() == 0;
		if( isListEmpty )
		{
			if( isMoving > 0 )
			{
				inkFlexRef.SetVisible( m_elevatorUpArrowsWidget, true );
				( ( ElevatorArrowsLogicController )( inkFlexRef.GetController( m_elevatorUpArrowsWidget ) ) ).PlayAnimationsArrowsUp();
			}
			else if( isMoving < 0 )
			{
				inkFlexRef.SetVisible( m_elevatorDownArrowsWidget, true );
				( ( ElevatorArrowsLogicController )( inkFlexRef.GetController( m_elevatorDownArrowsWidget ) ) ).PlayAnimationsArrowsDown();
			}
			else if( isMoving == 0 )
			{
				HideActionWidgets();
				inkCanvasRef.SetVisible( m_waitingStateWidget, true );
				m_animProxy = PlayLibraryAnimation( 'waiting_for_elevator', animOptions );
			}
		}
	}

	protected function RefreshFloor( widget : inkWidget, const widgetData : ref< SActionWidgetPackage >, floorNumber : Int32, maxFloors : Int32 )
	{
		InitializeActionWidget( widget, widgetData );
		switch( maxFloors )
		{
			case 1:
				( ( DeviceButtonLogicControllerBase )( widget.GetController() ) ).SetButtonSize( 100.0, m_buttonSizes[ 0 ] );
			break;
			case 2:
				( ( DeviceButtonLogicControllerBase )( widget.GetController() ) ).SetButtonSize( 100.0, m_buttonSizes[ 1 ] );
			break;
			case 3:
				( ( DeviceButtonLogicControllerBase )( widget.GetController() ) ).SetButtonSize( 100.0, m_buttonSizes[ 2 ] );
			break;
			case 4:
				( ( DeviceButtonLogicControllerBase )( widget.GetController() ) ).SetButtonSize( 100.0, m_buttonSizes[ 3 ] );
			break;
			case 5:
				( ( DeviceButtonLogicControllerBase )( widget.GetController() ) ).SetButtonSize( 100.0, m_buttonSizes[ 4 ] );
			break;
		}
		inkVerticalPanelRef.ReorderChild( m_verticalPanel, widget, floorNumber );
	}

	protected event OnActionWidgetSpawned( widget : inkWidget, userData : IScriptable )
	{
		super.OnActionWidgetSpawned( widget, userData );
		Refresh( GetOwner().GetDeviceState() );
	}

	public function SetCurrentFloorOnUI( const floorName : ref< String > )
	{
		inkTextRef.SetLetterCase( m_currentFloorTextWidget, textLetterCase.UpperCase );
		inkTextRef.SetLocalizedTextScript( m_currentFloorTextWidget, floorName );
	}

	protected override function GetOwner() : LiftDevice
	{
		return ( ( LiftDevice )( GetOwnerEntity() ) );
	}

	protected override function RegisterBlackboardCallbacks( blackboard : IBlackboard )
	{
		super.RegisterBlackboardCallbacks( blackboard );
		if( blackboard )
		{
			m_onChangeFloorListener = blackboard.RegisterListenerString( GetOwner().GetBlackboardDef().CurrentFloor, this, 'OnChangeFloor' );
			m_onPlayerScannedListener = blackboard.RegisterListenerBool( GetOwner().GetBlackboardDef().isPlayerScanned, this, 'OnPlayerScanned' );
			m_onPausedChangeListener = blackboard.RegisterListenerBool( GetOwner().GetBlackboardDef().isPaused, this, 'OnPausedChange' );
		}
	}

	protected override function UnRegisterBlackboardCallbacks( blackboard : IBlackboard )
	{
		super.UnRegisterBlackboardCallbacks( blackboard );
		if( blackboard )
		{
			blackboard.UnregisterListenerString( GetOwner().GetBlackboardDef().CurrentFloor, m_onChangeFloorListener );
			blackboard.UnregisterListenerBool( GetOwner().GetBlackboardDef().isPlayerScanned, m_onPlayerScannedListener );
			blackboard.UnregisterListenerBool( GetOwner().GetBlackboardDef().isPaused, m_onPausedChangeListener );
		}
	}

	protected event OnPlayerScanned( value : Bool )
	{
		if( m_isPlayerScanned != value )
		{
			m_isPlayerScanned = value;
			Refresh( GetOwner().GetDeviceState() );
		}
	}

	protected event OnPausedChange( value : Bool )
	{
		if( m_isPaused != value )
		{
			m_isPaused = value;
			Refresh( GetOwner().GetDeviceState() );
		}
	}

	protected event OnChangeFloor( value : String )
	{
		SetCurrentFloorOnUI( value );
	}

	public override function Refresh( state : EDeviceStatus )
	{
		SetupWidgets();
		super.Refresh( state );
		RequestActionWidgetsUpdate();
	}

}

class ElevatorTerminalFakeGameController extends DeviceInkGameControllerBase
{
	private editable var m_elevatorTerminalWidget : inkCanvasRef;

	public override function Refresh( state : EDeviceStatus )
	{
		var widgetPackage : SDeviceWidgetPackage;
		super.Refresh( state );
		( ( ElevatorTerminalLogicController )( inkCanvasRef.GetController( m_elevatorTerminalWidget ) ) ).Initialize( this, widgetPackage );
	}

}

