abstract class ProximityDetector extends Device
{
	default m_controllerTypeName = 'ProximityDetectorController';
	protected const var m_scanningAreaName : CName;
	default m_scanningAreaName = 'scanningArea';
	protected const var m_surroundingAreaName : CName;
	default m_surroundingAreaName = 'surroundingArea';
	protected var m_scanningArea : TriggerComponent;
	protected var m_surroundingArea : TriggerComponent;
	private var m_securityAreaType : ESecurityAreaType;
	private var m_notifiactionType : ESecurityNotificationType;

	protected event OnRequestComponents( ri : EntityRequestComponentsInterface )
	{
		EntityRequestComponentsInterface.RequestComponent( ri, m_scanningAreaName, 'gameStaticTriggerAreaComponent', false );
		EntityRequestComponentsInterface.RequestComponent( ri, m_surroundingAreaName, 'gameStaticTriggerAreaComponent', false );
		super.OnRequestComponents( ri );
	}

	protected event OnTakeControl( ri : EntityResolveComponentsInterface )
	{
		m_scanningArea = ( ( TriggerComponent )( EntityResolveComponentsInterface.GetComponent( ri, m_scanningAreaName ) ) );
		m_surroundingArea = ( ( TriggerComponent )( EntityResolveComponentsInterface.GetComponent( ri, m_surroundingAreaName ) ) );
		super.OnTakeControl( ri );
		m_controller = ( ( ProximityDetectorController )( EntityResolveComponentsInterface.GetComponent( ri, 'controller' ) ) );
	}

	protected override function ResolveGameplayState()
	{
		var i : Int32;
		var secAreas : array< SecurityAreaControllerPS >;
		super.ResolveGameplayState();
		secAreas = GetDevicePS().GetSecurityAreas();
		if( secAreas.Size() == 0 )
		{
			if( !( IsFinal() ) )
			{
			}
			return;
		}
		m_securityAreaType = ESecurityAreaType.DISABLED;
		for( i = 0; i < secAreas.Size(); i += 1 )
		{
			if( secAreas[ i ].GetSecurityAreaType() > m_securityAreaType )
			{
				m_securityAreaType = secAreas[ i ].GetSecurityAreaType();
			}
		}
		if( m_securityAreaType == ESecurityAreaType.SAFE )
		{
			LockDevice( false );
		}
		if( m_securityAreaType > ESecurityAreaType.RESTRICTED )
		{
			m_notifiactionType = ESecurityNotificationType.COMBAT;
		}
		else
		{
			m_notifiactionType = ESecurityNotificationType.ILLEGAL_ACTION;
		}
	}

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

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

	protected event OnAreaEnter( evt : AreaEnteredEvent )
	{
		var whoEntered : EntityID;
		var authLevel : ESecurityAccessLevel;
		if( !( IsDeviceUsable() ) )
		{
			return false;
		}
		whoEntered = EntityGameInterface.GetEntity( evt.activator ).GetEntityID();
		if( evt.componentName == m_surroundingAreaName )
		{
			if( ( whoEntered == GetPlayerMainObject().GetEntityID() ) && GetDevicePS().IsConnectedToSecuritySystem( authLevel ) )
			{
				if( GetDevicePS().GetSecuritySystem().IsUserAuthorized( whoEntered, authLevel ) )
				{
					LockDevice( false );
					return false;
				}
			}
		}
		if( evt.componentName == m_scanningAreaName )
		{
			if( GetDevicePS().IsConnectedToSecuritySystem( authLevel ) && !( GetDevicePS().GetSecuritySystem().IsUserAuthorized( whoEntered, authLevel ) ) )
			{
				GetDevicePS().TriggerSecuritySystemNotification( ( ( GameObject )( EntityGameInterface.GetEntity( evt.activator ) ) ), EntityGameInterface.GetEntity( evt.activator ).GetWorldPosition(), m_notifiactionType );
			}
		}
	}

	protected event OnAreaExit( evt : AreaExitedEvent )
	{
		var whoLeft : EntityID;
		if( !( IsDeviceUsable() ) )
		{
			return NULL;
		}
		if( evt.componentName != m_surroundingAreaName )
		{
			return NULL;
		}
		whoLeft = EntityGameInterface.GetEntity( evt.activator ).GetEntityID();
		if( whoLeft == GetPlayerMainObject().GetEntityID() )
		{
			LockDevice( true );
		}
	}

	protected event OnTargetAssessmentRequest( evt : TargetAssessmentRequest )
	{
		var secSys : SecuritySystemControllerPS;
		if( !( IsDeviceUsable() ) )
		{
			return false;
		}
		secSys = GetDevicePS().GetSecuritySystem();
		if( secSys )
		{
			if( secSys.GetMostDangerousSecurityAreaForEntityID( GetEntityID() ).GetSecurityAreaType() == ESecurityAreaType.SAFE && secSys.IsSystemSafe() )
			{
				LockDevice( false );
			}
			else
			{
				LockDevice( true );
			}
		}
	}

	protected function IsDeviceUsable() : Bool
	{
		return GetDevicePS().IsPoweredAndEnabled() && !( GetDevicePS().IsOFF() );
	}

	protected override function TurnOffDevice()
	{
		super.TurnOffDevice();
		ToggleComponents( false );
	}

	protected override function TurnOnDevice()
	{
		super.TurnOnDevice();
		ToggleComponents( true );
	}

	private function ToggleComponents( on : Bool )
	{
		m_scanningArea.Toggle( on );
		m_surroundingArea.Toggle( on );
	}

	protected virtual function LockDevice( enableLock : Bool ) {}

	protected event OnFullSystemRestart( evt : FullSystemRestart )
	{
		ToggleComponents( false );
		LockDevice( false );
	}

	protected event OnWakeUpFromRestartEvent( evt : WakeUpFromRestartEvent )
	{
		ToggleComponents( true );
		LockDevice( true );
	}

}

