//=========================================================================
// Summary  : */
// Filename : EventTriggers.cc
// Author   : */
// Project  : */
// Revision : 1
// Created  : 2000/08/19
// Modified : 2000/08/19
//=========================================================================
// Description :
//=========================================================================
#include <stdio.h>
#include <sys/kernel.h>
#include <errno.h>
#include "EventTriggers.h"
#include "TaskServer.h"
#include "Syslog.h"


EventTriggers::EventTriggers(pid_t observer)
{
  _observer = observer;
}


EventTriggers::~EventTriggers()
{
  Boolean debug = False;
  dprintf("EventTriggers::~EventTriggers() - cleaning up proxies.\n");

  EventTrigger *eventTrigger;
  for ( int i=0; i < _eventTriggers.size(); i++ ) {
	  _eventTriggers.get(i, &eventTrigger);
	  if ( eventTrigger->proxy != -1 )
	  {
		  dprintf("EventTriggers::~EventTriggers() - detaching proxy %d.\n", eventTrigger->proxy);
		  qnx_proxy_detach( eventTrigger->proxy );
	  }
  }
}


void EventTriggers::add(EventCode eventCode)
{
  Boolean debug = False;

  EventTrigger *eventTrigger;
  // Check to see if already registered
  for (int i = 0; i < _eventTriggers.size(); i++) {
    _eventTriggers.get(i, &eventTrigger);
    if (eventTrigger->notification->eventCode == eventCode) {
      // Already registered
      return;
    }
  }

  eventTrigger = new EventTrigger();
  eventTrigger->notification = new TaskServer::Event();
  eventTrigger->notification->eventCode = eventCode;
  eventTrigger->notification->forward = True;
  eventTrigger->notification->node = getnid();

  // Server pid will be filled in by associated server
  eventTrigger->notification->serverPid = NoPid;

  dprintf("**** EventTriggers::add() - attaching proxy to PID %d.", _observer);

  if ((eventTrigger->proxy =
       qnx_proxy_attach(_observer,
			(char *)eventTrigger->notification,
			sizeof(TaskServer::Event), -1)) == -1) {

    char errorBuf[256];
    sprintf(errorBuf, "EventTriggers::add() - %s", strerror(errno));
    throw Exception(errorBuf);
  }

  // Add to list
  _eventTriggers.add(&eventTrigger);
}



void EventTriggers::notify(EventCode eventCode)
{
  Boolean debug = False;
  dprintf("EventTriggers::notify() - eventCode=%d\n", eventCode);

  EventTrigger *eventTrigger;

  for (int i = 0; i < _eventTriggers.size(); i++) {
    _eventTriggers.get(i, &eventTrigger);

    if (eventTrigger->notification->eventCode == eventCode) {

      dprintf("EventTriggers::notify() - "
	      "triggering proxy %d, send to pid %d\n",
	      eventTrigger->proxy, _observer);

      eventTrigger->notification->forward = True;

      if (Trigger(eventTrigger->proxy) == (pid_t )-1) {
	Syslog::write("EventTriggers::notify() - Trigger() failed: %s\n",
		      strerror(errno));
      }

      return;
    }
  }

  // Event is not yet registered
  dprintf("EventTriggers::notify() - not yet registered; add()\n");
  add(eventCode);
  dprintf("EventTriggers::notify() - NOW notify()\n");
  notify(eventCode);
}
