class PhysicalHackingEvent extends Event
{
	var deviceName : String;
}

class Terminal extends InteractiveMasterDevice
{
	default m_controllerTypeName = 'TerminalController';
	protected var m_cameraFeed : ScriptableVirtualCameraViewComponent;
	private var m_isShortGlitchActive : Bool;
	private var m_shortGlitchDelayID : DelayID;

	protected event OnRequestComponents( ri : EntityRequestComponentsInterface )
	{
		EntityRequestComponentsInterface.RequestComponent( ri, 'terminalui', 'worlduiWidgetComponent', false );
		EntityRequestComponentsInterface.RequestComponent( ri, 'disassemblableComponent', 'DisassemblableComponent', true );
		super.OnRequestComponents( ri );
	}

	protected event OnTakeControl( ri : EntityResolveComponentsInterface )
	{
		m_uiComponent = ( ( worlduiWidgetComponent )( EntityResolveComponentsInterface.GetComponent( ri, 'terminalui' ) ) );
		m_disassemblableComponent = ( ( DisassemblableComponent )( EntityResolveComponentsInterface.GetComponent( ri, 'disassemblableComponent' ) ) );
		super.OnTakeControl( ri );
		m_controller = ( ( TerminalController )( EntityResolveComponentsInterface.GetComponent( ri, 'controller' ) ) );
	}

	protected override function ResolveGameplayState()
	{
		super.ResolveGameplayState();
		ResetScreenToDefault();
	}

	protected event OnLogicReady( evt : SetLogicReadyEvent )
	{
		super.OnLogicReady( evt );
		if( IsUIdirty() && m_isInsideLogicArea )
		{
			RefreshUI();
		}
	}

	protected event OnDetach()
	{
		super.OnDetach();
		GameInstance.GetGlobalTVSystem( GetGame() ).UnregisterTVChannelFromEntity( this );
	}

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

	protected override function UpdateDeviceState( optional isDelayed : Bool ) : Bool
	{
		if( super.UpdateDeviceState( isDelayed ) )
		{
			if( ( GetDevicePS().HasActiveContext( gamedeviceRequestType.Direct ) || GetDevicePS().IsAdvancedInteractionModeOn() ) || ( ShouldAlwasyRefreshUIInLogicAra() && m_isInsideLogicArea ) )
			{
				RefreshUI( isDelayed );
			}
			return true;
		}
		else
		{
			return false;
		}
	}

	protected override function ShouldAlwasyRefreshUIInLogicAra() : Bool
	{
		return true;
	}

	private const override function GetController() : TerminalController
	{
		return ( ( TerminalController )( m_controller ) );
	}

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

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

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

	protected override function CutPower()
	{
		TurnOffScreen();
		m_cameraFeed.Toggle( false );
	}

	protected override function TurnOffDevice()
	{
		TurnOffScreen();
		m_cameraFeed.Toggle( false );
	}

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

	protected event OnActionEngineering( evt : ActionEngineering )
	{
		var playerStateMachineBlackboard : IBlackboard;
		EnterWorkspot( GameInstance.GetPlayerSystem( GetGame() ).GetLocalPlayerControlledGameObject(), true, 'playerEngineeringWorkspot' );
		playerStateMachineBlackboard = GameInstance.GetBlackboardSystem( GetGame() ).Get( GetAllBlackboardDefs().PlayerStateMachine );
		playerStateMachineBlackboard.SetBool( GetAllBlackboardDefs().PlayerStateMachine.IsInteractingWithDevice, true );
	}

	protected event OnDisassembleDevice( evt : DisassembleDevice )
	{
		m_disassemblableComponent.ObtainParts();
		UpdateDeviceState();
	}

	protected event OnWorkspotFinished( componentName : CName )
	{
		super.OnWorkspotFinished( componentName );
		if( componentName == 'disassembleWorkspot' )
		{
			m_disassemblableComponent.ObtainParts();
		}
	}

	protected event OnAuthorizeUser( evt : AuthorizeUser )
	{
		var action : DeviceAction;
		if( ShouldExitZoomOnAuthorization() && GetDevicePS().IsAdvancedInteractionModeOn() )
		{
			action = GetDevicePS().ActionToggleZoomInteraction();
			ExecuteAction( action, GetPlayer( GetGame() ) );
		}
		super.OnAuthorizeUser( evt );
	}

	public const function IsAuthorizationModuleOn() : Bool
	{
		return GetDevicePS().IsAuthorizationModuleOn();
	}

	private function UnsecureTerminal()
	{
		ExecuteAction( GetDevicePS().GetActionByName( 'ToggleSecure' ) );
	}

	protected override function ShouldExitZoomOnAuthorization() : Bool
	{
		return true;
	}

	protected function StartHacking( executor : GameObject )
	{
		if( executor != NULL )
		{
		}
	}

	protected function ResetScreenToDefault()
	{
		if( GetDevicePS().IsON() )
		{
			return;
		}
		else
		{
			TurnOffScreen();
		}
	}

	protected function ShowScreenSaver() {}

	protected function TurnOffScreen()
	{
		m_uiComponent.Toggle( false );
		GameInstance.GetGlobalTVSystem( GetGame() ).UnregisterTVChannelFromEntity( this );
	}

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

	protected function SetState( state : gameinteractionsReactionState )
	{
		var evt : TerminalSetState;
		evt = new TerminalSetState;
		evt.state = state;
		GameInstance.GetPersistencySystem( GetGame() ).QueuePSEvent( GetController().GetPersistentID(), GetController().GetPSName(), evt );
	}

	private override function InitializeScreenDefinition()
	{
		if( !( TDBID.IsValid( m_screenDefinition.screenDefinition ) ) )
		{
			m_screenDefinition.screenDefinition = T"DevicesUIDefinitions.Terminal_9x16";
		}
		if( !( TDBID.IsValid( m_screenDefinition.style ) ) )
		{
			m_screenDefinition.style = T"DevicesUIStyles.None";
		}
	}

	public const override function ShouldShowTerminalTitle() : Bool
	{
		return GetDevicePS().ShouldShowTerminalTitle();
	}

	protected override function BreakDevice()
	{
		TurnOffScreen();
	}

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

	public const override function GetDefaultGlitchVideoPath() : ResRef
	{
		return GetDevicePS().GetDefaultGlitchVideoPath();
	}

	public const override function GetBroadcastGlitchVideoPath() : ResRef
	{
		return GetDevicePS().GetBroadcastGlitchVideoPath();
	}

	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, true );
		GetBlackboard().FireCallbacks();
	}

	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( GetDevicePS().GetBlackboardDef().GlitchData, glitchData );
		GetBlackboard().FireCallbacks();
	}

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

	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();
		}
	}

}

