enum CoverState
{
	Open = 0,
	Closed = 1,
}

enum ServerState
{
	Inactive = 0,
	Active = 1,
	Damaged = 2,
	Destroyed = 3,
}

class ServerNodeController extends ScriptableDeviceComponent
{

	public const override function GetPS() : ServerNodeControllerPS
	{
		return ( ( ServerNodeControllerPS )( GetBasePS() ) );
	}

}

class ServerNodeControllerPS extends ScriptableDeviceComponentPS
{
	default m_deviceState = EDeviceStatus.ON;
	private persistent var m_coverState : CoverState;
	default m_coverState = CoverState.Closed;
	private persistent var m_serverState : ServerState;
	default m_serverState = ServerState.Inactive;
	private persistent var m_destroyedPin : Int32[ 12 ];

	public const function GetCoverState() : CoverState
	{
		return m_coverState;
	}

	public const function GetServerState() : ServerState
	{
		return m_serverState;
	}

	public const function IsPinDestroyed( index : Int32 ) : Bool
	{
		return m_destroyedPin[ index ] == 1;
	}

	public function SetCoverState( state : CoverState )
	{
		m_coverState = state;
	}

	public function SetServerState( state : ServerState )
	{
		m_serverState = state;
	}

	public function SetDestroyedPin( pinNum : Int32 )
	{
		m_destroyedPin[ pinNum ] = 1;
	}

	public override function GetQuestActions( out actions : array< DeviceAction >, const context : ref< GetActionsContext > )
	{
		super.GetQuestActions( actions, context );
		actions.PushBack( ActionQuestOpen() );
		actions.PushBack( ActionQuestClose() );
		actions.PushBack( ActionQuestExplode() );
		actions.PushBack( ActionQuestStartHacking() );
		actions.PushBack( ActionQuestStopHacking() );
	}

	protected const override function CanCreateAnyQuickHackActions() : Bool
	{
		return true;
	}

	protected override function GetQuickHackActions( out actions : array< DeviceAction >, const context : ref< GetActionsContext > )
	{
		var currentAction : ScriptableDeviceAction;
		currentAction = ActionOverloadDevice();
		currentAction.SetObjectActionID( T"DeviceAction.ServerSingleOverloadClassHack" );
		currentAction.SetInactiveWithReason( IsPowered(), "LocKey#7013" );
		actions.PushBack( currentAction );
		currentAction = ActionServerOverload();
		actions.PushBack( currentAction );
		FinalizeGetQuickHackActions( actions, context );
	}

	public function ActionQuestOpen() : QuestOpen
	{
		var action : QuestOpen;
		action = new QuestOpen;
		action.clearanceLevel = DefaultActionsParametersHolder.GetQuestClearance();
		action.SetUp( this );
		action.SetProperties();
		action.AddDeviceName( m_deviceName );
		return action;
	}

	public function ActionQuestClose() : QuestClose
	{
		var action : QuestClose;
		action = new QuestClose;
		action.clearanceLevel = DefaultActionsParametersHolder.GetQuestClearance();
		action.SetUp( this );
		action.SetProperties();
		action.AddDeviceName( m_deviceName );
		return action;
	}

	public function ActionQuestExplode() : QuestExplode
	{
		var action : QuestExplode;
		action = new QuestExplode;
		action.clearanceLevel = DefaultActionsParametersHolder.GetQuestClearance();
		action.SetUp( this );
		action.SetProperties();
		action.AddDeviceName( m_deviceName );
		return action;
	}

	public function ActionQuestStartHacking() : QuestStartHacking
	{
		var action : QuestStartHacking;
		action = new QuestStartHacking;
		action.clearanceLevel = DefaultActionsParametersHolder.GetQuestClearance();
		action.SetUp( this );
		action.SetProperties();
		action.AddDeviceName( m_deviceName );
		return action;
	}

	public function ActionQuestStopHacking() : QuestStopHacking
	{
		var action : QuestStopHacking;
		action = new QuestStopHacking;
		action.clearanceLevel = DefaultActionsParametersHolder.GetQuestClearance();
		action.SetUp( this );
		action.SetProperties();
		action.AddDeviceName( m_deviceName );
		return action;
	}

	private function ActionServerOverload() : ServerOverload
	{
		var action : ServerOverload;
		action = new ServerOverload;
		action.clearanceLevel = DefaultActionsParametersHolder.GetQuestClearance();
		action.SetUp( this );
		action.SetProperties();
		action.AddDeviceName( m_deviceName );
		action.SetObjectActionID( T"DeviceAction.ServerOverloadClassHack" );
		action.SetInactiveWithReason( IsPowered(), "LocKey#7013" );
		return action;
	}

	private function TryUpdateServerState( serverState : ServerState ) : Bool
	{
		if( m_deviceState != EDeviceStatus.DISABLED && m_serverState != serverState )
		{
			SetServerState( serverState );
			return true;
		}
		return false;
	}

	private function TryUpdateCoverState( coverState : CoverState ) : Bool
	{
		if( m_deviceState != EDeviceStatus.DISABLED )
		{
			SetCoverState( coverState );
			return true;
		}
		return false;
	}

	private constexpr function GetNotificationBasedOnServerUpdateState( wasStateUpdated : Bool ) : EntityNotificationType
	{
		return ( ( wasStateUpdated ) ? ( EntityNotificationType.SendThisEventToEntity ) : ( EntityNotificationType.DoNotNotifyEntity ) );
	}

	private constexpr function TryOpenServer() : Bool
	{
		return m_coverState == CoverState.Closed && TryUpdateCoverState( CoverState.Open );
	}

	private constexpr function TryCloseServer() : Bool
	{
		return ( m_coverState == CoverState.Open && TryUpdateCoverState( CoverState.Closed ) ) && TryUpdateServerState( ServerState.Inactive );
	}

	public constexpr function TryExplode() : Bool
	{
		return TryUpdateServerState( ServerState.Destroyed );
	}

	private constexpr function OnQuestOpen( evt : QuestOpen ) : EntityNotificationType
	{
		return GetNotificationBasedOnServerUpdateState( TryOpenServer() );
	}

	private constexpr function OnQuestClose( evt : QuestClose ) : EntityNotificationType
	{
		return GetNotificationBasedOnServerUpdateState( TryCloseServer() );
	}

	private constexpr function OnQuestExplode( evt : QuestExplode ) : EntityNotificationType
	{
		return EntityNotificationType.SendThisEventToEntity;
	}

	private constexpr function OnQuestStartHacking( evt : QuestStartHacking ) : EntityNotificationType
	{
		return GetNotificationBasedOnServerUpdateState( TryUpdateCoverState( CoverState.Open ) && TryUpdateServerState( ServerState.Active ) );
	}

	private constexpr function OnQuestStopHacking( evt : QuestStopHacking ) : EntityNotificationType
	{
		return GetNotificationBasedOnServerUpdateState( TryCloseServer() );
	}

	protected override function OnOverloadDevice( evt : OverloadDevice ) : EntityNotificationType
	{
		return EntityNotificationType.SendThisEventToEntity;
	}

	private constexpr function OnServerOverload( evt : ServerOverload ) : EntityNotificationType
	{
		return GetNotificationBasedOnServerUpdateState( true );
	}

}

