class BlinkingEvent extends Event
{
	var requestNumber : Int32;
}

class SecurityAlarm extends InteractiveMasterDevice
{
	default m_controllerTypeName = 'SecurityAlarmController';
	protected var m_workingAlarm : MeshComponent;
	protected var m_destroyedAlarm : MeshComponent;
	protected var m_isGlitching : Bool;

	protected event OnRequestComponents( ri : EntityRequestComponentsInterface )
	{
		super.OnRequestComponents( ri );
		EntityRequestComponentsInterface.RequestComponent( ri, 'alarm', 'MeshComponent', false );
		EntityRequestComponentsInterface.RequestComponent( ri, 'alarm_destroyed', 'MeshComponent', false );
	}

	protected event OnTakeControl( ri : EntityResolveComponentsInterface )
	{
		super.OnTakeControl( ri );
		m_workingAlarm = ( ( MeshComponent )( EntityResolveComponentsInterface.GetComponent( ri, 'alarm' ) ) );
		m_destroyedAlarm = ( ( MeshComponent )( EntityResolveComponentsInterface.GetComponent( ri, 'alarm_destroyed' ) ) );
		m_controller = ( ( SecurityAlarmController )( EntityResolveComponentsInterface.GetComponent( ri, 'controller' ) ) );
	}

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

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

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

	protected event OnToggleAlarm( evt : ToggleAlarm )
	{
		DetermineState();
	}

	protected event OnSecuritySystemOutput( evt : SecuritySystemOutput )
	{
		super.OnSecuritySystemOutput( evt );
		DetermineState();
	}

	protected event OnSecurityAlarmBreachResponse( evt : SecurityAlarmBreachResponse )
	{
		DetermineState();
	}

	protected event OnTargetAssessmentRequest( evt : TargetAssessmentRequest )
	{
		DetermineState();
	}

	protected event OnQuestForceSecuritySystemSafe( evt : QuestForceSecuritySystemSafe )
	{
		DetermineState();
	}

	protected event OnQuestForceSecuritySystemArmed( evt : QuestForceSecuritySystemArmed )
	{
		DetermineState();
	}

	protected override function StartGlitching( glitchState : EGlitchState, optional intensity : Float )
	{
		if( GetDevicePS().GetAlarmState() != ESecuritySystemState.COMBAT )
		{
			m_isGlitching = true;
			TurnOnLights();
			StartBlinking();
		}
	}

	protected override function StopGlitching()
	{
		m_isGlitching = false;
		StopBlinking();
		DetermineState();
	}

	protected function DetermineState()
	{
		if( !( m_isGlitching ) )
		{
			DeactivateState();
			if( GetDevicePS().GetAlarmState() == ESecuritySystemState.COMBAT )
			{
				SetCombatState();
			}
		}
	}

	protected function SetCombatState()
	{
		if( GetDevicePS().IsON() )
		{
			TurnOnLights();
			PlaySound();
			SendStim();
		}
	}

	protected function DeactivateState()
	{
		TurnOffLights();
		StopSound();
		StopStim();
	}

	protected function PlaySound()
	{
		if( GetDevicePS().UsesSound() )
		{
			PlaySound( this, GetDevicePS().AlarmSound() );
		}
	}

	protected function StopSound()
	{
		if( GetDevicePS().UsesSound() )
		{
			StopSound( this, GetDevicePS().AlarmSound() );
		}
	}

	protected function SendStim()
	{
		var stimType : gamedataStimType;
		var broadcaster : StimBroadcasterComponent;
		stimType = ( ( GetDevicePS().UsesSound() ) ? ( gamedataStimType.Alarm ) : ( gamedataStimType.SilentAlarm ) );
		broadcaster = GetStimBroadcasterComponent();
		if( broadcaster )
		{
			broadcaster.SetSingleActiveStimuli( this, stimType, , 20.0 );
		}
	}

	protected function StopStim()
	{
		var stimType : gamedataStimType;
		var broadcaster : StimBroadcasterComponent;
		stimType = ( ( GetDevicePS().UsesSound() ) ? ( gamedataStimType.Alarm ) : ( gamedataStimType.SilentAlarm ) );
		broadcaster = GetStimBroadcasterComponent();
		if( broadcaster )
		{
			broadcaster.RemoveActiveStimuliByName( this, stimType );
		}
	}

	protected virtual function TurnOffLights()
	{
		var evt : ToggleLightEvent;
		evt = new ToggleLightEvent;
		evt.toggle = false;
		QueueEvent( evt );
	}

	protected function TurnOnLights()
	{
		var evt : ToggleLightEvent;
		evt = new ToggleLightEvent;
		evt.toggle = true;
		QueueEvent( evt );
	}

	protected function StartBlinking()
	{
		var evt : ChangeCurveEvent;
		evt = new ChangeCurveEvent;
		evt.time = 3.0;
		evt.curve = 'BrokenLamp3';
		evt.loop = true;
		QueueEvent( evt );
	}

	protected function StopBlinking()
	{
		var evt : ChangeCurveEvent;
		evt = new ChangeCurveEvent;
		evt.time = 3.0;
		evt.curve = 'alarm';
		evt.loop = true;
		QueueEvent( evt );
	}

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

	protected override function TurnOffDevice()
	{
		DeactivateState();
	}

	protected override function CutPower()
	{
		DeactivateState();
	}

	protected override function DeactivateDevice()
	{
		super.DeactivateDevice();
		GetDevicePS().GetDeviceOperationsContainer().Execute( 'death_VFX', this );
		m_workingAlarm.Toggle( false );
		m_destroyedAlarm.Toggle( true );
	}

	protected override function ActivateDevice()
	{
		super.ActivateDevice();
		m_workingAlarm.Toggle( true );
		m_destroyedAlarm.Toggle( false );
	}

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

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

}

