#ifndef _NAVSENSOR_H
#define _NAVSENSOR_H

#include "DynamicArray.h"
#include "DeviceIF.h"
#include "TimeIF.h"

class NavSensor;
typedef DynamicArray<NavSensor *> NavSensors;

/*
CLASS 
NavSensor

DESCRIPTION
Contains a TaskInterface to a sensor server task. (This TaskInterface
object must be created by a NavSensor subclass). Provides methods to
create TaskInterface, read sensor data, indicate if sensor data is currently
"valid", etc. Keeps track of consecutive DeviceIF errors.

Navigation has a list (NavSensors) of all NavSensor objects, and so
can process them all uniformly.

AUTHOR
Tom O'Reilly

*/

class NavSensor {

public:

  NavSensor(const char *name, NavSensors *sensors, int maxBad);

  virtual ~NavSensor();

  ///////////////////////////////////////////////////////////////////
  // True if latest reading is valid
  Boolean valid();

  ///////////////////////////////////////////////////////////////////
  // Sensor sample time
  TimeIF::TimeSpec sampleTime();

  ///////////////////////////////////////////////////////////////////
  // Reset valid flag, try to read sensor. Returns true if valid.
  // Keeps track of consecutive bad readings.
  Boolean read();

  ///////////////////////////////////////////////////////////////////
  // Return pointer to sensor's TaskInterface
  TaskInterface *taskIF();

  ///////////////////////////////////////////////////////////////////
  // Number of consecutive invalid reads that returned DeviceIF error status
  int nConsecutiveBad();

  ///////////////////////////////////////////////////////////////////
  // Maximum allowable consecutive invalid reads that return 
  // DeviceIF error status
  int maxConsecutiveBad();

  ///////////////////////////////////////////////////////////////////
  // True if nConsecutiveBad() exceeds maxConsecutiveBad()
  Boolean failed();

  ///////////////////////////////////////////////////////////////////
  // Creates TaskInterface object and connects to its server
  void connect(int timeout);

  ///////////////////////////////////////////////////////////////////
  // Sensor name
  const char *name();


  ///////////////////////////////////////////////////////////////////
  // Most recent DeviceIF status
  DeviceIF::Status deviceStatus();


protected:

  ///////////////////////////////////////////////////////////////////
  // Read the sensor's interface.
  // [output] valid: True if data is usable (e.g., within range)
  // 
  // Returns DeviceIF::Ok if device is functioning properly, else
  // a DeviceIF::Status error code.
  virtual DeviceIF::Status readTaskIF(Boolean *valid, 
				      TimeIF::TimeSpec *sampleTime) = 0;

  ///////////////////////////////////////////////////////////////////
  // Create and return pointer to TaskInterface object
  virtual TaskInterface *createTaskIF(int timeout) = 0;

  TaskInterface *_taskIF;
  Boolean _valid;
  int _nConsecutiveBad;
  int _maxConsecutiveBad;
  const char *_name;

private:

  DeviceIF::Status _status;
  TimeIF::TimeSpec _sampleTime;
};




#endif
