class ExplosiveTriggerDeviceProximityEvent extends Event
{
	var instigator : EntityID;
}

class ExplosiveTriggerDevice extends ExplosiveDevice
{
	private var m_meshTrigger : MeshComponent;
	private var m_trapTrigger : TriggerComponent;
	private var triggerName : CName;
	default triggerName = 'trapTrigger';
	private var m_surroundingArea : TriggerComponent;
	private var m_surroundingAreaName : CName;
	default m_surroundingAreaName = 'surroundingArea';
	private var m_soundIsActive : Bool;
	private var m_playerIsInSurroundingArea : Bool;
	private var m_proximityExplosionEventID : DelayID;
	private var m_proximityExplosionEventSent : Bool;
	default m_proximityExplosionEventSent = false;

	protected event OnRequestComponents( ri : EntityRequestComponentsInterface )
	{
		super.OnRequestComponents( ri );
		EntityRequestComponentsInterface.RequestComponent( ri, 'meshTrigger', 'MeshComponent', false );
		EntityRequestComponentsInterface.RequestComponent( ri, triggerName, 'gameStaticTriggerAreaComponent', true );
		EntityRequestComponentsInterface.RequestComponent( ri, m_surroundingAreaName, 'gameStaticTriggerAreaComponent', true );
	}

	protected event OnTakeControl( ri : EntityResolveComponentsInterface )
	{
		m_meshTrigger = ( ( MeshComponent )( EntityResolveComponentsInterface.GetComponent( ri, 'meshTrigger' ) ) );
		m_trapTrigger = ( ( TriggerComponent )( EntityResolveComponentsInterface.GetComponent( ri, triggerName ) ) );
		m_surroundingArea = ( ( TriggerComponent )( EntityResolveComponentsInterface.GetComponent( ri, m_surroundingAreaName ) ) );
		super.OnTakeControl( ri );
		m_controller = ( ( ExplosiveDeviceController )( EntityResolveComponentsInterface.GetComponent( ri, 'controller' ) ) );
	}

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

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

	protected event OnAreaEnter( evt : AreaEnteredEvent )
	{
		var whoEntered : EntityID;
		var puppet : weak< ScriptedPuppet >;
		whoEntered = EntityGameInterface.GetEntity( evt.activator ).GetEntityID();
		puppet = ( ( ScriptedPuppet )( EntityGameInterface.GetEntity( evt.activator ) ) );
		if( !( GetDevicePS().IsON() ) )
		{
			return false;
		}
		if( GameObject.GetAttitudeTowards( ( ( ScriptedPuppet )( EntityGameInterface.GetEntity( evt.activator ) ) ), GameInstance.GetPlayerSystem( GetGame() ).GetLocalPlayerControlledGameObject() ) == EAIAttitude.AIA_Friendly && ( ( ExplosiveTriggerDeviceControllerPS )( GetDevicePS() ) ).CanPlayerSafePass() )
		{
			return false;
		}
		if( ScriptedPuppet.IsPlayerCompanion( ( ( ScriptedPuppet )( EntityGameInterface.GetEntity( evt.activator ) ) ) ) )
		{
			return false;
		}
		if( puppet && puppet.GetNPCType() == gamedataNPCType.Drone )
		{
			return false;
		}
		if( evt.componentName == m_surroundingAreaName )
		{
			ReactOnSurroundingArea( whoEntered );
		}
		else if( evt.componentName == triggerName )
		{
			ReactOnTrigger( whoEntered );
		}
	}

	private function ReactOnSurroundingArea( whoEnteredID : EntityID )
	{
		var authLevel : ESecurityAccessLevel;
		var proximityEvt : ExplosiveTriggerDeviceProximityEvent;
		GetDevicePS().IsConnectedToSecuritySystem( authLevel );
		if( GetDevicePS().GetSecuritySystem().IsUserAuthorized( whoEnteredID, authLevel ) )
		{
			return;
		}
		if( GetDevicePS().IsDisarmed() )
		{
			return;
		}
		if( whoEnteredID == GetPlayerMainObject().GetEntityID() )
		{
			m_playerIsInSurroundingArea = true;
		}
		proximityEvt = new ExplosiveTriggerDeviceProximityEvent;
		proximityEvt.instigator = whoEnteredID;
		m_proximityExplosionEventID = GameInstance.GetDelaySystem( GetGame() ).DelayEvent( this, proximityEvt, 2.0 );
		m_proximityExplosionEventSent = true;
		PlaySoundEvent( this, 'w_gre_mine_activate' );
		m_soundIsActive = true;
	}

	private function ReactOnTrigger( whoEnteredID : EntityID )
	{
		if( ( ( ExplosiveTriggerDeviceControllerPS )( GetDevicePS() ) ).CanPlayerSafePass() && ( whoEnteredID == GetPlayerMainObject().GetEntityID() ) )
		{
			return;
		}
		else if( !( GetDevicePS().CanPlayerSafePass() ) && ( whoEnteredID != GetPlayerMainObject().GetEntityID() ) )
		{
			return;
		}
		else
		{
			if( m_proximityExplosionEventSent )
			{
				GameInstance.GetDelaySystem( GetGame() ).CancelDelay( m_proximityExplosionEventID );
				m_proximityExplosionEventSent = false;
			}
			StartExplosionPipeline( this );
			StopSoundEvent( this, 'w_gre_mine_activate' );
			PlaySoundEvent( this, 'w_gre_mine_stop' );
			m_soundIsActive = false;
			GetDevicePS().TriggerSecuritySystemNotification( ( ( GameObject )( GameInstance.FindEntityByID( GetGame(), whoEnteredID ) ) ), GetWorldPosition(), ESecurityNotificationType.ALARM );
		}
	}

	protected event OnAreaExit( evt : AreaExitedEvent )
	{
		if( m_proximityExplosionEventSent )
		{
			GameInstance.GetDelaySystem( GetGame() ).CancelDelay( m_proximityExplosionEventID );
			m_proximityExplosionEventSent = false;
		}
		if( m_soundIsActive && !( GetDevicePS().IsDisarmed() ) )
		{
			StopSoundEvent( this, 'w_gre_mine_activate' );
			PlaySoundEvent( this, 'w_gre_mine_deactivate' );
			m_soundIsActive = false;
		}
		if( evt.triggerID == GetPlayerMainObject().GetEntityID() )
		{
			m_playerIsInSurroundingArea = false;
		}
	}

	protected event OnExplosiveTriggerDeviceProximityEvent( evt : ExplosiveTriggerDeviceProximityEvent )
	{
		m_proximityExplosionEventSent = false;
		if( !( GetDevicePS().IsDisarmed() ) && !( GetDevicePS().IsExploded() ) )
		{
			ReactOnTrigger( evt.instigator );
		}
	}

	protected override function ToggleVisibility( visible : Bool )
	{
		super.ToggleVisibility( visible );
		ToggleTriggerLogic( visible );
	}

	protected function ToggleTriggerLogic( state : Bool )
	{
		m_trapTrigger.Toggle( state );
		if( !( state ) )
		{
			ChangeLasersColor( ExplosiveTriggerDeviceLaserState.DISABLED );
		}
		else
		{
			if( GetDevicePS().CanPlayerSafePass() )
			{
				ChangeLasersColor( ExplosiveTriggerDeviceLaserState.GREEN );
			}
			else
			{
				ChangeLasersColor( ExplosiveTriggerDeviceLaserState.RED );
			}
		}
	}

	protected override function TurnOffDevice()
	{
		ToggleComponents( false );
		PlaySoundEvent( this, 'w_gre_mine_deactivate' );
		super.TurnOffDevice();
		if( m_proximityExplosionEventSent )
		{
			GameInstance.GetDelaySystem( GetGame() ).CancelDelay( m_proximityExplosionEventID );
			m_proximityExplosionEventSent = false;
		}
	}

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

	protected function ToggleComponents( state : Bool )
	{
		ToggleTriggerLogic( state );
	}

	private function ChangeLasersColor( laserState : ExplosiveTriggerDeviceLaserState )
	{
		var lightEvent : ChangeLightEvent;
		var isExploded : Bool;
		isExploded = GetDevicePS().IsExploded();
		if( !( isExploded ) )
		{
			lightEvent = new ChangeLightEvent;
			lightEvent.settings.strength = 1.0;
			lightEvent.time = 0.5;
			if( laserState == ExplosiveTriggerDeviceLaserState.GREEN )
			{
				GameObjectEffectHelper.StartEffectEvent( this, 'mine_laser_green' );
				GameObjectEffectHelper.BreakEffectLoopEvent( this, 'mine_laser_red' );
				lightEvent.settings.color = Color( 0, 255, 0, 0 );
			}
			else if( laserState == ExplosiveTriggerDeviceLaserState.RED )
			{
				GameObjectEffectHelper.StartEffectEvent( this, 'mine_laser_red' );
				GameObjectEffectHelper.BreakEffectLoopEvent( this, 'mine_laser_green' );
				lightEvent.settings.color = Color( 255, 0, 0, 0 );
			}
			QueueEvent( lightEvent );
		}
		if( laserState == ExplosiveTriggerDeviceLaserState.DISABLED )
		{
			if( isExploded )
			{
				GameObjectEffectHelper.StopEffectEvent( this, 'mine_laser_red' );
				GameObjectEffectHelper.StopEffectEvent( this, 'mine_laser_green' );
			}
			else
			{
				GameObjectEffectHelper.BreakEffectLoopEvent( this, 'mine_laser_red' );
				GameObjectEffectHelper.BreakEffectLoopEvent( this, 'mine_laser_green' );
			}
			lightEvent.settings.color = Color( 0, 0, 0, 0 );
			QueueEvent( lightEvent );
		}
	}

	protected event OnSetDeviceAttitude( evt : SetDeviceAttitude )
	{
		if( GetDevicePS().CanPlayerSafePass() )
		{
			ChangeLasersColor( ExplosiveTriggerDeviceLaserState.GREEN );
			if( m_soundIsActive && m_playerIsInSurroundingArea )
			{
				StopSoundEvent( this, 'w_gre_mine_activate' );
				PlaySoundEvent( this, 'w_gre_mine_deactivate' );
				m_soundIsActive = false;
			}
		}
		else
		{
			ChangeLasersColor( ExplosiveTriggerDeviceLaserState.RED );
		}
	}

	protected event OnQuestSetPlayerSafePass( evt : QuestSetPlayerSafePass )
	{
		if( GetDevicePS().CanPlayerSafePass() )
		{
			ChangeLasersColor( ExplosiveTriggerDeviceLaserState.GREEN );
		}
		else
		{
			ChangeLasersColor( ExplosiveTriggerDeviceLaserState.RED );
		}
	}

	public const override function DeterminGameplayRoleMappinVisuaState( const data : ref< SDeviceMappinData > ) : EMappinVisualState
	{
		if( ( GetDevicePS().CanPlayerSafePass() || GetDevicePS().IsDisarmed() ) || GetDevicePS().IsOFF() )
		{
			return EMappinVisualState.Unavailable;
		}
		else
		{
			return super.DeterminGameplayRoleMappinVisuaState( data );
		}
	}

}

enum ExplosiveTriggerDeviceLaserState
{
	GREEN = 0,
	RED = 1,
	DISABLED = 2,
}

