class BlindingLight extends BasicDistractionDevice
{
	default m_controllerTypeName = 'BlindingLightController';
	protected instanceeditable var m_areaComponent : TriggerComponent;
	protected var m_highLightActive : Bool;

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

	protected event OnTakeControl( ri : EntityResolveComponentsInterface )
	{
		super.OnTakeControl( ri );
		m_areaComponent = ( ( TriggerComponent )( EntityResolveComponentsInterface.GetComponent( ri, 'area' ) ) );
		m_controller = ( ( BlindingLightController )( EntityResolveComponentsInterface.GetComponent( ri, 'controller' ) ) );
	}

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

	protected event OnOverloadDevice( evt : OverloadDevice )
	{
		if( evt.IsStarted() )
		{
			TurnOnDevice();
			GetDevicePS().GetDeviceOperationsContainer().Execute( 'light_cone', this );
			ApplyStatusEffect();
			RefreshInteraction();
		}
		else
		{
			RestoreDeviceState();
		}
	}

	protected override function StartDistraction( optional loopAnimation : Bool )
	{
		super.StartDistraction( loopAnimation );
		StartBlinking();
		PlaySoundEvent( this, GetDevicePS().GetDistractionSound() );
		m_interaction.Toggle( false );
	}

	protected override function StopDistraction()
	{
		super.StopDistraction();
		StopBlinking();
		m_interaction.Toggle( true );
		RefreshInteraction();
	}

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

	protected function StopBlinking()
	{
		var evt : ChangeCurveEvent;
		evt = new ChangeCurveEvent;
		QueueEvent( evt );
		RestoreDeviceState();
	}

	protected override function TurnOnDevice()
	{
		TurnOnLights();
		PlaySoundEvent( this, GetDevicePS().GetTurnOnSound() );
	}

	protected override function TurnOffDevice()
	{
		TurnOffLights();
		PlaySoundEvent( this, GetDevicePS().GetTurnOffSound() );
	}

	protected event OnAreaEnter( evt : AreaEnteredEvent )
	{
		var activator : weak< NPCPuppet >;
		super.OnAreaEnter( evt );
		activator = ( ( NPCPuppet )( EntityGameInterface.GetEntity( evt.activator ) ) );
		if( ( activator != NULL ) && m_highLightActive )
		{
			ToggleHighlightOnSingleTarget( true, activator.GetEntityID() );
		}
	}

	protected event OnAreaExit( evt : AreaExitedEvent )
	{
		var activator : weak< NPCPuppet >;
		super.OnAreaExit( evt );
		activator = ( ( NPCPuppet )( EntityGameInterface.GetEntity( evt.activator ) ) );
		if( ( activator != NULL ) && m_highLightActive )
		{
			ToggleHighlightOnSingleTarget( false, activator.GetEntityID() );
		}
	}

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

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

	public const function GetEntitiesInArea() : array< Entity >
	{
		return m_areaComponent.GetOverlappingEntities();
	}

	protected function ApplyStatusEffect()
	{
		var statusEffectID : TweakDBID;
		var entities : array< Entity >;
		var i : Int32;
		statusEffectID = T"BaseStatusEffect.Blind";
		entities = GetEntitiesInArea();
		for( i = 0; i < entities.Size(); i += 1 )
		{
			GameInstance.GetStatusEffectSystem( GetGame() ).ApplyStatusEffect( entities[ i ].GetEntityID(), statusEffectID );
		}
	}

	protected event OnRevealDeviceRequest( evt : RevealDeviceRequest )
	{
		super.OnRevealDeviceRequest( evt );
		if( !( GetDevicePS().ShouldRevealDevicesGrid() ) )
		{
			return true;
		}
		ToggleHighlightOnTargets( evt.shouldReveal );
	}

	protected function CreateHighlight( highlightType : EFocusForcedHighlightType ) : FocusForcedHighlightData
	{
		var highlight : FocusForcedHighlightData;
		highlight = new FocusForcedHighlightData;
		highlight.sourceID = GetEntityID();
		highlight.sourceName = GetClassName();
		highlight.highlightType = highlightType;
		highlight.inTransitionTime = 0.0;
		highlight.outTransitionTime = 0.0;
		highlight.priority = EPriority.VeryHigh;
		return highlight;
	}

	private function ToggleHighlightOnTargets( toggle : Bool )
	{
		var i : Int32;
		var entities : array< Entity >;
		entities = GetEntitiesInArea();
		m_highLightActive = toggle;
		for( i = 0; i < entities.Size(); i += 1 )
		{
			if( ( ( NPCPuppet )( entities[ i ] ) ) != NULL )
			{
				ToggleHighlightOnSingleTarget( toggle, entities[ i ].GetEntityID() );
			}
		}
	}

	protected function ToggleHighlightOnSingleTarget( toggle : Bool, id : EntityID )
	{
		var evt : ForceVisionApperanceEvent;
		var highlight : FocusForcedHighlightData;
		highlight = CreateHighlight( EFocusForcedHighlightType.DISTRACTION );
		evt = new ForceVisionApperanceEvent;
		evt.apply = toggle;
		evt.forcedHighlight = highlight;
		QueueEventForEntityID( id, evt );
	}

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

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

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

}

