#ifndef _CDEV_REACTOR_H_
#define _CDEV_REACTOR_H_ 1

#include "cdevTime.h"
#include "cdevHandleSet.h"
#include "cdevEventHandler.h"

class CDEV_REACTOR_API cdevReactor 
{
public:
typedef enum	{
	INPUT           =  0,
	OUTPUT          =  1,
	EXCEPTION       =  2,
	SIGNAL          =  3
	} REACTOR_EVENT;
	
typedef enum	{
	REACTOR_ERROR   = -1,
	SUCCESS         =  0,
	INVALID_HANDLE  =  1,
	INVALID_HANDLER =  2,
	HANDLE_EXISTS   =  3,
	UNKNOWN_HANDLER =  4,
	INVALID_TIMEOUT =  5
	} REACTOR_RESULT;

typedef enum {
	UNTIL_TIMEOUT = 0,
	UNTIL_EVENT   = 1
	} HANDLE_EVENT_FLAG;
		
protected:
	static int          netInitCount;

	int                 maxEntries;
	int                 size;
	cdevHandleSet       read_set;
	cdevHandleSet       write_set;
	cdevHandleSet       except_set;
	cdevEventHandler ** handlers;
	cdevEventHandler  * timers;

private:
	void calculateMask    ( void );
	int  calculateTimeout ( cdevTime defaultPeriod, struct timeval &timeout );
	int  handleFileEvent  ( cdevHandleSet * fds, REACTOR_EVENT event);	
public:
	cdevReactor          ( void );	
	virtual ~cdevReactor ( void );
	
	virtual int checkHandlers    ( void );
	virtual int registerHandler  ( cdevEventHandler * handler, unsigned mask );
	virtual int removeHandler    ( cdevEventHandler * handler );
	virtual int removeHandler    ( int fd );
	virtual int extractHandler   ( cdevEventHandler * handler );
	virtual int getHandler       ( int fd, cdevEventHandler * &handler );

	virtual int registerTimer    ( cdevEventHandler * timer   );
	virtual int cancelTimer      ( cdevEventHandler * timer   );
	
	virtual int handleEvents     ( cdevTime period = -1.0, int flags = UNTIL_TIMEOUT );
};

#endif
