class StatPoolChangeOverTimePrereqListener extends BaseStatPoolPrereqListener
{
	protected var m_state : weak< StatPoolChangeOverTimePrereqState >;

	public export override function OnStatPoolValueChanged( oldValue : Float, newValue : Float, percToPoints : Float )
	{
		m_state.StatPoolUpdate( oldValue, newValue, percToPoints );
	}

	public override function RegisterState( state : PrereqState )
	{
		m_state = ( ( StatPoolChangeOverTimePrereqState )( state ) );
	}

}

struct ChangeInfoWithTimeStamp
{
	var TimeStamp : Float;
	var Change : Float;
}

class StatPoolChangeOverTimePrereqState extends PrereqState
{
	var m_statPoolListener : BaseStatPoolPrereqListener;
	var m_ownerID : StatsObjectID;
	var m_valueToCheck : Float;
	var m_timeFrame : Float;
	var m_comparePercentage : Bool;
	var m_checkGain : Bool;
	var m_history : array< ChangeInfoWithTimeStamp >;
	var m_GameInstance : GameInstance;

	public virtual function StatPoolUpdate( oldValue : Float, newValue : Float, percToPoints : Float )
	{
		var checkPassed : Bool;
		var changeDelta : Float;
		var tempInfo : ChangeInfoWithTimeStamp;
		if( m_checkGain )
		{
			changeDelta = newValue - oldValue;
		}
		else
		{
			changeDelta = oldValue - newValue;
		}
		if( !( m_comparePercentage ) )
		{
			changeDelta = changeDelta * percToPoints;
		}
		if( changeDelta > 0.0 )
		{
			tempInfo = ChangeInfoWithTimeStamp( EngineTime.ToFloat( GameInstance.GetTimeSystem( m_GameInstance ).GetSimTime() ), changeDelta );
			m_history.PushBack( tempInfo );
			checkPassed = CheckHistory();
		}
		OnChanged( checkPassed );
	}

	public virtual function RegisterStatPoolListener( game : GameInstance, statPoolType : gamedataStatPoolType, owner : EntityID )
	{
		if( EntityID.IsDefined( owner ) )
		{
			m_ownerID = owner;
			m_GameInstance = game;
			m_statPoolListener = new StatPoolChangeOverTimePrereqListener;
			m_statPoolListener.RegisterState( this );
			GameInstance.GetStatPoolsSystem( m_GameInstance ).RequestRegisteringListener( m_ownerID, statPoolType, m_statPoolListener );
		}
	}

	public virtual function UnregisterStatPoolListener( game : GameInstance, statPoolType : gamedataStatPoolType )
	{
		if( m_statPoolListener )
		{
			GameInstance.GetStatPoolsSystem( game ).RequestUnregisteringListener( m_ownerID, statPoolType, m_statPoolListener );
		}
		m_statPoolListener = NULL;
	}

	private function CheckHistory() : Bool
	{
		var retVal : Bool;
		var i : Int32;
		var currentTimeStamp : Float;
		var currentInfo : ChangeInfoWithTimeStamp;
		var totalChange : Float;
		var toDelete : array< ChangeInfoWithTimeStamp >;
		currentTimeStamp = EngineTime.ToFloat( GameInstance.GetTimeSystem( m_GameInstance ).GetSimTime() );
		for( i = m_history.Size() - 1; i >= 0; i -= 1 )
		{
			currentInfo = m_history[ i ];
			if( ( currentTimeStamp - currentInfo.TimeStamp ) < m_timeFrame )
			{
				totalChange += currentInfo.Change;
				if( totalChange >= m_valueToCheck )
				{
					retVal = true;
					m_history.Clear();
					return retVal;
				}
			}
			else
			{
				toDelete.PushBack( currentInfo );
			}
		}
		for( i = 0; i < toDelete.Size(); i += 1 )
		{
			m_history.Remove( toDelete[ i ] );
		}
		return retVal;
	}

}

class StatPoolChangeOverTimePrereq extends IScriptablePrereq
{
	var m_statPoolType : gamedataStatPoolType;
	var m_timeFrame : Float;
	var m_valueToCheck : Float;
	var m_comparePercentage : Bool;
	var m_checkGain : Bool;

	protected const override function OnRegister( state : PrereqState, game : GameInstance, context : IScriptable ) : Bool
	{
		var owner : GameObject;
		var castedState : StatPoolChangeOverTimePrereqState;
		castedState = ( ( StatPoolChangeOverTimePrereqState )( state ) );
		castedState.m_comparePercentage = m_comparePercentage;
		castedState.m_checkGain = m_checkGain;
		castedState.m_timeFrame = m_timeFrame;
		castedState.m_valueToCheck = m_valueToCheck;
		owner = ( ( GameObject )( context ) );
		castedState.RegisterStatPoolListener( game, m_statPoolType, owner.GetEntityID() );
		return false;
	}

	protected export const override function OnUnregister( state : PrereqState, game : GameInstance, context : IScriptable )
	{
		var castedState : StatPoolChangeOverTimePrereqState;
		castedState = ( ( StatPoolChangeOverTimePrereqState )( state ) );
		castedState.UnregisterStatPoolListener( game, m_statPoolType );
	}

	protected override function Initialize( record : TweakDBID )
	{
		m_statPoolType = ( ( gamedataStatPoolType )( ( ( Int32 )( EnumValueFromName( 'gamedataStatPoolType', TweakDBInterface.GetCName( record + T".statPoolType", 'Health' ) ) ) ) ) );
		m_comparePercentage = TweakDBInterface.GetBool( record + T".comparePercentage", true );
		m_valueToCheck = TweakDBInterface.GetFloat( record + T".valueToCheck", 50.0 );
		m_timeFrame = TweakDBInterface.GetFloat( record + T".timeFrame", 3.0 );
		m_checkGain = TweakDBInterface.GetBool( record + T".checkGain", false );
	}

}

