class EMPEnded extends Event
{
}

class FuseBox extends InteractiveMasterDevice
{
	default m_controllerTypeName = 'ExplosiveDeviceController';
	default m_controllerTypeName = 'FuseBoxController';
	private var m_isShortGlitchActive : Bool;
	private var m_shortGlitchDelayID : DelayID;
	protected editable var m_numberOfComponentsToON : Int32;
	default m_numberOfComponentsToON = 0;
	protected editable var m_numberOfComponentsToOFF : Int32;
	default m_numberOfComponentsToOFF = 0;
	protected const editable var m_indexesOfComponentsToOFF : array< Int32 >;
	var m_mesh : MeshComponent;
	private var m_componentsON : array< IPlacedComponent >;
	private var m_componentsOFF : array< IPlacedComponent >;

	protected event OnRequestComponents( ri : EntityRequestComponentsInterface )
	{
		var i : Int32;
		var componentName : String;
		EntityRequestComponentsInterface.RequestComponent( ri, 'stand_generator', 'MeshComponent', false );
		super.OnRequestComponents( ri );
		for( i = 0; i < m_numberOfComponentsToON; i += 1 )
		{
			componentName = "componentON_" + i;
			EntityRequestComponentsInterface.RequestComponent( ri, StringToName( componentName ), 'IPlacedComponent', true );
		}
		for( i = 0; i < m_numberOfComponentsToOFF; i += 1 )
		{
			componentName = "componentOFF_" + i;
			EntityRequestComponentsInterface.RequestComponent( ri, StringToName( componentName ), 'IPlacedComponent', true );
		}
	}

	protected event OnTakeControl( ri : EntityResolveComponentsInterface )
	{
		var i : Int32;
		var componentName : String;
		m_mesh = ( ( MeshComponent )( EntityResolveComponentsInterface.GetComponent( ri, 'stand_generator' ) ) );
		for( i = 0; i < m_numberOfComponentsToON; i += 1 )
		{
			componentName = "componentON_" + i;
			m_componentsON.PushBack( ( ( IPlacedComponent )( EntityResolveComponentsInterface.GetComponent( ri, StringToName( componentName ) ) ) ) );
		}
		for( i = 0; i < m_numberOfComponentsToOFF; i += 1 )
		{
			componentName = "componentOFF_" + i;
			m_componentsOFF.PushBack( ( ( IPlacedComponent )( EntityResolveComponentsInterface.GetComponent( ri, StringToName( componentName ) ) ) ) );
		}
		super.OnTakeControl( ri );
		m_controller = ( ( FuseBoxController )( EntityResolveComponentsInterface.GetComponent( ri, 'controller' ) ) );
	}

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

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

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

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

	protected function ToggleComponentsON_OFF( visible : Bool )
	{
		var i : Int32;
		for( i = 0; i < m_indexesOfComponentsToOFF.Size(); i += 1 )
		{
			m_componentsOFF[ m_indexesOfComponentsToOFF[ i ] ].Toggle( visible );
		}
	}

	protected override function ResolveGameplayState()
	{
		if( GetDevicePS().IsOverloaded() )
		{
			ToggleVisibility( false );
		}
		super.ResolveGameplayState();
	}

	protected event OnOverloadDevice( evt : OverloadDevice )
	{
		if( evt.IsStarted() )
		{
			StartOverloading( evt.GetClassName() );
		}
		else
		{
			StopOverloading();
		}
	}

	private function StartOverloading( effectName : CName )
	{
		var empEffect : EffectInstance;
		var position : Vector4;
		var actionIndex : Int32;
		var areaEffect : AreaEffectData;
		actionIndex = GetFxResourceMapper().GetAreaEffectDataIndexByName( effectName );
		if( actionIndex < 0 )
		{
			return;
		}
		areaEffect = GetFxResourceMapper().GetAreaEffectDataByIndex( actionIndex );
		position = GetAcousticQuerryStartPoint();
		empEffect = GameInstance.GetGameEffectSystem( GetGame() ).CreateEffectStatic( 'emp', 'emp', this );
		EffectData.SetVector( empEffect.GetSharedData(), GetAllBlackboardDefs().EffectSharedData.position, position );
		EffectData.SetFloat( empEffect.GetSharedData(), GetAllBlackboardDefs().EffectSharedData.radius, areaEffect.stimRange );
		empEffect.Run();
		GameObjectEffectHelper.ActivateEffectAction( this, gamedataFxActionType.Start, 'emp' );
		StartGlitching( EGlitchState.DEFAULT, 1.0 );
		ToggleVisibility( false );
	}

	private function StopOverloading()
	{
		GameObjectEffectHelper.ActivateEffectAction( this, gamedataFxActionType.BreakLoop, 'smoke' );
		if( !( GetDevicePS().IsGlitching() ) )
		{
			StopGlitching();
		}
	}

	protected virtual function ToggleVisibility( visible : Bool )
	{
		var i : Int32;
		m_mesh.Toggle( visible );
		for( i = 0; i < m_numberOfComponentsToON; i += 1 )
		{
			m_componentsON[ i ].Toggle( !( visible ) );
		}
		for( i = 0; i < m_numberOfComponentsToOFF; i += 1 )
		{
			m_componentsOFF[ i ].Toggle( visible );
		}
		SetGameplayRoleToNone();
		GetDevicePS().ForceDisableDevice();
	}

	public const override function DeterminGameplayRole() : EGameplayRole
	{
		if( GetDevicePS().IsGenerator() )
		{
			return EGameplayRole.Distract;
		}
		else if( GetDevicePS().IsOFF() || GetDevicePS().IsDisabled() )
		{
			return EGameplayRole.None;
		}
		return EGameplayRole.CutPower;
	}

	protected override function StartGlitching( glitchState : EGlitchState, optional intensity : Float )
	{
		var evt : AdvertGlitchEvent;
		if( intensity == 0.0 )
		{
			intensity = 1.0;
		}
		evt = new AdvertGlitchEvent;
		evt.SetShouldGlitch( intensity );
		QueueEvent( evt );
		GameObjectEffectHelper.ActivateEffectAction( this, gamedataFxActionType.Start, 'smoke' );
	}

	protected override function StopGlitching()
	{
		var evt : AdvertGlitchEvent;
		evt = new AdvertGlitchEvent;
		evt.SetShouldGlitch( 0.0 );
		QueueEvent( evt );
		GameObjectEffectHelper.ActivateEffectAction( this, gamedataFxActionType.BreakLoop, 'smoke' );
	}

	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();
			GameObjectEffectHelper.ActivateEffectAction( this, gamedataFxActionType.Kill, 'smoke' );
		}
	}

	protected const override function HasAnyDirectInteractionActive() : Bool
	{
		if( IsDead() )
		{
			return false;
		}
		else
		{
			return true;
		}
	}

}

