#ifndef _DATAMANAGER_H
#define _DATAMANAGER_H
static char DataManager_h_id[] = "$Header: /u/oreilly/rov/datamgr/RCS/DataManager.h,v 1.13 1998/05/18 19:53:19 oreilly Exp oreilly $";
/*
$Log: DataManager.h,v $
Revision 1.13  1998/05/18 19:53:19  oreilly
*** empty log message ***

Revision 1.12  1998/03/13 19:26:28  oreilly
Added Cocoon documentation

Revision 1.11  1998/02/23 16:33:45  oreilly
*** empty log message ***

Revision 1.10  1998/01/27 17:02:15  oreilly
Don't include hashLib.h

Revision 1.9  1997/12/08 15:32:21  oreilly
*** empty log message ***

 * Revision 1.8  97/08/12  15:12:45  15:12:45  oreilly (Thomas C. O'Reilly)
 * *** empty log message ***
 * 
 * Revision 1.7  97/03/20  12:25:04  12:25:04  oreilly (Thomas C. O'Reilly)
 * *** empty log message ***
 * 
 * Revision 1.6  97/02/24  11:39:55  11:39:55  oreilly (Thomas C. O'Reilly)
 * *** empty log message ***
 * 
 * Revision 1.5  97/01/28  09:46:07  09:46:07  oreilly (Thomas C. O'Reilly)
 * *** empty log message ***
 * 
 * Revision 1.4  96/10/28  09:10:02  09:10:02  oreilly (Thomas C. O'Reilly)
 * *** empty log message ***
 * 
 * Revision 1.3  96/07/22  08:44:26  08:44:26  oreilly (Thomas C. O'Reilly)
 * *** empty log message ***
 * 
*/

#include <stdio.h>
#include <mbari/types.h>

#ifdef UNIX
# include <dmUnix.h>
# include <time.h>
# include <sys/param.h>
#else
# include <mbari/param.h>
# include <sys/times.h>
#endif

#include <stdio.h>
#include <string.h>
#include <mbari/types.h>
#include <mbari/const.h>

extern "C" 
{
#include <semLib.h>
#include <lstLib.h>
#include "datamgr.h"
#include "dm_errno.h"
#include <signal.h>
#include <taskLib.h>
};


#ifdef UNIX
# include <malloc.h>
#endif

#include "ErrorHandler.h"

#define NoPeriod NO_PERIOD

#define MaxDmNameLen MAX_NMLEN

typedef enum
{
  ExclusiveProvider, MultiProviders

} ProviderType;


typedef enum {
  DmPeriodic, DmAperiodic

} DmSampleMethod;

typedef enum
{
  DmOpaqueType,
  DmEnumType, DmBooleanType, 
  DmNat16Type, DmInt16Type, DmNat32Type, DmInt32Type, 
  DmFlt32Type,
  DmFlt64Type, DmEmptyType, DmAttitudeType, DmPositionType,
  DmStringType

} DmObjectType;


const int DmConsumeFlag = 01;
const int DmProvideFlag = 02;
const int DmMultiProvideFlag = 02;
typedef unsigned int DmRoleFlags;

/*
CLASS 
DmObject

DESCRIPTION
DmObject encapsulates a Data Manager item and functions that can be performed
on it.

AUTHOR
Tom O'Reilly
*/

class DmObject : public ErrorHandler
{
  protected:

  char *_name;
  int _arraySize;
  DM_Item _handle;
  DmRoleFlags _roleFlags;
  Period _consumePeriod;
  Period _providePeriod;

  /* Create data manager item */
  virtual int createItem(DM_Type type);
  virtual int createHandle();
  
  ///////////////////////////////////////////////////////////////////
  // Write item. Use gettimeofday() if input time pointer is NULL
  Errno dmWrite(void *data, DM_Size bytes, DM_Time *t);
  

  public:

  ///////////////////////////////////////////////////////////////////
  // Constructor
  // [input] name:  Name of object/item
  // [input] arraySize: Elements in item array (passed to dm_create())
  DmObject(
	   const char *name, 
           int arraySize
	  ); 

  ///////////////////////////////////////////////////////////////////
  // Constructor  
  // Create a DmObject from an existing DM_Item.
  // [input] handle: Pointer to DM_Item
  // [input] arraySize: Elements in item array (passed to dm_create())
  DmObject(
	   DM_Item *handle,
	   int arraySize = 1
	  );

  
  ~DmObject();

  ///////////////////////////////////////////////////////////////////
  // Return size of DM_Item array
  int arraySize() 
  {
    return _arraySize;
  }

  ///////////////////////////////////////////////////////////////////
  // Return object type
  virtual DmObjectType objectType()
  {
    return DmOpaqueType;
  }


  ///////////////////////////////////////////////////////////////////
  // Return consume period in micro-seconds
  Period consumePeriod()
  {
    return _consumePeriod;
  }
  
  ///////////////////////////////////////////////////////////////////
  // Return provide period in micro-seconds
  Period providePeriod()
  {
    return _providePeriod;
  }
  
  ///////////////////////////////////////////////////////////////////
  // Return object name
  const char *getName()
  {
    return (const char *)_name;
  }
  
  ///////////////////////////////////////////////////////////////////
  // Determine if object is a consumer
  MBool isConsumer()
  {
    return (_roleFlags & DmConsumeFlag);
  }
  
  ///////////////////////////////////////////////////////////////////
  // Determine if object is a provider
  MBool isProvider()
  {
    return (_roleFlags & DmProvideFlag);
  }

  ///////////////////////////////////////////////////////////////////
  // Determine if object is a multiple provider
  MBool isMultiProvider()
  {
    return (_roleFlags & DmMultiProvideFlag);
  }
  
  ///////////////////////////////////////////////////////////////////
  // Return DM_Item associated with object
  DM_Item getHandle()
  {
    return _handle;
  }
  
  ///////////////////////////////////////////////////////////////////
  // Determine if Datamanager error code is fatal
  // [input] err: Datamanager error code (as defined in datamgr.h)
  static MBool fatalError(Errno err);
  

  ///////////////////////////////////////////////////////////////////
  // Start providing 
  // [input] period: Period (microsecs) at which to provide data
  // [input] multiple: ExclusiveProvider or MultiProviders
  Errno startProvide(Period period, ProviderType multiple = MultiProviders);

  ///////////////////////////////////////////////////////////////////
  // Start providing, with preset period specified by setProvidePeriod()
  // [input] multiple: ExclusiveProvider or MultiProviders
  Errno startProvide(ProviderType multiple = MultiProviders);

  ///////////////////////////////////////////////////////////////////
  // Stop providing
  Errno stopProvide();

  ///////////////////////////////////////////////////////////////////
  // Start consuming
  // [input] period: Period (microsecs) at which to consume data
  // [input] wakeup: Optional wakeup semaphore
  Errno startConsume(Period period, SEM_ID wakeup = SEM_NULL);

  ///////////////////////////////////////////////////////////////////
  // Start consuming, with preset period specified by setConsumePeriod()
  Errno startConsume(SEM_ID wakeup = SEM_NULL);

  ///////////////////////////////////////////////////////////////////
  // Stop consuming
  Errno stopConsume();

  ///////////////////////////////////////////////////////////////////
  // Preset the consumer period. Subsequent calls to startConsume()
  // with no period specified will use the preset period.
  // [input] period: Period (microsecs) at which to consume data
  Errno setConsumePeriod(Period period);

  ///////////////////////////////////////////////////////////////////
  // Preset the provider period. Subsequent calls to startProvide()
  // with no period specified will use the preset period.
  // [input] period: Period (microsecs) at which to provide data
  Errno setProvidePeriod(Period microsec);

  ///////////////////////////////////////////////////////////////////
  // Open for urgent write.
  // [input] period: Period (microsecs) at which to provide data
  Errno urgentOpen(Period period);

  ///////////////////////////////////////////////////////////////////
  // Terminate urgent writing
  Errno urgentClose();
  
  ///////////////////////////////////////////////////////////////////
  // Print mnemonic string corresponding to specified DM_Type
  static void sprintDataType(DM_Type dmType, char *buf);

  ///////////////////////////////////////////////////////////////////
  // Build item name from components. 
  // Caller must terminate component list with null.
  static void buildName(char itemName[MaxDmNameLen], ...);

  ///////////////////////////////////////////////////////////////////
  // Build item name prefix from components. Ensures that prefix
  // ends in '.' Caller must terminate component list with null.
  static void buildPrefix(char itemName[MaxDmNameLen], ...);
};


/*
CLASS 
DmInt16Object

DESCRIPTION
DmObject for data of type Int16
on it.

AUTHOR
Tom O'Reilly
*/

class DmInt16Object : public DmObject
{
  public:

  ///////////////////////////////////////////////////////////////////
  // Constructor
  // [input] name:  Name of object/item
  // [input] arraySize: Elements in item array (passed to dm_create())
  DmInt16Object(const char *name, int arraySize = 1);

  ///////////////////////////////////////////////////////////////////
  // Write data. If this object is an array, this method writes only
  // the first array element.
  // If DM_Time pointer is NULL, gettimeofday() is used to timestamp data
  // [input] val: Value to write 
  // [input] t: Time at which data is written 
  Errno write(Int16 val, DM_Time *t = 0);

  ///////////////////////////////////////////////////////////////////
  // Write data. If this object is an array, this method writes all
  // elements.
  // If DM_Time pointer is NULL, gettimeofday() is used to timestamp data
  // [input] val: Array of values to write 
  // [input] t: Time at which data is written
  Errno write(Int16 *val, DM_Time *t = 0);

  ///////////////////////////////////////////////////////////////////
  // Read data. If this object is an array, this method reads all
  // elements.
  // [input] val: Destination for data
  // [output] t: Time at which data was written
  Errno read(Int16 *val, DM_Time *t = 0);

  ///////////////////////////////////////////////////////////////////
  // Return DmObjectType
  DmObjectType objectType() 
  {
    return DmInt16Type;
  }
  
};


/*
CLASS 
DmNat16Object

DESCRIPTION
DmObject for data of type Nat16
on it.

AUTHOR
Tom O'Reilly
*/
class DmNat16Object : public DmObject
{
  public:
  
  ///////////////////////////////////////////////////////////////////
  // Constructor
  // [input] name:  Name of object/item
  // [input] arraySize: Elements in item array (passed to dm_create())
  DmNat16Object(const char *name, int arraySize = 1);

  ///////////////////////////////////////////////////////////////////
  // Write data. If this object is an array, this method writes only
  // the first array element.
  // If DM_Time pointer is NULL, gettimeofday() is used to timestamp data
  // [input] val: Value to write 
  // [input] t: Time at which data is written
  Errno write(Nat16 val, DM_Time *t = 0);

  ///////////////////////////////////////////////////////////////////
  // Write data. If this object is an array, this method writes all
  // elements.
  // If DM_Time pointer is NULL, gettimeofday() is used to timestamp data
  // [input] val: Array of values to write 
  // [input] t: Time at which data is written
  Errno write(Nat16 *val, DM_Time *t = 0);

  ///////////////////////////////////////////////////////////////////
  // Read data. If this object is an array, this method reads all
  // elements.
  // [input] val: Destination for data
  // [output] t: Time at which data was written
  Errno read(Nat16 *val, DM_Time *t = 0);

  ///////////////////////////////////////////////////////////////////
  // Return DmObjectType
  DmObjectType objectType() 
  {
    return DmNat16Type;
  }
  
};


/*
CLASS 
DmNat32Object

DESCRIPTION
DmObject for data of type Nat32

AUTHOR
Tom O'Reilly
*/
class DmNat32Object : public DmObject
{
  public:
  
  ///////////////////////////////////////////////////////////////////
  // Constructor
  // [input] name:  Name of object/item
  // [input] arraySize: Elements in item array (passed to dm_create())
  DmNat32Object(const char *name, int arraySize = 1);

  ///////////////////////////////////////////////////////////////////
  // Write data. If this object is an array, this method writes only
  // the first array element.
  // If DM_Time pointer is NULL, gettimeofday() is used to timestamp data
  // [input] val: Value to write 
  // [input] t: Time at which data is written
  Errno write(Nat32 val, DM_Time *t = 0);

  ///////////////////////////////////////////////////////////////////
  // Write data. If this object is an array, this method writes all
  // elements.
  // If DM_Time pointer is NULL, gettimeofday() is used to timestamp data
  // [input] val: Array of values to write 
  // [input] t: Time at which data is written
  Errno write(Nat32 *val, DM_Time *t = 0);

  ///////////////////////////////////////////////////////////////////
  // Read data. If this object is an array, this method reads all
  // elements.
  // [input] val: Destination for data
  // [output] t: Time at which data was written
  Errno read(Nat32 *val, DM_Time *t = 0);

  ///////////////////////////////////////////////////////////////////
  // Return DmObjectType
  DmObjectType objectType() 
  {
    return DmNat32Type;
  }
  
};


/*
CLASS 
DmInt32Object

DESCRIPTION
DmObject for data of type Int32

AUTHOR
Tom O'Reilly
*/
class DmInt32Object : public DmObject
{
  public:
  
  ///////////////////////////////////////////////////////////////////
  // Constructor
  // [input] name:  Name of object/item
  // [input] arraySize: Elements in item array (passed to dm_create())
  DmInt32Object(const char *name, int arraySize = 1);

  ///////////////////////////////////////////////////////////////////
  // Write data. If this object is an array, this method writes only
  // the first array element.
  // If DM_Time pointer is NULL, gettimeofday() is used to timestamp data
  // [input] val: Value to write 
  // [input] t: Time at which data is written
  Errno write(Int32 val, DM_Time *t = 0);

  ///////////////////////////////////////////////////////////////////
  // Write data. If this object is an array, this method writes all
  // elements.
  // If DM_Time pointer is NULL, gettimeofday() is used to timestamp data
  // [input] val: Array of values to write 
  // [input] t: Time at which data is written
  Errno write(Int32 *val, DM_Time *t = 0);

  ///////////////////////////////////////////////////////////////////
  // Read data. If this object is an array, this method reads all
  // elements.
  // [input] val: Destination for data
  // [output] t: Time at which data was written
  Errno read(Int32 *val, DM_Time *t = 0);

  ///////////////////////////////////////////////////////////////////
  // Return DmObjectType
  DmObjectType objectType() 
  {
    return DmInt32Type;
  }
  
};


/*
CLASS 
DmFlt32Object

DESCRIPTION
DmObject for data of type Flt32
on it.

AUTHOR
Tom O'Reilly
*/
class DmFlt32Object : public DmObject
{
  public:
  
  ///////////////////////////////////////////////////////////////////
  // Constructor
  // [input] name:  Name of object/item
  // [input] arraySize: Elements in item array (passed to dm_create())
  DmFlt32Object(const char *name, int arraySize = 1);

  ///////////////////////////////////////////////////////////////////
  // Write data. If this object is an array, this method writes only
  // the first array element.
  // If DM_Time pointer is NULL, gettimeofday() is used to timestamp data
  // [input] val: Value to write 
  // [input] t: Time at which data is written
  Errno write(Flt32 val, DM_Time *t = 0);

  ///////////////////////////////////////////////////////////////////
  // Write data. If this object is an array, this method writes all
  // elements.
  // If DM_Time pointer is NULL, gettimeofday() is used to timestamp data
  // [input] val: Array of values to write 
  // [input] t: Time at which data is written
  Errno write(Flt32 *val, DM_Time *t = 0);

  ///////////////////////////////////////////////////////////////////
  // Read data. If this object is an array, this method reads all
  // elements.
  // [input] val: Destination for data
  // [output] t: Time at which data was written
  Errno read(Flt32 *val, DM_Time *t = 0);

  ///////////////////////////////////////////////////////////////////
  // Return DmObjectType
  DmObjectType objectType() 
  {
    return DmFlt32Type;
  }
};


/*
CLASS 
DmFlt64Object

DESCRIPTION
DmObject for data of type Flt64

AUTHOR
Tom O'Reilly
*/
class DmFlt64Object : public DmObject
{
  public:
  
  ///////////////////////////////////////////////////////////////////
  // Constructor
  // [input] name:  Name of object/item
  // [input] arraySize: Elements in item array (passed to dm_create())
  DmFlt64Object(const char *name, int arraySize = 1);

  ///////////////////////////////////////////////////////////////////
  // Write data. If this object is an array, this method writes only
  // the first array element.
  // If DM_Time pointer is NULL, gettimeofday() is used to timestamp data
  // [input] val: Value to write 
  // [input] t: Time at which data is written
  Errno write(Flt64 val, DM_Time *t = 0);

  ///////////////////////////////////////////////////////////////////
  // Write data. If this object is an array, this method writes all
  // elements.
  // If DM_Time pointer is NULL, gettimeofday() is used to timestamp data
  // [input] val: Array of values to write 
  // [input] t: Time at which data is written
  Errno write(Flt64 *val, DM_Time *t = 0);

  ///////////////////////////////////////////////////////////////////
  // Read data. If this object is an array, this method reads all
  // elements.
  // [input] val: Destination for data
  // [output] t: Time at which data was written
  Errno read(Flt64 *val, DM_Time *t = 0);

  ///////////////////////////////////////////////////////////////////
  // Return DmObjectType
  DmObjectType objectType() 
  {
    return DmFlt64Type;
  }
};


/*
CLASS 
DmEnumObject

DESCRIPTION
DmObject for data of type Enum

AUTHOR
Tom O'Reilly
*/
class DmEnumObject : public DmObject
{
  public:
  
  ///////////////////////////////////////////////////////////////////
  // Constructor
  // [input] name:  Name of object/item
  // [input] arraySize: Elements in item array (passed to dm_create())
  DmEnumObject(const char *name, int arraySize = 1);

  ///////////////////////////////////////////////////////////////////
  // Write data. If this object is an array, this method writes only
  // the first array element.
  // If DM_Time pointer is NULL, gettimeofday() is used to timestamp data
  // [input] val: Value to write 
  // [input] t: Time at which data is written
  Errno write(Int32 val, DM_Time *t = 0);

  ///////////////////////////////////////////////////////////////////
  // Write data. If this object is an array, this method writes all
  // elements.
  // If DM_Time pointer is NULL, gettimeofday() is used to timestamp data
  // [input] val: Array of values to write 
  // [input] t: Time at which data is written
  Errno write(Int32 *val, DM_Time *t = 0);

  ///////////////////////////////////////////////////////////////////
  // Read data. If this object is an array, this method reads all
  // elements.
  // [input] val: Destination for data
  // [output] t: Time at which data was written
  Errno read(Int32 *val, DM_Time *t = 0);

  ///////////////////////////////////////////////////////////////////
  // Return DmObjectType
  DmObjectType objectType() 
  {
    return DmEnumType;
  }
};


/*
CLASS 
DmBooleanObject

DESCRIPTION
DmObject for data of type MBool

AUTHOR
Tom O'Reilly
*/
class DmBooleanObject : public DmObject
{
  public:
  
  ///////////////////////////////////////////////////////////////////
  // Constructor
  // [input] name:  Name of object/item
  // [input] arraySize: Elements in item array (passed to dm_create())
  DmBooleanObject(const char *name, int arraySize = 1);

  ///////////////////////////////////////////////////////////////////
  // Write data. If this object is an array, this method writes only
  // the first array element.
  // If DM_Time pointer is NULL, gettimeofday() is used to timestamp data
  // [input] val: Value to write 
  // [input] t: Time at which data is written
  Errno write(MBool val, DM_Time *t = 0);

  ///////////////////////////////////////////////////////////////////
  // Write data. If this object is an array, this method writes all
  // elements.
  // If DM_Time pointer is NULL, gettimeofday() is used to timestamp data
  // [input] val: Array of values to write 
  // [input] t: Time at which data is written
  Errno write(MBool *val, DM_Time *t = 0);


  ///////////////////////////////////////////////////////////////////
  // Read data. If this object is an array, this method reads all
  // elements.
  // [input] val: Destination for data
  // [output] t: Time at which data was written
  Errno read(MBool *val, DM_Time *t = 0);

  ///////////////////////////////////////////////////////////////////
  // Return DmObjectType
  DmObjectType objectType() 
  {
    return DmBooleanType;
  }
};


/*
CLASS 
DmEmptyObject

DESCRIPTION
DmObject for "events"

AUTHOR
Tom O'Reilly
*/
class DmEmptyObject : public DmObject
{
  public:
  
  ///////////////////////////////////////////////////////////////////
  // Constructor
  // [input] name:  Name of object/item
  // [input] arraySize: Elements in item array (passed to dm_create())
  DmEmptyObject(const char *name, int arraySize = 1);

  ///////////////////////////////////////////////////////////////////
  // Write event. If this object is an array, this method writes only
  // the first array element.
  // If DM_Time pointer is NULL, gettimeofday() is used to timestamp data
  // [input] t: Time at which data is written
  Errno write(DM_Time *t = 0);


  ///////////////////////////////////////////////////////////////////
  // Read data.
  // [input] t: Time at which data was written
  Errno read(DM_Time *t = 0);

  ///////////////////////////////////////////////////////////////////
  // Return DmObjectType
  DmObjectType objectType() 
  {
    return DmEmptyType;
  }
};


/*
CLASS 
DmStringObject

DESCRIPTION
DmObject for character string data

AUTHOR
Tom O'Reilly
*/
class DmStringObject : public DmObject
{
  public:
  ///////////////////////////////////////////////////////////////////
  // Constructor
  // [input] name:  Name of object/item
  // [input] maxLength: Maximum characters in string
  DmStringObject(const char *name, int maxLength);

  ///////////////////////////////////////////////////////////////////
  // Write string. 
  // If DM_Time pointer is NULL, gettimeofday() is used to timestamp data
  // [input] str: String to write 
  // [input] t: Time at which data is written
  Errno write(char *str, DM_Time *t = 0);

  ///////////////////////////////////////////////////////////////////
  // Read data. 
  // [input] str: Destination for string. At least maxLength+1 bytes
  // should be allocated for str.
  // [input] t: Time at which data was written
  Errno read(char *str, DM_Time *t = 0);
  
  ///////////////////////////////////////////////////////////////////
  // Return DmObjectType
  DmObjectType objectType()
  {
    return DmStringType;
  }

  protected:
  int _maxLength;
  
};



#endif


