class NcartTimeTableCounterUpdateEvent extends Event
{
}

class NcartTimetable extends InteractiveDevice
{
	default m_controllerTypeName = 'NcartTimetableController';
	private var m_isShortGlitchActive : Bool;
	private var m_shortGlitchDelayID : DelayID;

	protected event OnRequestComponents( ri : EntityRequestComponentsInterface )
	{
		EntityRequestComponentsInterface.RequestComponent( ri, 'ui', 'worlduiWidgetComponent', false );
		super.OnRequestComponents( ri );
	}

	public override function ResavePersistentData( ps : PersistentState ) : Bool
	{
		return false;
	}

	protected event OnTakeControl( ri : EntityResolveComponentsInterface )
	{
		m_uiComponent = ( ( worlduiWidgetComponent )( EntityResolveComponentsInterface.GetComponent( ri, 'ui' ) ) );
		super.OnTakeControl( ri );
		m_controller = ( ( NcartTimetableController )( EntityResolveComponentsInterface.GetComponent( ri, 'controller' ) ) );
	}

	protected override function ResolveGameplayState()
	{
		super.ResolveGameplayState();
		if( IsUIdirty() && m_isInsideLogicArea )
		{
			RefreshUI();
		}
	}

	protected event OnPersitentStateInitialized( evt : GameAttachedEvent )
	{
		super.OnPersitentStateInitialized( evt );
		InitializeDisplayUpdate();
	}

	protected override function CreateBlackboard()
	{
		m_blackboard = IBlackboard.Create( GetAllBlackboardDefs().NcartTimetableBlackboard );
	}

	public const override function GetBlackboardDef() : NcartTimetableBlackboardDef
	{
		return GetDevicePS().GetBlackboardDef();
	}

	protected const override function GetController() : NcartTimetableController
	{
		return ( ( NcartTimetableController )( m_controller ) );
	}

	public const override function GetDevicePS() : NcartTimetableControllerPS
	{
		return GetController().GetPS();
	}

	protected override function StartGlitching( glitchState : EGlitchState, optional intensity : Float )
	{
		var glitchData : GlitchData;
		var evt : AdvertGlitchEvent;
		glitchData.state = glitchState;
		glitchData.intensity = intensity;
		if( intensity == 0.0 )
		{
			intensity = 1.0;
		}
		evt = new AdvertGlitchEvent;
		evt.SetShouldGlitch( intensity );
		QueueEvent( evt );
		GetBlackboard().SetVariant( GetBlackboardDef().GlitchData, glitchData );
		GetBlackboard().FireCallbacks();
		GameObjectEffectHelper.ActivateEffectAction( this, gamedataFxActionType.Start, 'hack_fx' );
	}

	protected override function StopGlitching()
	{
		var glitchData : GlitchData;
		var evt : AdvertGlitchEvent;
		evt = new AdvertGlitchEvent;
		evt.SetShouldGlitch( 0.0 );
		QueueEvent( evt );
		glitchData.state = EGlitchState.NONE;
		GetBlackboard().SetVariant( GetBlackboardDef().GlitchData, glitchData );
		GetBlackboard().FireCallbacks();
		GameObjectEffectHelper.ActivateEffectAction( this, gamedataFxActionType.BreakLoop, 'hack_fx' );
	}

	private function StartShortGlitch()
	{
		var evt : StopShortGlitchEvent;
		if( GetDevicePS().IsGlitching() )
		{
			return;
		}
		if( !( m_isShortGlitchActive ) )
		{
			evt = new StopShortGlitchEvent;
			StartGlitching( EGlitchState.DEFAULT, 1.0 );
			m_shortGlitchDelayID = GameInstance.GetDelaySystem( GetGame() ).DelayEvent( this, evt, 0.25 );
			m_isShortGlitchActive = true;
		}
	}

	protected event OnStopShortGlitch( evt : StopShortGlitchEvent )
	{
		m_isShortGlitchActive = false;
		if( !( GetDevicePS().IsGlitching() ) )
		{
			StopGlitching();
		}
	}

	protected event OnHitEvent( hit : gameHitEvent )
	{
		super.OnHitEvent( hit );
		StartShortGlitch();
	}

	protected override function TurnOnDevice()
	{
		super.TurnOnDevice();
		TurnOnScreen();
	}

	protected override function TurnOffDevice()
	{
		super.TurnOffDevice();
		TurnOffScreen();
	}

	protected override function CutPower()
	{
		super.CutPower();
		TurnOffScreen();
	}

	private function TurnOffScreen()
	{
		m_uiComponent.Toggle( false );
	}

	private function TurnOnScreen()
	{
		m_uiComponent.Toggle( true );
	}

	public const override function DeterminGameplayRole() : EGameplayRole
	{
		return EGameplayRole.Distract;
	}

	protected override function ApplyActiveStatusEffect( target : EntityID, statusEffect : TweakDBID )
	{
		if( IsActiveStatusEffectValid() && GetDevicePS().IsGlitching() )
		{
			GameInstance.GetStatusEffectSystem( GetGame() ).ApplyStatusEffect( target, statusEffect );
		}
	}

	protected override function UploadActiveProgramOnNPC( targetID : EntityID )
	{
		var evt : ExecutePuppetActionEvent;
		if( IsActiveProgramToUploadOnNPCValid() && GetDevicePS().IsGlitching() )
		{
			evt = new ExecutePuppetActionEvent;
			evt.actionID = GetActiveProgramToUploadOnNPC();
			QueueEventForEntityID( targetID, evt );
		}
	}

	private function InitializeDisplayUpdate()
	{
		var evt : NcartTimeTableCounterUpdateEvent;
		evt = new NcartTimeTableCounterUpdateEvent;
		GameInstance.GetDelaySystem( GetGame() ).DelayEvent( this, evt, GetDevicePS().GetUiUpdateFrequency() );
		UpdateCounterUI();
	}

	private function UpdateCounterUI()
	{
		var counterValue : Int32;
		counterValue = GetDevicePS().GetCurrentTimeToDepart();
		GetBlackboard().SetInt( GetAllBlackboardDefs().NcartTimetableBlackboard.TimeToDepart, counterValue, true );
		GetBlackboard().SetInt( GetAllBlackboardDefs().NcartTimetableBlackboard.NextTrainLine, GetDevicePS().GetCurrentLine(), true );
		GetBlackboard().FireCallbacks();
	}

	protected event OnCounterUpdate( evt : NcartTimeTableCounterUpdateEvent )
	{
		evt = new NcartTimeTableCounterUpdateEvent;
		GetDevicePS().UpdateCurrentTimeToDepart();
		UpdateCounterUI();
		GameInstance.GetDelaySystem( GetGame() ).DelayEvent( this, evt, GetDevicePS().GetUiUpdateFrequency() );
	}

}

