class WindowBlindersReplicatedState extends DeviceReplicatedState
{
	var m_isOpen : Bool;
	var m_isTilted : Bool;
}

class WindowBlinders extends InteractiveDevice
{
	default m_controllerTypeName = 'WindowBlindersController';
	private var m_animFeature : AnimFeature_SimpleDevice;
	private var m_workspotSideName : CName;
	protected var m_portalLight : gameLightComponent;
	protected var m_portalLight2 : gameLightComponent;
	protected var m_portalLight3 : gameLightComponent;
	protected var m_portalLight4 : gameLightComponent;
	protected const editable var m_sideTriggerNames : array< CName >;
	protected var m_triggerComponents : array< TriggerComponent >;
	protected var m_interactionBlockingCollider : IPlacedComponent;

	public export const override function GetDeviceStateClass() : CName
	{
		return 'WindowBlindersReplicatedState';
	}

	protected override function ApplyReplicatedState( const state : DeviceReplicatedState )
	{
		const var blindersState : WindowBlindersReplicatedState;
		super.ApplyReplicatedState( state );
		blindersState = ( ( WindowBlindersReplicatedState )( state ) );
		ApplyAnimState( blindersState.m_isOpen, blindersState.m_isTilted );
	}

	protected event OnRequestComponents( ri : EntityRequestComponentsInterface )
	{
		var i : Int32;
		super.OnRequestComponents( ri );
		for( i = 0; i < m_sideTriggerNames.Size(); i += 1 )
		{
			EntityRequestComponentsInterface.RequestComponent( ri, m_sideTriggerNames[ i ], 'TriggerComponent', true );
		}
		EntityRequestComponentsInterface.RequestComponent( ri, 'portal_light', 'gameLightComponent', false );
		EntityRequestComponentsInterface.RequestComponent( ri, 'portal_light_2', 'gameLightComponent', false );
		EntityRequestComponentsInterface.RequestComponent( ri, 'portal_light_gi', 'gameLightComponent', false );
		EntityRequestComponentsInterface.RequestComponent( ri, 'portal_light_gi_2', 'gameLightComponent', false );
		EntityRequestComponentsInterface.RequestComponent( ri, 'fullCollider', 'entColliderComponent', false );
	}

	protected event OnTakeControl( ri : EntityResolveComponentsInterface )
	{
		var i : Int32;
		super.OnTakeControl( ri );
		for( i = 0; i < m_sideTriggerNames.Size(); i += 1 )
		{
			m_triggerComponents.PushBack( ( ( TriggerComponent )( EntityResolveComponentsInterface.GetComponent( ri, m_sideTriggerNames[ i ] ) ) ) );
		}
		m_portalLight = ( ( gameLightComponent )( EntityResolveComponentsInterface.GetComponent( ri, 'portal_light' ) ) );
		m_portalLight2 = ( ( gameLightComponent )( EntityResolveComponentsInterface.GetComponent( ri, 'portal_light_2' ) ) );
		m_portalLight3 = ( ( gameLightComponent )( EntityResolveComponentsInterface.GetComponent( ri, 'portal_light_gi' ) ) );
		m_portalLight4 = ( ( gameLightComponent )( EntityResolveComponentsInterface.GetComponent( ri, 'portal_light_gi_2' ) ) );
		m_controller = ( ( WindowBlindersController )( EntityResolveComponentsInterface.GetComponent( ri, 'controller' ) ) );
		m_interactionBlockingCollider = ( ( IPlacedComponent )( EntityResolveComponentsInterface.GetComponent( ri, 'fullCollider' ) ) );
	}

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

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

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

	protected override function UpdateDeviceState( optional isDelayed : Bool ) : Bool
	{
		if( super.UpdateDeviceState( isDelayed ) )
		{
			UpdateAnimState();
			return true;
		}
		else
		{
			return false;
		}
	}

	protected event OnToggleOpen( evt : ToggleOpen )
	{
		UpdateDeviceState();
		GameObject.PlaySoundEvent( this, 'dev_doors_hidden_stop' );
	}

	protected event OnQuickHackToggleOpen( evt : QuickHackToggleOpen )
	{
		UpdateDeviceState();
		GameObject.PlaySoundEvent( this, 'dev_doors_hidden_stop' );
	}

	protected event OnToggleTilt( evt : ToggleTiltBlinders )
	{
		UpdateDeviceState();
		GameObject.PlaySoundEvent( this, 'dev_doors_hidden_stop' );
	}

	protected event OnActionEngineering( evt : ActionEngineering )
	{
		UpdateDeviceState();
	}

	protected event OnActionDemolition( evt : ActionDemolition )
	{
		UpdateDeviceState();
		EnterWorkspot();
	}

	protected function EnterWorkspot()
	{
		var workspotSystem : WorkspotGameSystem;
		var playerStateMachineBlackboard : IBlackboard;
		playerStateMachineBlackboard = GameInstance.GetBlackboardSystem( GetGame() ).GetLocalInstanced( GameInstance.GetPlayerSystem( GetGame() ).GetLocalPlayerMainGameObject().GetEntityID(), GetAllBlackboardDefs().PlayerStateMachine );
		playerStateMachineBlackboard.SetBool( GetAllBlackboardDefs().PlayerStateMachine.IsInteractingWithDevice, true );
		workspotSystem = GameInstance.GetWorkspotSystem( GetGame() );
		CheckCurrentSide();
		workspotSystem.PlayInDevice( this, GameInstance.GetPlayerSystem( GetGame() ).GetLocalPlayerMainGameObject(), 'lockedCamera', 'playerWorkspot' + m_workspotSideName, 'deviceWorkspot' + m_workspotSideName, 'blinders', 0.5, WorkspotSlidingBehaviour.PlayAtResourcePosition );
	}

	protected event OnQuestStatusChange( evt : PSChangedEvent )
	{
		UpdateDeviceState();
		GameObject.PlaySoundEvent( this, 'dev_doors_hidden_stop' );
	}

	private function UpdateAnimState()
	{
		var replicatedState : WindowBlindersReplicatedState;
		var ps : WindowBlindersControllerPS;
		replicatedState = ( ( WindowBlindersReplicatedState )( GetServerState() ) );
		ps = GetDevicePS();
		if( replicatedState )
		{
			replicatedState.m_isOpen = ps.IsOpen();
			replicatedState.m_isTilted = ps.IsTilted();
		}
		ApplyAnimState( ps.IsOpen(), ps.IsTilted() );
		UpdatePortalLights( ps.IsOpen() );
		if( !( m_wasAnimationFastForwarded ) )
		{
			FastForwardAnimations();
		}
	}

	private function UpdatePortalLights( isOpen : Bool )
	{
		if( m_portalLight && m_portalLight.IsEnabled() )
		{
			m_portalLight.ToggleLight( isOpen );
		}
		if( m_portalLight2 && m_portalLight2.IsEnabled() )
		{
			m_portalLight2.ToggleLight( isOpen );
		}
		if( m_portalLight3 && m_portalLight3.IsEnabled() )
		{
			m_portalLight3.ToggleLight( isOpen );
		}
		if( m_portalLight4 && m_portalLight4.IsEnabled() )
		{
			m_portalLight4.ToggleLight( isOpen );
		}
		m_interactionBlockingCollider.Toggle( !( ( ( WindowBlindersControllerPS )( GetDevicePS() ) ).IsOpen() ) );
	}

	private function ApplyAnimState( isOpen : Bool, isTilted : Bool )
	{
		if( !( m_animFeature ) )
		{
			m_animFeature = new AnimFeature_SimpleDevice;
		}
		m_animFeature.isOpen = isOpen;
		m_animFeature.isOpenLeft = isTilted;
		AnimationControllerComponent.ApplyFeature( this, 'DeviceWindowBlinders', m_animFeature );
	}

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

	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_workspotSideName = StringToName( finalName );
				}
			}
		}
		if( m_workspotSideName == '' )
		{
			m_workspotSideName = 'Side1';
		}
	}

}

