class DetectionMeterEffector extends Effector
{
	private var m_statusEffectID : TweakDBID;
	private var m_detectionStep : Float;
	private var m_maxStacks : Int32;
	private var m_onlyHostileDetection : Bool;
	private var m_dontRemoveStacks : Bool;
	private var m_detectionListener : CallbackHandle;
	private var m_currentStacks : Int32;
	private var m_gameInstance : GameInstance;
	private var m_ownerID : EntityID;

	protected override function Initialize( record : TweakDBID, game : GameInstance, parentRecord : TweakDBID )
	{
		m_gameInstance = game;
		m_statusEffectID = TDB.GetForeignKey( record + T".statusEffect" );
		m_detectionStep = TDB.GetFloat( record + T".detectionStep" );
		m_maxStacks = TDB.GetInt( record + T".maxStacks" );
		m_onlyHostileDetection = TDB.GetBool( record + T".onlyHostileDetection" );
		m_dontRemoveStacks = TDB.GetBool( record + T".dontRemoveStacks" );
	}

	protected export override function ActionOn( owner : GameObject )
	{
		var blackboard : IBlackboard;
		m_ownerID = owner.GetEntityID();
		blackboard = GameInstance.GetBlackboardSystem( owner.GetGame() ).Get( GetAllBlackboardDefs().UI_Stealth );
		if( blackboard )
		{
			if( m_onlyHostileDetection )
			{
				m_detectionListener = blackboard.RegisterListenerFloat( GetAllBlackboardDefs().UI_Stealth.highestHostileDetectionOnPlayer, this, 'OnDetectionChanged' );
				UpdateWithDetection( blackboard.GetFloat( GetAllBlackboardDefs().UI_Stealth.highestHostileDetectionOnPlayer ) );
			}
			else
			{
				m_detectionListener = blackboard.RegisterListenerFloat( GetAllBlackboardDefs().UI_Stealth.highestDetectionOnPlayer, this, 'OnDetectionChanged' );
				UpdateWithDetection( blackboard.GetFloat( GetAllBlackboardDefs().UI_Stealth.highestDetectionOnPlayer ) );
			}
		}
	}

	protected event OnDetectionChanged( newDetection : Float )
	{
		UpdateWithDetection( newDetection );
	}

	protected export override function ActionOff( owner : GameObject )
	{
		var blackboard : IBlackboard;
		if( m_detectionListener )
		{
			blackboard = GameInstance.GetBlackboardSystem( owner.GetGame() ).Get( GetAllBlackboardDefs().UI_Stealth );
			if( blackboard )
			{
				if( m_onlyHostileDetection )
				{
					blackboard.UnregisterListenerFloat( GetAllBlackboardDefs().UI_Stealth.highestHostileDetectionOnPlayer, m_detectionListener );
				}
				else
				{
					blackboard.UnregisterListenerFloat( GetAllBlackboardDefs().UI_Stealth.highestDetectionOnPlayer, m_detectionListener );
				}
			}
		}
		ProcessStacksChange( -( m_currentStacks ) );
		m_currentStacks = 0;
	}

	private function UpdateWithDetection( newDetection : Float )
	{
		var newStacks, stacksChange : Int32;
		if( ( m_detectionStep <= 0.0 ) || !( TDBID.IsValid( m_statusEffectID ) ) )
		{
			return;
		}
		newStacks = FloorF( newDetection / m_detectionStep );
		if( m_maxStacks > 0 )
		{
			newStacks = Min( newStacks, m_maxStacks );
		}
		stacksChange = newStacks - m_currentStacks;
		if( stacksChange == 0 )
		{
			return;
		}
		m_currentStacks = newStacks;
		ProcessStacksChange( stacksChange );
	}

	private function ProcessStacksChange( stacksChange : Int32 )
	{
		if( stacksChange > 0 )
		{
			GameInstance.GetStatusEffectSystem( m_gameInstance ).ApplyStatusEffect( m_ownerID, m_statusEffectID, TDBID.None(), m_ownerID, ( ( Uint32 )( stacksChange ) ) );
		}
		else if( !( m_dontRemoveStacks ) )
		{
			GameInstance.GetStatusEffectSystem( m_gameInstance ).RemoveStatusEffect( m_ownerID, m_statusEffectID, ( ( Uint32 )( Abs( stacksChange ) ) ) );
		}
	}

}

