class BasicDistractionDevice extends InteractiveDevice
{
	default m_controllerTypeName = 'BasicDistractionDeviceController';
	protected var m_animFeatureDataDistractor : AnimFeature_DistractionState;
	protected var m_animFeatureDataNameDistractor : CName;
	protected const editable var m_distractionComponentSwapNamesToON : array< CName >;
	protected const editable var m_distractionComponentSwapNamesToOFF : array< CName >;
	private var m_distractionComponentON : array< IPlacedComponent >;
	private var m_distractionComponentOFF : array< IPlacedComponent >;
	[ category = "Distraction properties" ]
	protected editable var m_meshAppearanceNameON : CName;
	[ category = "Distraction properties" ]
	protected editable var m_meshAppearanceNameOFF : CName;

	protected event OnRequestComponents( ri : EntityRequestComponentsInterface )
	{
		var i : Int32;
		for( i = 0; i < m_distractionComponentSwapNamesToON.Size(); i += 1 )
		{
			EntityRequestComponentsInterface.RequestComponent( ri, m_distractionComponentSwapNamesToON[ i ], 'IPlacedComponent', true );
		}
		for( i = 0; i < m_distractionComponentSwapNamesToOFF.Size(); i += 1 )
		{
			EntityRequestComponentsInterface.RequestComponent( ri, m_distractionComponentSwapNamesToOFF[ i ], 'IPlacedComponent', true );
		}
		super.OnRequestComponents( ri );
	}

	protected event OnTakeControl( ri : EntityResolveComponentsInterface )
	{
		var i : Int32;
		for( i = 0; i < m_distractionComponentSwapNamesToON.Size(); i += 1 )
		{
			m_distractionComponentON.PushBack( ( ( IPlacedComponent )( EntityResolveComponentsInterface.GetComponent( ri, m_distractionComponentSwapNamesToON[ i ] ) ) ) );
		}
		for( i = 0; i < m_distractionComponentSwapNamesToOFF.Size(); i += 1 )
		{
			m_distractionComponentOFF.PushBack( ( ( IPlacedComponent )( EntityResolveComponentsInterface.GetComponent( ri, m_distractionComponentSwapNamesToOFF[ i ] ) ) ) );
		}
		super.OnTakeControl( ri );
		m_controller = ( ( BasicDistractionDeviceController )( EntityResolveComponentsInterface.GetComponent( ri, 'controller' ) ) );
	}

	protected event OnGameAttached()
	{
		m_animFeatureDataDistractor = new AnimFeature_DistractionState;
		m_animFeatureDataNameDistractor = 'distraction';
		super.OnGameAttached();
		if( GetDevicePS().GetForceAnimationSystem() )
		{
			ToggleForcedVisibilityInAnimSystem( 'DistractionDeviceSpecialForce', true, 0.0 );
		}
	}

	protected event OnDetach()
	{
		super.OnDetach();
		if( GetDevicePS().GetForceAnimationSystem() )
		{
			ToggleForcedVisibilityInAnimSystem( 'DistractionDeviceSpecialForce', false, 0.0 );
		}
	}

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

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

	protected override function TurnOnDevice()
	{
		super.TurnOnDevice();
		PlayTransformAnimation( 'turnON', true );
	}

	protected override function TurnOffDevice()
	{
		super.TurnOffDevice();
		StopTransformDistractAnimation( 'turnON' );
	}

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

	protected event OnSpiderbotDistractDevicePerformed( evt : SpiderbotDistractDevicePerformed )
	{
		if( evt.IsStarted() )
		{
			StartDistraction( true );
		}
		else
		{
			StopDistraction();
		}
	}

	protected event OnQuickHackDistraction( evt : QuickHackDistraction )
	{
		super.OnQuickHackDistraction( evt );
		if( evt.IsStarted() )
		{
			StartDistraction( true );
		}
		else
		{
			StopDistraction();
		}
	}

	protected event OnQuestStartGlitch( evt : QuestStartGlitch )
	{
		super.OnQuestStartGlitch( evt );
		StartDistraction( true );
	}

	protected event OnQuestStopGlitch( evt : QuestStopGlitch )
	{
		super.OnQuestStopGlitch( evt );
		StopDistraction();
	}

	protected virtual function StartDistraction( optional loopAnimation : Bool )
	{
		PlayDistractAnimation( loopAnimation );
		SetMeshAppearance( m_meshAppearanceNameON );
		EffectsOnStartPlay();
		MeshSwapOnDistraction( true );
	}

	protected virtual function StopDistraction()
	{
		StopDistractAnimation();
		EffectsOnStartStop();
		SetMeshAppearance( m_meshAppearanceNameOFF );
		MeshSwapOnDistraction( false );
	}

	protected virtual function PlayDistractAnimation( optional loop : Bool )
	{
		if( GetDevicePS().GetAnimationType() == EAnimationType.REGULAR )
		{
			PlayAnimgraphTransformAnimation();
		}
		else if( GetDevicePS().GetAnimationType() == EAnimationType.TRANSFORM )
		{
			PlayTransformAnimation( 'distraction', loop );
		}
	}

	protected virtual function StopDistractAnimation()
	{
		if( GetDevicePS().GetAnimationType() == EAnimationType.REGULAR )
		{
			StopAnimgraphTransformAnimation();
		}
		else if( GetDevicePS().GetAnimationType() == EAnimationType.TRANSFORM )
		{
			StopTransformDistractAnimation( 'distraction' );
		}
	}

	protected virtual function PlayAnimgraphTransformAnimation()
	{
		m_animFeatureDataDistractor.isOn = true;
		ApplyAnimFeatureToReplicate( this, m_animFeatureDataNameDistractor, m_animFeatureDataDistractor );
	}

	protected virtual function StopAnimgraphTransformAnimation()
	{
		m_animFeatureDataDistractor.isOn = false;
		ApplyAnimFeatureToReplicate( this, m_animFeatureDataNameDistractor, m_animFeatureDataDistractor );
	}

	protected virtual function PlayTransformAnimation( animationName : CName, optional loop : Bool )
	{
		var playEvent : gameTransformAnimationPlayEvent;
		playEvent = new gameTransformAnimationPlayEvent;
		playEvent.animationName = animationName;
		playEvent.timeScale = 1.0;
		playEvent.looping = loop;
		if( loop )
		{
			playEvent.timesPlayed = 1;
		}
		else
		{
			playEvent.timesPlayed = 100;
		}
		QueueEvent( playEvent );
	}

	protected virtual function StopTransformDistractAnimation( animationName : CName )
	{
		var playEvent : gameTransformAnimationPlayEvent;
		playEvent = new gameTransformAnimationPlayEvent;
		playEvent.timeScale = 1.0;
		playEvent.looping = false;
		playEvent.timesPlayed = 1;
		playEvent.animationName = animationName;
		QueueEvent( playEvent );
	}

	protected function EffectsOnStartPlay()
	{
		var effectNames : array< CName >;
		var i : Int32;
		effectNames = GetDevicePS().GetEffectOnStartNames();
		for( i = 0; i < effectNames.Size(); i += 1 )
		{
			GameObjectEffectHelper.StartEffectEvent( this, effectNames[ i ] );
		}
	}

	protected function EffectsOnStartStop( optional shouldStop : Bool )
	{
		var effectNames : array< CName >;
		var i : Int32;
		effectNames = GetDevicePS().GetEffectOnStartNames();
		for( i = 0; i < effectNames.Size(); i += 1 )
		{
			if( shouldStop )
			{
				GameObjectEffectHelper.StopEffectEvent( this, effectNames[ i ] );
			}
			else
			{
				GameObjectEffectHelper.BreakEffectLoopEvent( this, effectNames[ i ] );
			}
		}
	}

	protected function MeshSwapOnDistraction( start : Bool )
	{
		var i : Int32;
		for( i = 0; i < m_distractionComponentON.Size(); i += 1 )
		{
			m_distractionComponentON[ i ].Toggle( start );
		}
		for( i = 0; i < m_distractionComponentOFF.Size(); i += 1 )
		{
			m_distractionComponentOFF[ i ].Toggle( !( start ) );
		}
	}

}

