#ifndef _MICROAPP_H
#define _MICROAPP_H

#include "DeviceInterface.h"
#include "MicroSampler.h"
#include "DmMonitor.h"
#include "TaskSynchronizer.h"
#include "ErrorHandler.h"

#define dprintf if (debug) logMsg

#ifdef UNIX
# include "VxStubs.h"
# define logMsg printf
#else
  extern "C" 
  {
#   include "logLib.h"
#   include "vxWorks.h"
#   include "msgQLib.h"
#   include "semLib.h"
#   include "taskLib.h"
#   include "lstLib.h"
#   include "datamgr.h"
#   include "sio32.h"
#   include "sio32Server.h"
#   include "sio32Client.h"
#   include "microCmd.h"
#   include "microcmd.h"
#   include "applic.h"
#   include "powerTypes.h"
#   include "microTask.h"

};
# endif


/*
CLASS 
MicroApp

DESCRIPTION
MicroApp has the following responsibilities:

Initialize micro communication
Spawn subsidiary tasks
Process Micro SRQs

AUTHOR
Tom O'Reilly
*/
class MicroApp : public ErrorHandler
{
  public:

  ///////////////////////////////////////////////////////////////////
  // Constructor
  // [input] systemName:  Name of system (e.g. "TIBURON")
  // [input] appName:  Name of application (e.g. "MWSLED")
  // [input] device: Pointer to DeviceInterface
  MicroApp(const char *systemName,
	   const char *appName,
	   DeviceInterface *device);

  ~MicroApp();

  ///////////////////////////////////////////////////////////////////
  // Create and run subsidiary tasks. Process Micro events.
  int run();
  
  ///////////////////////////////////////////////////////////////////
  // TaskSynchronizer (inter-task synchronization, etc.)
  TaskSynchronizer *taskSync;
  
  ///////////////////////////////////////////////////////////////////
  // Micro Datamanager objects
  MicroDm *microDm;

  ///////////////////////////////////////////////////////////////////
  // Interface to micro device
  DeviceInterface *device;


  protected:

  ///////////////////////////////////////////////////////////////////
  // Task parameters for subsidiary tasks
  // [] priority: Task priority
  // [] floatingPoint: TRUE if task uses floatingPoint operations
  // [] stackSize: stacksize for task
  struct TaskParams
  {
    int priority;
    MBool floatingPoint;
    int stackSize;
  };

  ///////////////////////////////////////////////////////////////////
  // Fill in TasksParams structure for DmMonitor and MicroSampler tasks
  virtual void setTaskParams() = 0;

  ///////////////////////////////////////////////////////////////////
  // Process SRQ from micro. Return 0 on success, -1 on error
  // [input] srqPacket: packet read from micro
  // [input] nPacketBytes: # of bytes in srqPacket
  virtual int processSrq(Byte *srqPacket, int nPacketBytes) = 0;

  ///////////////////////////////////////////////////////////////////
  // Create MicroSampler subclass object
  virtual MicroSampler *createMicroSampler() = 0;

  ///////////////////////////////////////////////////////////////////
  // Create DmMonitor subclass object
  virtual DmMonitor *createDmMonitor() = 0;
  
  ///////////////////////////////////////////////////////////////////
  // Handle Micro reset
  virtual DeviceInterface::LinkState processMicroReset();

  ///////////////////////////////////////////////////////////////////
  // Create MicroDm and TaskSynchronizer
  virtual int initialize();

  ///////////////////////////////////////////////////////////////////
  // Pointer to created MicroSampler
  MicroSampler *_microSampler;

  ///////////////////////////////////////////////////////////////////
  // Pointer to created DmMonitor
  DmMonitor *_dmMonitor;

  ///////////////////////////////////////////////////////////////////
  // System name
  const char *_systemName;

  ///////////////////////////////////////////////////////////////////
  // Application name
  const char *_appName;
  
  ///////////////////////////////////////////////////////////////////
  // Serial channel number
  Nat16 _serialChanNo;

  ///////////////////////////////////////////////////////////////////
  // TaskParams for DmMonitor; must be filled in by setTaskParams() 
  TaskParams _dmMonitorParams;

  ///////////////////////////////////////////////////////////////////
  // TaskParams for MicroSampler; must be filled in by setTaskParams() 
  TaskParams _microSamplerParams;

  ///////////////////////////////////////////////////////////////////
  // Enable the micro (try maxTries). Returns OK on success, 
  // ERROR on failure
  // [input] maxTries: Maximum number of tries to enable
  STATUS enableMicro(int maxTries = 5);
  
  ///////////////////////////////////////////////////////////////////
  // Update micro Datamanager items following reset
  virtual STATUS resetMicroDmItems();
  

  private:

  int spawnTasks();
  static int runMicroSampler(MicroApp *mainTask,
			     int dummy1,
			     int dummy2,
			     int dummy3,
			     int dummy4,
			     int dummy5,
			     int dummy6,
			     int dummy7,
			     int dummy8,
			     int dummy9);

  static int runDmMonitor(MicroApp *mainTask,
			  int dummy1,
			  int dummy2,
			  int dummy3,
			  int dummy4,
			  int dummy5,
			  int dummy6,
			  int dummy7,
			  int dummy8,
			  int dummy9);
};


#endif




