class WeakFence extends InteractiveDevice
{
	protected instanceeditable var m_impulseForce : Float;
	protected instanceeditable var m_impulseVector : Vector4;
	protected const editable var m_sideTriggerNames : array< CName >;
	protected var m_triggerComponents : array< TriggerComponent >;
	protected var m_currentWorkspotSuffix : CName;
	protected var m_offMeshConnectionComponent : OffMeshConnectionComponent;
	protected var m_physicalMesh : IPlacedComponent;

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

	protected event OnTakeControl( ri : EntityResolveComponentsInterface )
	{
		var i : Int32;
		super.OnTakeControl( ri );
		m_offMeshConnectionComponent = ( ( OffMeshConnectionComponent )( EntityResolveComponentsInterface.GetComponent( ri, 'offMeshConnection' ) ) );
		m_physicalMesh = ( ( IPlacedComponent )( EntityResolveComponentsInterface.GetComponent( ri, 'fence_door' ) ) );
		m_controller = ( ( WeakFenceController )( EntityResolveComponentsInterface.GetComponent( ri, 'controller' ) ) );
		for( i = 0; i < m_sideTriggerNames.Size(); i += 1 )
		{
			m_triggerComponents.PushBack( ( ( TriggerComponent )( EntityResolveComponentsInterface.GetComponent( ri, m_sideTriggerNames[ i ] ) ) ) );
		}
	}

	protected override function ResolveGameplayState()
	{
		super.ResolveGameplayState();
		if( GetDevicePS().IsDisabled() )
		{
			m_physicalMesh.Toggle( false );
			EnableOffMeshConnections();
		}
		else
		{
			DisableOffMeshConnections();
		}
	}

	protected const override function GetController() : WeakFenceController
	{
		return ( ( WeakFenceController )( m_controller ) );
	}

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

	protected event OnActivateDevice( evt : ActivateDevice )
	{
		PlayWorkspotAnimations();
		EnableOffMeshConnections();
	}

	protected event OnActionEngineering( evt : ActionEngineering )
	{
		PlayWorkspotAnimations();
		EnableOffMeshConnections();
	}

	protected function PlayWorkspotAnimations()
	{
		var workspotSystem : WorkspotGameSystem;
		var playerStateMachineBlackboard : IBlackboard;
		playerStateMachineBlackboard = GameInstance.GetBlackboardSystem( GetGame() ).GetLocalInstanced( GameInstance.GetPlayerSystem( GetGame() ).GetLocalPlayerControlledGameObject().GetEntityID(), GetAllBlackboardDefs().PlayerStateMachine );
		playerStateMachineBlackboard.SetBool( GetAllBlackboardDefs().PlayerStateMachine.IsInteractingWithDevice, true );
		CheckCurrentSide();
		workspotSystem = GameInstance.GetWorkspotSystem( GetGame() );
		workspotSystem.PlayInDevice( this, GameInstance.GetPlayerSystem( GetGame() ).GetLocalPlayerMainGameObject(), 'lockedCamera', 'playerWorkspot' + m_currentWorkspotSuffix, 'deviceWorkspot' + m_currentWorkspotSuffix, 'fence_sync' );
	}

	protected event OnWorkspotFinished( componentName : CName )
	{
		super.OnWorkspotFinished( componentName );
		UpdateAnimState();
	}

	protected function CheckCurrentSide()
	{
		var finalName : String;
		var i : Int32;
		var j : Int32;
		var overlappingEntities : array< Entity >;
		for( i = 0; i < m_triggerComponents.Size(); i += 1 )
		{
			overlappingEntities = m_triggerComponents[ i ].GetOverlappingEntities();
			for( j = 0; j < overlappingEntities.Size(); j += 1 )
			{
				if( ( ( GameObject )( overlappingEntities[ j ] ) ).IsPlayer() )
				{
					finalName = "Side" + ( ( String )( ( i + 1 ) ) );
					m_currentWorkspotSuffix = StringToName( finalName );
				}
			}
		}
	}

	private function UpdateAnimState()
	{
		var animFeature : AnimFeature_SimpleDevice;
		animFeature = new AnimFeature_SimpleDevice;
		animFeature.isOpen = true;
		if( m_currentWorkspotSuffix == 'Side1' )
		{
			animFeature.isOpenLeft = true;
		}
		else
		{
			animFeature.isOpenRight = true;
		}
		AnimationControllerComponent.ApplyFeature( this, 'weakFence', animFeature );
	}

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

	protected function EnableOffMeshConnections()
	{
		if( m_offMeshConnectionComponent != NULL )
		{
			m_offMeshConnectionComponent.EnableOffMeshConnection();
			m_offMeshConnectionComponent.EnableForPlayer();
		}
	}

	protected function DisableOffMeshConnections()
	{
		if( m_offMeshConnectionComponent != NULL )
		{
			m_offMeshConnectionComponent.DisableOffMeshConnection();
			m_offMeshConnectionComponent.DisableForPlayer();
		}
	}

}

