#ifndef _DMMONITOR_H
#define _DMMONITOR_H
static char DmMonitor_h_id[] = "$Header: /usr/tiburon/unix/gui/tmacs/RCS/DmMonitor.h,v 1.3 1997/08/12 14:40:00 oreilly Exp $";

/*
$Log: DmMonitor.h,v $
Revision 1.3  1997/08/12 14:40:00  oreilly
*** empty log message ***

 * Revision 1.2  97/03/20  12:33:50  12:33:50  oreilly (Thomas C. O'Reilly)
 * *** empty log message ***
 * 
 * Revision 1.1  96/10/28  09:13:37  09:13:37  oreilly (Thomas C. O'Reilly)
 * Initial revision
 * 
*/

#include "array.h"
#include "DataManager.h" 

#define MAX_GROUP_SIZE 32
#define EmptySlot 0

typedef enum
{
  AddItem, RemoveItem

} RequestCmd;


struct RequestMessage
{
  RequestCmd cmd;
  char itemName[MAX_NMLEN];
  int arrayIndex;
  Period period;
  void *guiListPtr;
};

struct MonitoredGroupItem
{
  DM_Item handle;
  void *guiListPtr;
};

struct MonitoredGroup
{
  MonitoredGroup();
  DM_Group id;
  int nItems;
  MonitoredGroupItem items[MAX_GROUP_SIZE];
};

/*
DmMonitor manages "registration" requests from application for aperiodic data;
monitors items for new data; when new data is ready DmMonitor notifies 
application
*/
class DmMonitor
{
  public:
  DmMonitor(SEM_ID wakeupSem, int writeFd);
  ~DmMonitor();

  // Register specified DM item for monitoring
  int handleRequest(RequestMessage *message);

  // Determine if new data in any groups
  MBool newData();

  // Return total number of registered items
  int nItems();

  // Send message(s) to application for any updated DM item(s)
  int handleNewData();

  protected:
  // Register a DM item for monitoring
  int addItem(RequestMessage *message);

  // Unregister a DM item
  int removeItem(RequestMessage *message);

  // Create a new DM group
  MonitoredGroup *newGroup();

  // Return pointer to first MonitoredGroup which contains empty slots
  MonitoredGroup *availableGroup();
  
  // Array of MonitoredGroups
  DynArray<MonitoredGroup *> _groups;

  int _totalItems;
  SEM_ID _wakeupSem;
  int _writeFd;
};

#endif
