#ifndef _MICROEVENTHANDLER_H
#define _MICROEVENTHANDLER_H

#include "ostask.h"
#include "errorhandler.h"
#include "callback.h"
#include "dynamicarray.h"
#include "eventobject.h"

class MicroApp;
class TaskSynchronizer;

/*----------------------------------------------------------------
CLASS 
	MicroEventHandler

DESCRIPTION
	MicroEventHandler monitors event items, and either invoke callbacks
	when they change, or hand off processing to parent class through
	a processEvents() virtual method.

AUTHOR
	Tom O'Reilly. Modified by D.Cline for Genosensor Project.
	Modifications not required for the LRS project.
----------------------------------------------------------------*/
class MicroEventHandler : public ErrorHandler, public TaskBase
{
  public:

  // Constructor
  // [input] name: application name
  // [input] tasksync: TaskSynchronizer
  // throws NullArg exception is tasksync is NULL
  MicroEventHandler(const char *name, TaskSynchronizer *tasksync);
  
  // Destructor
  // Frees all event items, and strduped application name  
  ~MicroEventHandler();

  // Entry point for eventhandler task. This will run a loop that
  // monitors for events until shutdown() is called
  void *  run();		

  // Add EventObject to event list
  // [input] EventObject: EventObject to be event
  // [input] callback: Function to call when EventObject changes
  int addEventMonitor(EventObject *event, CallbackObject *callback = NULL);

  // Call this to end the run() method. This will set the shutdown event  
  // and call the appropriate taskSynchronizer shutdown methods. Use this
  // to close the EventHandler as a standalone module(such as for module
  // tests). Returns -1 on error
  // [input] waitmillisecs: Seconds to wait for task to shutdown
  int shutdown(int waitmillisecs = 1);

  // Reset event monitoring loop.  Is used to reset the runEventLoop() method 
  // Must be used with TaskSynchronizer to do a system reset.
  void reset();

  protected:

  // Process any changed EventObject items. Override this method if you want
  // to process all item changes at once in addition to
  // (those using the "callback" method)
  virtual int processEvents();

  private:

  const char *_name;
  TaskSynchronizer *_taskSync;

  // Event object. Is set to break run() loop. Task synchronizer must
  // set this AFTER setting calling semTake on MicroEventHandler.
  EventObject _resetEvent;

  EventObject _shutdownEvent;

  Boolean _callbacksDefined;
	  
  // Runs event monitor loop
  // monitors for events until task syncronizer shutdown or reset
  // is called
  int runEventLoop();		

  // Waits for a single event handle in _syncArray to be signaled
  // Returns -1 if timed out before an event was signaled
  int waitForEvent(Int32 timeOut = WAIT_FOREVER);

  // Calls clear method for all EventItems in _eventItems array
  // Is called just after a reset, or on initial startup  	 
  void clearChanges(void);

  // TODO: please comment this
  int invokeCallbacks();

  // eventItem holds pointers to eventObjects and callback methods
  struct EventItem
  {
    // EventObject item ptr
    EventObject *eventObject;

    // Pointer to callback
	CallbackObject *callback;
  };

  // Array of event nodes
  DynamicArray _eventItems;  


};


#endif

