/*
* timers.hh       : Timer Management Include File
* authors         : John Heidemann and Fabio Silva
*
* Copyright (C) 2000-2001 by the Unversity of Southern California
* $Id: timers.hh,v 1.3 2002/02/18 15:24:36 johnh Exp $
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
*
*/

#ifndef _TIMERS_H_
#define _TIMERS_H_

#include <string.h>

#include "tools.hh"

#define WAIT_FOREVER       -1
#define POLLING_INTERVAL   10 // seconds

typedef long handle;

/* timeval routines */
int Timeval_Cmp(struct timeval *x, struct timeval *y);
struct timeval *Timeval_Sub(struct timeval *x, struct timeval *y);
void Timeval_Addusecs(struct timeval *tv, int usecs);

#ifndef RAND_MAX
#define RAND_MAX 2147483647
#endif // RAND_MAX


/*
 * To make a new timer,
 * subclass TimerCallback and override
 * the expire() method.
 *
 * If you need to pass parameters to your timer,
 * pass them in the constructor of your subclass.
 *
 * If you allocate data in your callback,
 * free it in the destructor.
 *
 *
 * When the timer fires, expire() will be called.
 * You can do anything you want there.
 * When you're done, return a value that indicates what happens
 * to the timer:
 *
 * return = 0   re-add timer again to queue with same timeout as last time
 *        > 0   re-add timer to queue with new timeout given by return value
 *        < 0   discard timer (do not re-add it to the queue)
 */
class TimerCallback {
public:
	TimerCallback() {};
	virtual ~TimerCallback() {};
       	virtual int expire() = 0;
};


class EventQueue;  // used internally

class Timers {
public:
	Timers();
	~Timers() {};

	// Timer API functions:
	
	// add a timer to the queue, returning the handle
	//     that can be used to cancel it with RemoveTimer
  	handle AddTimer(int timeout, TimerCallback *cb);
	// remove a timer that's scheduled, returns if it was there.
	bool RemoveTimer(handle hdl);
	
	// returns the timer value at head of the queue
	void NextTimerTime(struct timeval *tv);
  
	// Executes the timer on the head of the queue
	void ExecuteNextTimer();

protected:
	int next_handle_;  // counter of handle ids
	EventQueue *eq_;  // internal list of timers
};

#endif // _TIMERS_H_


