#include "cdevSystem.h"
#include "cdevSessionManager.h"

class GENERIC_SERVER_API cdevSystemEventHandler : public cdevEventHandler 
{
private:
	int cdevfd;
	
public:
	cdevSystemEventHandler ( cdevReactor & Reactor, int fd )
		: cdevfd(fd)
		{
		Reactor.registerHandler(this, READ_MASK|WRITE_MASK|EXCEPT_MASK);
		}
		
	~cdevSystemEventHandler ( void )
		{
		if(reactor) reactor->extractHandler(this);
		handleClose();
		}
		
	int handleInput ( void )
		{
		cdevSystem::defaultSystem().poll();
		return 0;
		}

	int handleOutput ( void )
		{
		cdevSystem::defaultSystem().flush();
		return 0;
		}
		
	int handleExcept ( void )
		{
		cdevSystem::defaultSystem().poll();
		return 0;
		}
	
	int getHandle   ( void ) const
		{
		return cdevfd;
		}
};



class GENERIC_SERVER_API cdevSystemEventManager : public cdevEventHandler
{
public:
	cdevSystemEventManager ( cdevReactor &Reactor=cdevSessionManager::Reactor, double Rate = 30.0 )
		{
		setTimeoutRate(Rate);
		Reactor.registerTimer(this);
		cdevSystem::defaultSystem().addFdChangedCallback 
			(cdevSystemEventManager::fdChangedCallback, this);
		}
		
	~cdevSystemEventManager ( void )
		{
		if(reactor) reactor->extractHandler(this);
		handleClose();
		}
		
	int handleTimeout ( void )
		{
		cdevSystem::defaultSystem().pend(0.0001);
		return 0;
		}
	
	static void fdChangedCallback ( int fd, int opened, void * arg )
		{
		cdevSystemEventManager *manager = (cdevSystemEventManager *)arg;
		cdevEventHandler       *handler;
		cdevReactor            *reactor = manager->reactor;
		
		if(reactor)
			{
			if(opened && reactor->getHandler(fd, handler)!=0)
				{
				handler = new cdevSystemEventHandler(*reactor, fd);
				}
			else if(!opened && reactor->getHandler(fd, handler)==0)
				{
				delete handler;
				}
			}
		}
};

