#ifndef _CDEV_MONITOR_TABLE_H_
#define _CDEV_MONITOR_TABLE_H_ 1

#include <cdevMessage.h>
#include <StringHash.h>
#include <cdevData.h>
#include <xdrClass.h>


// *****************************************************************************
// * class cdevMonitorData :
// *	This class gives a cdevData object the capacity to selectively place
// *	its tagged data items into an XDR stream.  
// *****************************************************************************
class GENERIC_SERVER_API cdevMonitorData : public cdevData
{
protected:
	int * criticalTags;
	int   criticalTagCnt;

	virtual int  isTagCritical ( int tag );

public:
	cdevMonitorData (void );
	cdevMonitorData (const cdevData & data);
	cdevMonitorData (const cdevMonitorData & data);

	virtual void setCriticalTags ( int * tags, int tagCnt );
	virtual int  changeTag       ( int oldTag, int newTag );
	virtual int  xdrExport       ( char ** buf, size_t * bufLen );
	virtual int  xdrExport       ( char * buf, size_t bufLen, size_t count);
	virtual int  xdrSize         ( size_t * bufLen, size_t * elementCount );
};


// *****************************************************************************
// * class cdevMonitorNode :
// *	This class is used to store the list of monitors associated with a 
// *	device / attribute pair.  It maintains a back-pointer to the 
// *	cdevMonitorTable object to allow it to call the fireCallback method of 
// *	the parent in order to submit the reply.
// *****************************************************************************
class GENERIC_SERVER_API cdevMonitorNode
{
friend class cdevMonitorTable;

protected:
	// **********************************************************************
	// * class cdevMonitorEntry :
	// *	This is an individual monitor transaction that has been installed 
	// *	in a cdevMonitorNode.
	// **********************************************************************
	class cdevMonitorEntry
	{
	friend class cdevMonitorNode;
	private:
		static int         VALUE_TAG;	
		static int         STATUS_TAG;
		static int         TIME_TAG;
		static int         DEVICE_TAG; // *** Added for multi-device

		cdevMonitorEntry * next;
		cdevMessage      * message;
		int              * triggers;
		int              * trigType;
		int                trigCnt;
		int              * properties;
		int                propCnt;
		
		int                deviceIdx;  // *** Added for multi-device
			 
		cdevMonitorEntry  ( cdevMessage * Message, int deviceIdx ); 
		~cdevMonitorEntry ( void );
	};
	
	class cdevMonitorTable * parent;
	cdevMonitorEntry       * nodes;
	cdevMonitorData          mData;
	char                   * hashString;
	
	virtual int    fireMonitor          ( cdevMonitorEntry *entry, 
				              int property, 
				              cdevMonitorData * data,
				              int endOfTransaction = 0);

	virtual int    insertMonitor        ( cdevMessage * request, 
				              cdevData    * data, 
				              int           deviceIdx );

	virtual int    removeMonitor        ( cdevMessage * request );
	virtual int    removeMonitor        ( unsigned transIndex );
	virtual int    removeClientMonitors ( short clientID, int fire = 1 );
	char *         getHashString        ( void ) { return hashString; }

public:
	cdevMonitorNode                     ( cdevMonitorTable * Parent, 
	                                      char             * Device, 
	                                      char             * Attrib );
	virtual ~cdevMonitorNode            ( void );

	virtual int    fireMonitor          ( char * property, cdevData * data );
	virtual int    fireMonitor          ( int property, cdevData * data );
	int            isMonitored          ( void ) { return nodes==NULL?0:1; }
};



// *****************************************************************************
// * class cdevMonitorTable :
// *	This class is used to store the list of all monitors for all device /
// *	attribute pairs in the system. The developer must provide the 
// *	fireCallback method which will be used to submit the callback to the 
// *	client.
// *****************************************************************************
class GENERIC_SERVER_API cdevMonitorTable
{
protected:
	StringHash monitors;
	
public:
	cdevMonitorTable                      ( void );
	virtual ~cdevMonitorTable             ( void );
	
	virtual int               insertMonitor       ( cdevMessage * request, cdevData * data );
	virtual int               insertMonitor       ( cdevMessage * request, cdevData ** data, size_t dataCnt );
	virtual int               removeMonitor       ( cdevMessage * request );
	virtual int               removeClientMonitors( short clientID, int fire = 1 );
	virtual cdevMonitorNode * findMonitor         ( char * device, char * attrib );	
	virtual int               fireMonitor         ( char * device, char * attrib, 
	                                                char * property, cdevData * data );
	virtual int               fireMonitor         ( char * device, char * attrib, 
	                                                int property, cdevData * data );
	virtual int               fireCallback        ( cdevMessage * message );
};

#endif
