#ifdef UNIX
# include <malloc.h>
#endif
#include "vxUtils.h" 
#include "IviewMonitor.h"
#include "DmControlSource.h"

#define dprintf if (debug) fprintf

IviewMonitor::IviewMonitor()
{
  for (int index = 0; index < MaxControlSources; index++)
  {
    controlSource[index] = new DmControlSource(index);
    controlSource[index]->setMonitorRole();
  }
}


IviewMonitor::~IviewMonitor()
{
  for (int index = 0; index < MaxControlSources; index++)
    delete controlSource[index];
}


MBool IviewMonitor::hasControl(IviewDevice device, unsigned short axisMask, 
			       int *id, pid_t *pid)
{
  MBool client;
  MBool debug = TRUE;
  
  for (int index = 0; index < MaxControlSources; index++)
  {
    DmControlSource::AperiodicRequest request;
    DmControlSource::RequestStatus status;
    DmControlSource::Message msg;

    unsigned short devices;

    MBool inUse;
    
    controlSource[index]->hasClient(&inUse);
    if (!inUse)
      continue;

    controlSource[index]->readRequest(&request);

    if (!(axisMask & request.axisMask))
      // Control source not using this axis
      continue;
    
    controlSource[index]->readMessage(&msg);    
    devices = msg.deviceMask;

    if (devices & device)
    {
      *id = index;
      *pid = request.pid;
      return TRUE;
    }
  }

  *id = -1;
  return FALSE;
}


pid_t IviewMonitor::clientPid(unsigned int controlId, MBool *inUse)
{
  if (controlId < 0 || controlId >= MaxControlSources)
    return -1;
  
  pid_t pid;

  DmControlSource::AperiodicRequest request;

  controlSource[controlId]->hasClient(inUse);

  if (*inUse)
  {
    controlSource[controlId]->readRequest(&request);
    pid = request.pid;
  }
  else
    pid = -1;

  return pid;
}



int IviewMonitor::clientInfo(unsigned int controlId,
			     MBool *inUse,
			     int *clientHostAddr,
			     pid_t *clientPid,
			     unsigned short *axisMask,
			     unsigned short *deviceMask)
{
  if (controlId >= MaxControlSources)
    // Invalid id
    return -1;

  controlSource[controlId]->hasClient(inUse);

  if (!(*inUse))
  {
    return 0;
  } 

  DmControlSource::AperiodicRequest request;
  DmControlSource::RequestStatus status;
  DmControlSource::Message msg;

  unsigned short devices;

  controlSource[controlId]->readRequest(&request);

  *clientPid = request.pid;
  *clientHostAddr = request.hostAddr;
  *axisMask = request.axisMask;
    
  controlSource[controlId]->readMessage(&msg);    
  *deviceMask = msg.deviceMask;

  return 0;
}



