class QuickHackableQueueHelper
{

	public static function PutActionInQuickhackQueue( action : ScriptableDeviceAction, gameplayRoleComponent : GameplayRoleComponent, gameInstance : GameInstance, qhIndicatorSlotName : CName, requesterObject : GameObject ) : Bool
	{
		var player : PlayerPuppet;
		var putActionInQueue : Bool;
		var isQueuePerkBought : Bool;
		var inQueueVisualData : GameplayRoleMappinData;
		var deviceActionQueue : DeviceActionQueue;
		var statSystem : StatsSystem;
		var playerBlackboard : IBlackboard;
		var decreaseQhUploadTimeVal : Float;
		var firstHackInQueueUploadTimeDecrease : Float;
		var playerEntityID : EntityID;
		var hackedEntityID : EntityID;
		var currentlyUploadingAction : ScriptableDeviceAction;
		var statPoolsSystem : StatPoolsSystem;
		currentlyUploadingAction = requesterObject.GetCurrentlyUploadingAction();
		player = ( ( PlayerPuppet )( action.GetExecutor() ) );
		if( !( player ) )
		{
			return false;
		}
		if( !( action.IsQuickHack() ) )
		{
			return false;
		}
		playerEntityID = player.GetEntityID();
		if( action.m_isQueuedAction )
		{
			if( currentlyUploadingAction )
			{
				deviceActionQueue = currentlyUploadingAction.m_deviceActionQueue;
			}
			currentlyUploadingAction = ( ( ScriptableDeviceAction )( action ) );
			currentlyUploadingAction.m_deviceActionQueue = deviceActionQueue;
			currentlyUploadingAction.m_isActionQueueingUsed = true;
			requesterObject.SetCurrentlyUploadingAction( currentlyUploadingAction );
			playerBlackboard = GameInstance.GetBlackboardSystem( gameInstance ).GetLocalInstanced( playerEntityID, GetAllBlackboardDefs().PlayerStateMachine );
			playerBlackboard.SetVariant( GetAllBlackboardDefs().PlayerStateMachine.CostFreeActionID, currentlyUploadingAction.GetObjectActionID() );
			return false;
		}
		statSystem = GameInstance.GetStatsSystem( gameInstance );
		decreaseQhUploadTimeVal = statSystem.GetStatValue( playerEntityID, gamedataStatType.QuickHackUploadTimeDecrease );
		if( decreaseQhUploadTimeVal > 0.0 )
		{
			action.m_activationTimeReduction = MinF( decreaseQhUploadTimeVal, 1.0 );
		}
		statPoolsSystem = GameInstance.GetStatPoolsSystem( gameInstance );
		if( ( ( !( statSystem.GetStatBoolValue( player.GetEntityID(), gamedataStatType.IgnoreAwarenessCostWhenOverclocked ) ) && !( StatusEffectSystem.ObjectHasStatusEffectWithTag( ( ( ScriptedPuppet )( requesterObject ) ), 'CommsNoiseJam' ) ) ) && ( ( player.IsBeingRevealed() && IsAwarenessBumpingAllowed( ( ( ScriptedPuppet )( requesterObject ) ) ) ) || StatusEffectSystem.ObjectHasStatusEffect( player, T"BaseStatusEffect.ForcedQHUploadAwarenessBumps" ) ) ) || ( player.IsBeingRevealed() && ( action.GetAwarenessCost( gameInstance ) < 0.0 ) ) )
		{
			BumpQuickHackUploadStatPoolValue( action, player, gameInstance );
		}
		isQueuePerkBought = IsQueuePerkBought( player );
		if( isQueuePerkBought && ( action.CanSkipPayCost( true ) || action.CanPayCost( NULL, true ) ) )
		{
			if( currentlyUploadingAction && !( currentlyUploadingAction.m_deviceActionQueue ) )
			{
				currentlyUploadingAction.m_deviceActionQueue = new DeviceActionQueue;
			}
			if( currentlyUploadingAction && currentlyUploadingAction.m_deviceActionQueue )
			{
				currentlyUploadingAction.m_deviceActionQueue.SetMaxQueueSize( ( ( Int32 )( statSystem.GetStatValue( playerEntityID, gamedataStatType.QuickHackQueueSize ) ) ) );
			}
			putActionInQueue = ( currentlyUploadingAction && !( currentlyUploadingAction.m_isInactive ) ) && currentlyUploadingAction.m_deviceActionQueue.CanNewActionBeQueued();
			if( putActionInQueue && ( action.CanSkipPayCost( true ) || action.PayCost( true ) ) )
			{
				decreaseQhUploadTimeVal = statSystem.GetStatValue( playerEntityID, gamedataStatType.QuickHackQueueUploadTimeDecrease );
				firstHackInQueueUploadTimeDecrease = statSystem.GetStatValue( playerEntityID, gamedataStatType.FirstHackInQueueUploadTimeDecrease );
				if( ( ( currentlyUploadingAction.m_deviceActionQueue.GetQueueSize() == 0 ) && ( firstHackInQueueUploadTimeDecrease > 0.0 ) ) && ( firstHackInQueueUploadTimeDecrease < 1.0 ) )
				{
					decreaseQhUploadTimeVal += firstHackInQueueUploadTimeDecrease;
					decreaseQhUploadTimeVal = MinF( decreaseQhUploadTimeVal, 1.0 );
				}
				currentlyUploadingAction.m_deviceActionQueue.PutActionInQueue( action, decreaseQhUploadTimeVal );
				if( PlayerDevelopmentSystem.GetData( player ).IsNewPerkBought( gamedataNewPerkType.Intelligence_Master_Perk_1 ) && ( currentlyUploadingAction.m_deviceActionQueue.GetQueueSize() >= currentlyUploadingAction.m_deviceActionQueue.GetMaxQueueSize() ) )
				{
					hackedEntityID = gameplayRoleComponent.GetOwner().GetEntityID();
					GameInstance.GetStatusEffectSystem( gameInstance ).ApplyStatusEffect( hackedEntityID, T"BaseStatusEffect.Intelligence_Master_Perk_2_Queue_Lock" );
					currentlyUploadingAction.m_deviceActionQueue.LockQueue();
				}
				if( gameplayRoleComponent )
				{
					inQueueVisualData = new GameplayRoleMappinData;
					inQueueVisualData.m_progressBarType = EProgressBarType.UPLOAD;
					if( action.GetInteractionIcon() )
					{
						inQueueVisualData.m_textureID = action.GetInteractionIcon().TexturePartID().GetID();
					}
					inQueueVisualData.m_visibleThroughWalls = true;
					gameplayRoleComponent.AddQuickhackMappinToQueue( inQueueVisualData );
				}
				statSystem.AddModifier( playerEntityID, ( ( gameConstantStatModifierData )( RPGManager.CreateStatModifier( gamedataStatType.QuickHackQueueCount, gameStatModifierType.Additive, 1.0 ) ) ) );
				QuickhackModule.RequestRefreshQuickhackMenu( gameInstance, currentlyUploadingAction.GetRequesterID() );
				return true;
			}
			else
			{
				statPoolsSystem.RequestRemovingStatPool( action.GetRequesterID(), gamedataStatPoolType.QuickHackUpload );
				QuickHackableQueueHelper.RemoveQuickhackQueue( gameplayRoleComponent, currentlyUploadingAction );
				action.m_isActionQueueingUsed = true;
				requesterObject.SetCurrentlyUploadingAction( action );
				QuickhackModule.RequestRefreshQuickhackMenu( gameInstance, currentlyUploadingAction.GetRequesterID() );
			}
		}
		else if( currentlyUploadingAction )
		{
			currentlyUploadingAction.m_isInactive = true;
			requesterObject.SetCurrentlyUploadingAction( currentlyUploadingAction );
		}
		return false;
	}

	private static function BumpQuickHackUploadStatPoolValue( action : ScriptableDeviceAction, player : GameObject, gameInstance : GameInstance )
	{
		var statPoolsSystem : StatPoolsSystem;
		var awarenessCost : Float;
		var quickHackUploadVal : Float;
		var maxQuickHackUploadVal : Float;
		var maxAwarenessValReached : Bool;
		statPoolsSystem = GameInstance.GetStatPoolsSystem( gameInstance );
		maxQuickHackUploadVal = 99.90000153;
		if( !( statPoolsSystem.HasActiveStatPool( player.GetEntityID(), gamedataStatPoolType.QuickHackUpload ) ) )
		{
			return;
		}
		awarenessCost = action.GetAwarenessCost( gameInstance );
		quickHackUploadVal = statPoolsSystem.GetStatPoolValue( player.GetEntityID(), gamedataStatPoolType.QuickHackUpload, true );
		maxAwarenessValReached = ( quickHackUploadVal + awarenessCost ) > maxQuickHackUploadVal;
		if( maxAwarenessValReached )
		{
			awarenessCost = MaxF( maxQuickHackUploadVal - quickHackUploadVal, 0.0 );
		}
		if( awarenessCost != 0.0 )
		{
			statPoolsSystem.RequestChangingStatPoolValue( player.GetEntityID(), gamedataStatPoolType.QuickHackUpload, awarenessCost, player, true, true );
		}
		if( maxAwarenessValReached )
		{
			statPoolsSystem.RequestSettingStatPoolMaxValue( player.GetEntityID(), gamedataStatPoolType.QuickHackUpload, player );
		}
	}

	public static function IsAwarenessBumpingAllowed( target : ScriptedPuppet ) : Bool
	{
		var i : Int32;
		var completionEffects : array< weak< ObjectActionEffect_Record > >;
		var statusEffect : weak< StatusEffect_Record >;
		var completedQhHistory : array< ScriptableDeviceAction >;
		var currentlyUploadingAction : ScriptableDeviceAction;
		var objectActionRecords : array< ObjectAction_Record >;
		if( target && target.IsActionQueueEnabled() )
		{
			completedQhHistory = target.GetCompletedQuickhackActionHistory();
			currentlyUploadingAction = target.GetCurrentlyUploadingAction();
			if( currentlyUploadingAction && !( currentlyUploadingAction.m_isInactive ) )
			{
				completedQhHistory.PushBack( currentlyUploadingAction );
				if( currentlyUploadingAction.m_deviceActionQueue )
				{
					currentlyUploadingAction.m_deviceActionQueue.GetAllQueuedActionObjectRecords( objectActionRecords );
					for( i = 0; i < objectActionRecords.Size(); i += 1 )
					{
						objectActionRecords[ i ].CompletionEffects( completionEffects );
					}
				}
			}
			for( i = 0; i < completedQhHistory.Size(); i += 1 )
			{
				completedQhHistory[ i ].GetObjectActionRecord().CompletionEffects( completionEffects );
			}
			for( i = 0; i < completionEffects.Size(); i += 1 )
			{
				statusEffect = completionEffects[ i ].StatusEffect();
				if( statusEffect && statusEffect.GameplayTagsContains( 'DisallowsAwarenessBumpInQueue' ) )
				{
					return false;
				}
			}
		}
		return true;
	}

	public static function CheckAndSetInactivityReasonForVehicleActions( actions : array< DeviceAction >, scriptableDeviceAction : ScriptableDeviceAction ) : Bool
	{
		var i, j : Int32;
		var action : ScriptableDeviceAction;
		var actionNames : array< CName >;
		var isFailureSet : Bool;
		var blockSameQhTypeQueuingOnVehicles : Bool;
		var inactivityReasonIsQuickHacked : String;
		if( !( scriptableDeviceAction ) )
		{
			return false;
		}
		inactivityReasonIsQuickHacked = QuickhacksListGameController.EActionInactivityResonToLocalizationString( EActionInactivityReson.IsQuickHacked );
		blockSameQhTypeQueuingOnVehicles = TDB.GetBool( T"NewPerks.Intelligence_Left_Milestone_2.blockSameQhTypeQueuingOnVehicles" );
		if( blockSameQhTypeQueuingOnVehicles )
		{
			for( i = 0; i < actions.Size(); i += 1 )
			{
				action = ( ( ScriptableDeviceAction )( actions[ i ] ) );
				if( action && action.actionName == scriptableDeviceAction.actionName )
				{
					action.SetInactiveWithReason( false, inactivityReasonIsQuickHacked );
					isFailureSet = true;
				}
				else if( action && scriptableDeviceAction.m_deviceActionQueue )
				{
					actionNames.Clear();
					scriptableDeviceAction.m_deviceActionQueue.GetAllQueuedActionNames( actionNames );
					for( j = 0; j < actionNames.Size(); j += 1 )
					{
						if( action.actionName == actionNames[ j ] )
						{
							action.SetInactiveWithReason( false, inactivityReasonIsQuickHacked );
							isFailureSet = true;
						}
					}
				}
			}
		}
		else
		{
			for( i = 0; i < actions.Size(); i += 1 )
			{
				action = ( ( ScriptableDeviceAction )( actions[ i ] ) );
				if( action && SetInactivityReasonForAction( action, action.actionName, scriptableDeviceAction, inactivityReasonIsQuickHacked ) )
				{
					isFailureSet = true;
				}
			}
		}
		return isFailureSet;
	}

	public static function SetInactivityReasonForAction( scriptableDeviceAction : ScriptableDeviceAction, actionName : CName, currentlyUploadingAction : ScriptableDeviceAction, failureExplanation : String ) : Bool
	{
		var actionNamesInQueue : array< CName >;
		var disallowedActionNames : array< CName >;
		var actionShouldBeAllowed : Bool;
		var i, j : Int32;
		actionShouldBeAllowed = true;
		if( currentlyUploadingAction )
		{
			currentlyUploadingAction.m_deviceActionQueue.GetAllQueuedActionNames( actionNamesInQueue );
			DeviceActionQueue.GetAllDisallowedActionNames( disallowedActionNames );
			for( i = 0; i < disallowedActionNames.Size(); i += 1 )
			{
				if( ( !( currentlyUploadingAction.m_isInactive ) && actionName == currentlyUploadingAction.GetActionName() ) && currentlyUploadingAction.GetActionName() == disallowedActionNames[ i ] )
				{
					actionShouldBeAllowed = false;
					break;
				}
				for( j = 0; j < actionNamesInQueue.Size(); j += 1 )
				{
					if( actionName == actionNamesInQueue[ j ] && actionNamesInQueue[ j ] == disallowedActionNames[ i ] )
					{
						actionShouldBeAllowed = false;
						break;
					}
				}
			}
		}
		if( ( failureExplanation != "LocKey#43809" && failureExplanation != "LocKey#43808" ) || !( actionShouldBeAllowed ) )
		{
			scriptableDeviceAction.SetInactiveWithReason( false, failureExplanation );
			return true;
		}
		return false;
	}

	public static function IsStatusEffectStackable( statusEffectRecord : StatusEffect_Record ) : Bool
	{
		var packages : array< weak< GameplayLogicPackage_Record > >;
		var package : weak< GameplayLogicPackage_Record >;
		var i : Int32;
		var hasStackableComponent : Bool;
		statusEffectRecord.Packages( packages );
		for( i = 0; i < packages.Size(); i += 1 )
		{
			package = packages[ i ];
			hasStackableComponent = hasStackableComponent || package.Stackable();
		}
		return hasStackableComponent;
	}

	public static function DecreaseQuickHackQueueCount( player : PlayerPuppet )
	{
		var gameInstance : GameInstance;
		var playerEntityID : EntityID;
		var statSystem : StatsSystem;
		var gameStatModifierData : gameConstantStatModifierData;
		if( !( player ) )
		{
			return;
		}
		gameInstance = player.GetGame();
		playerEntityID = player.GetEntityID();
		statSystem = GameInstance.GetStatsSystem( gameInstance );
		if( statSystem.GetStatValue( playerEntityID, gamedataStatType.QuickHackQueueCount ) <= 1.0 )
		{
			statSystem.RemoveAllModifiers( playerEntityID, gamedataStatType.QuickHackQueueCount );
		}
		else
		{
			gameStatModifierData = ( ( gameConstantStatModifierData )( RPGManager.CreateStatModifier( gamedataStatType.QuickHackQueueCount, gameStatModifierType.Additive, -1.0 ) ) );
			statSystem.AddModifier( playerEntityID, gameStatModifierData );
		}
	}

	public static function RemoveQuickhackQueue( gameplayRoleComponent : GameplayRoleComponent, currentlyUploadingAction : ScriptableDeviceAction )
	{
		var i : Int32;
		var objectActionRecords : array< ObjectAction_Record >;
		if( gameplayRoleComponent )
		{
			gameplayRoleComponent.ToggleMappin( gamedataMappinVariant.QuickHackVariant, false, false );
		}
		if( currentlyUploadingAction )
		{
			currentlyUploadingAction.m_isTargetDead = true;
			if( currentlyUploadingAction.GetExecutor().IsPlayer() && ( currentlyUploadingAction.m_deviceActionQueue != NULL ) )
			{
				currentlyUploadingAction.m_deviceActionQueue.GetAllQueuedActionObjectRecords( objectActionRecords );
				for( i = 0; i < objectActionRecords.Size(); i += 1 )
				{
					RPGManager.DecrementQuickHackBlackboard( currentlyUploadingAction.GetExecutor().GetGame(), objectActionRecords[ i ].GetID() );
					DecreaseQuickHackQueueCount( ( ( PlayerPuppet )( currentlyUploadingAction.GetExecutor() ) ) );
				}
			}
		}
	}

	public static function PopFromQuickHackQueue( evt : UploadProgramProgressEvent, gameplayRoleComponent : GameplayRoleComponent ) : QuickSlotCommandUsed
	{
		var action : ScriptableDeviceAction;
		var quickSlotCommandUsed : QuickSlotCommandUsed;
		var player : PlayerPuppet;
		var gameInstance : GameInstance;
		var hackedEntityID : EntityID;
		var setQuickHackAttempt : SetQuickHackAttemptEvent;
		setQuickHackAttempt = new SetQuickHackAttemptEvent;
		gameInstance = gameplayRoleComponent.GetOwner().GetGame();
		if( !( evt.deviceActionQueue ) )
		{
			setQuickHackAttempt.wasQuickHackAttempt = false;
			GameInstance.GetPersistencySystem( gameInstance ).QueuePSEvent( evt.action.GetPersistentID(), evt.action.GetDeviceClassName(), setQuickHackAttempt );
			return NULL;
		}
		action = ( ( ScriptableDeviceAction )( evt.deviceActionQueue.PopActionInQueue() ) );
		if( action )
		{
			action.m_isQueuedAction = true;
			quickSlotCommandUsed = new QuickSlotCommandUsed;
			quickSlotCommandUsed.action = action;
			player = ( ( PlayerPuppet )( GameInstance.GetPlayerSystem( gameInstance ).GetLocalPlayerMainGameObject() ) );
			DecreaseQuickHackQueueCount( player );
		}
		else
		{
			hackedEntityID = gameplayRoleComponent.GetOwner().GetEntityID();
			GameInstance.GetStatusEffectSystem( gameInstance ).RemoveStatusEffect( hackedEntityID, T"BaseStatusEffect.Intelligence_Master_Perk_2_Queue_Lock" );
			evt.deviceActionQueue.UnlockQueue();
			setQuickHackAttempt.wasQuickHackAttempt = false;
			GameInstance.GetPersistencySystem( gameInstance ).QueuePSEvent( evt.action.GetPersistentID(), evt.action.GetDeviceClassName(), setQuickHackAttempt );
		}
		return quickSlotCommandUsed;
	}

	public static function IsQueuePerkBought( playerPuppet : PlayerPuppet ) : Bool
	{
		return playerPuppet && ( PlayerDevelopmentSystem.GetData( playerPuppet ).IsNewPerkBought( gamedataNewPerkType.Intelligence_Left_Milestone_2 ) == 2 );
	}

	public static function IsActionQueueEnabled( currentlyUploadingAction : ScriptableDeviceAction, playerPuppet : PlayerPuppet ) : Bool
	{
		return ( currentlyUploadingAction && currentlyUploadingAction.m_isActionQueueingUsed ) || IsQueuePerkBought( playerPuppet );
	}

	public static function IsActionQueueFull( currentlyUploadingAction : ScriptableDeviceAction ) : Bool
	{
		return ( currentlyUploadingAction && currentlyUploadingAction.m_deviceActionQueue ) && currentlyUploadingAction.m_deviceActionQueue.IsActionQueueFull();
	}

	public static function CanNewActionBeQueued( currentlyUploadingAction : ScriptableDeviceAction ) : Bool
	{
		return ( currentlyUploadingAction && currentlyUploadingAction.m_deviceActionQueue ) && currentlyUploadingAction.m_deviceActionQueue.CanNewActionBeQueued();
	}

	public static function GetFinisherHealthThresholdIncreaseForQueue( player : GameObject, target : GameObject ) : Float
	{
		var statsSystem : StatsSystem;
		var scriptedPuppet : ScriptedPuppet;
		var finisherHealthThresholdIncreaseForQueue : Float;
		var qhQueueSize : Int32;
		scriptedPuppet = ( ( ScriptedPuppet )( target ) );
		if( !( scriptedPuppet ) )
		{
			return 0.0;
		}
		statsSystem = GameInstance.GetStatsSystem( player.GetGame() );
		finisherHealthThresholdIncreaseForQueue = statsSystem.GetStatValue( player.GetEntityID(), gamedataStatType.FinisherHealthThresholdIncreaseForQueue );
		if( finisherHealthThresholdIncreaseForQueue > 0.0 )
		{
			qhQueueSize = scriptedPuppet.GetDeviceActionQueueSize();
			return ( ( Float )( qhQueueSize ) ) * finisherHealthThresholdIncreaseForQueue;
		}
		return 0.0;
	}

}

class DeviceActionQueue
{
	private var m_actionsInQueue : array< DeviceAction >;
	private var m_maxQueueSize : Int32;
	default m_maxQueueSize = 1;
	private var m_locked : Bool;
	default m_locked = false;

	public static function GetAllDisallowedActionNames( out actionNames : array< CName > )
	{
		actionNames = TDB.GetCNameArray( T"NewPerks.Intelligence_Left_Milestone_2.preventInQueueAgain" );
	}

	public function LockQueue()
	{
		m_locked = true;
	}

	public function UnlockQueue()
	{
		m_locked = false;
	}

	public function GetMaxQueueSize() : Int32
	{
		return m_maxQueueSize;
	}

	public function SetMaxQueueSize( maxQueueSize : Int32 )
	{
		if( maxQueueSize > 0 )
		{
			m_maxQueueSize = maxQueueSize;
		}
	}

	public function GetQueueSize() : Int32
	{
		return m_actionsInQueue.Size();
	}

	public function GetQueuedActionsTotalCost() : Int32
	{
		var scriptableDeviceAction : ScriptableDeviceAction;
		var totalCost : Int32;
		var i : Int32;
		for( i = 0; i < m_actionsInQueue.Size(); i += 1 )
		{
			scriptableDeviceAction = ( ( ScriptableDeviceAction )( m_actionsInQueue[ i ] ) );
			if( scriptableDeviceAction )
			{
				totalCost += scriptableDeviceAction.GetCost();
			}
		}
		return totalCost;
	}

	public function GetAllQueuedActionNames( out actionNames : array< CName > ) : Bool
	{
		var i : Int32;
		for( i = 0; i < m_actionsInQueue.Size(); i += 1 )
		{
			actionNames.PushBack( m_actionsInQueue[ i ].actionName );
		}
		return HasActionInQueue();
	}

	public function GetAllQueuedActionObjectRecords( out objectActionRecords : array< ObjectAction_Record > ) : Bool
	{
		var i : Int32;
		var action : ScriptableDeviceAction;
		for( i = 0; i < m_actionsInQueue.Size(); i += 1 )
		{
			action = ( ( ScriptableDeviceAction )( m_actionsInQueue[ i ] ) );
			if( action )
			{
				objectActionRecords.PushBack( action.GetObjectActionRecord() );
			}
		}
		return HasActionInQueue();
	}

	public function IsQhQueueUploadInProgress() : Bool
	{
		var uploadVal : Float;
		var statPoolsSystem : StatPoolsSystem;
		var action : ScriptableDeviceAction;
		if( m_actionsInQueue.Size() > 0 )
		{
			if( ( m_actionsInQueue[ 0 ] == NULL ) && !( m_actionsInQueue[ 0 ].IsA( 'ScriptableDeviceAction' ) ) )
			{
				return false;
			}
			action = ( ( ScriptableDeviceAction )( m_actionsInQueue[ 0 ] ) );
			if( action )
			{
				statPoolsSystem = GameInstance.GetStatPoolsSystem( action.GetExecutor().GetGame() );
				uploadVal = statPoolsSystem.GetStatPoolValue( action.GetRequesterID(), gamedataStatPoolType.QuickHackUpload );
				return ( uploadVal > 0.0 ) && ( uploadVal < 100.0 );
			}
		}
		return true;
	}

	public function CanNewActionBeQueued() : Bool
	{
		if( !( IsQhQueueUploadInProgress() ) )
		{
			return false;
		}
		return !( m_locked ) && ( m_actionsInQueue.Size() < m_maxQueueSize );
	}

	public function HasActionInQueue() : Bool
	{
		return m_actionsInQueue.Size() > 0;
	}

	public function IsActionQueueFull() : Bool
	{
		if( !( IsQhQueueUploadInProgress() ) )
		{
			return false;
		}
		return !( CanNewActionBeQueued() ) || ( m_actionsInQueue.Size() == m_maxQueueSize );
	}

	private function DecreaseUploadTime( deviceAction : ScriptableDeviceAction, decreaseQhUploadTimeVal : Float )
	{
		if( decreaseQhUploadTimeVal < 0.0 )
		{
			return;
		}
		decreaseQhUploadTimeVal += ( decreaseQhUploadTimeVal * ( ( Float )( m_actionsInQueue.Size() ) ) );
		decreaseQhUploadTimeVal = MinF( decreaseQhUploadTimeVal, 0.99000001 );
		deviceAction.m_activationTimeReduction = decreaseQhUploadTimeVal;
	}

	public function PutActionInQueue( deviceAction : ScriptableDeviceAction, decreaseQhUploadTimeVal : Float ) : Bool
	{
		if( IsActionQueueFull() )
		{
			return false;
		}
		DecreaseUploadTime( deviceAction, decreaseQhUploadTimeVal );
		m_actionsInQueue.PushBack( deviceAction );
		return true;
	}

	public function PopActionInQueue() : DeviceAction
	{
		var deviceAction : DeviceAction;
		if( !( HasActionInQueue() ) )
		{
			return NULL;
		}
		deviceAction = m_actionsInQueue[ 0 ];
		m_actionsInQueue.Erase( 0 );
		return deviceAction;
	}

}

