class TemporalPrereqDelayCallback extends DelayCallback
{
	protected var m_state : weak< TemporalPrereqState >;

	public export override function Call()
	{
		m_state.CallbackRecall();
	}

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

}

class TemporalPrereqState extends PrereqState
{
	var m_delaySystem : DelaySystem;
	var m_callback : TemporalPrereqDelayCallback;
	var m_lapsedTime : Float;
	var m_delayID : DelayID;

	public virtual function RegisterDealyCallback( delayTime : Float )
	{
		m_delayID = m_delaySystem.DelayCallback( m_callback, delayTime );
	}

	public virtual function CallbackRecall()
	{
		var newState : Bool;
		const var prereq : TemporalPrereq;
		prereq = ( ( TemporalPrereq )( GetPrereq() ) );
		newState = m_lapsedTime >= prereq.m_totalDuration;
		OnChanged( newState );
		m_lapsedTime += prereq.m_totalDuration;
		if( !( IsFulfilled() ) )
		{
			RegisterDealyCallback( prereq.m_totalDuration );
		}
	}

}

class TemporalPrereq extends IScriptablePrereq
{
	var m_totalDuration : Float;

	protected export const override function OnRegister( state : PrereqState, game : GameInstance, context : IScriptable ) : Bool
	{
		var castedState : TemporalPrereqState;
		castedState = ( ( TemporalPrereqState )( state ) );
		castedState.m_delaySystem = GameInstance.GetDelaySystem( game );
		castedState.m_callback = new TemporalPrereqDelayCallback;
		castedState.m_callback.RegisterState( castedState );
		castedState.m_lapsedTime = 0.0;
		castedState.RegisterDealyCallback( 0.0 );
		return false;
	}

	protected export const override function OnUnregister( state : PrereqState, game : GameInstance, context : IScriptable )
	{
		var castedState : TemporalPrereqState;
		castedState = ( ( TemporalPrereqState )( state ) );
		GameInstance.GetDelaySystem( game ).CancelCallback( castedState.m_delayID );
		castedState.m_callback = NULL;
	}

	protected export override function Initialize( recordID : TweakDBID )
	{
		var randRange : Float;
		m_totalDuration = TweakDBInterface.GetFloat( recordID + T".duration", 0.0 );
		randRange = TweakDBInterface.GetFloat( recordID + T".randRange", 0.0 );
		if( randRange > 0.0 )
		{
			m_totalDuration = RandRangeF( m_totalDuration - randRange, m_totalDuration + randRange );
		}
	}

}

class PlayerVehicleStatePrereq extends IScriptablePrereq
{

	public export const override function IsFulfilled( game : GameInstance, context : IScriptable ) : Bool
	{
		var bboard : IBlackboard;
		var playerVehState : Bool;
		var playerPuppet : PlayerPuppet;
		playerPuppet = ( ( PlayerPuppet )( GameInstance.GetPlayerSystem( game ).GetLocalPlayerMainGameObject() ) );
		if( playerPuppet )
		{
			bboard = GameInstance.GetBlackboardSystem( game ).GetLocalInstanced( playerPuppet.GetEntityID(), GetAllBlackboardDefs().PlayerStateMachine );
			playerVehState = bboard.GetInt( GetAllBlackboardDefs().PlayerStateMachine.Vehicle ) == 0;
		}
		else
		{
			playerVehState = true;
		}
		return playerVehState;
	}

}

