/*
********************************************************
Copyright 2000 MBARI.
MBARI Proprietary Information. All rights reserved.
NOTE: This file is automatically generated.
DO NOT MODIFY.
********************************************************
*/

#ifndef __EchoSounderIF_H
#define __EchoSounderIF_H

#include "TaskInterface.h"

#include "RangeFinderIF.h"
#include "TimeIF.h"

#define EchoSounderIFServerName "EchoSounderIFServer"

class EchoSounderIF : public RangeFinderIF {

  friend class EchoSounderIF_SK;

  public:

  // Forward declarations of public structures
  struct Data;
  
  /*
  CLASS 
  EchoSounderIF
  
  DESCRIPTION 
  InstrumentIF for the echo sounder, which is a type of range finder.  See the
  parent classes - there is lots of other stuff!
  
  AUTHOR
  Rob McEwen
  
  */
  enum Constants {
    ScanArraySize = 151,
    EchoArraySize = 500
  };

  
  typedef char String4[4];
  typedef char StringArray[500];
  typedef short ShortArrayType[151];
  typedef unsigned long LongArrayType[151];
  
  //    typedef sequence<TimeIF::TimeSpec, SCANARRAYSIZE> TimeSpecArrayType;
  struct Data {
    double xzAngle;
    // read in from .cfg 
    EchoSounderIF::String4 header;
    char headID;
    char serialStatus;
    short train;
    unsigned char sector;
    unsigned char maxRange;
    // max range read in from .cfg 
    unsigned char maxRangeCfrm;
    Boolean error;
    TimeIF::TimeSpec updateTime;
    TimeIF::TimeSpec epoch;
    double range;
    // Range to target 
    EchoSounderIF::StringArray echoData;
    short nBytes;
    short nBytesRead;
    double freq;
    long crashCtr;
    Boolean echoReceived;
    EchoSounderIF::ShortArrayType ranges;
    EchoSounderIF::LongArrayType times;
    //TimeSpecArrayType times;
    short toffset;
    short tindx;
    short tindxMax;
    short tindxMin;
  };
  EchoSounderIF(const char *name, int timeout = 10);

  EchoSounderIF(const char *name, const char *serverName, int timeout = 10);

  ~EchoSounderIF();

  /////////////////////////////////////////////////////////
  // Get all available data from the instrument.
  DeviceIF::Status get(EchoSounderIF::Data *data);

  /////////////////////////////////////////////////////////
  // Get the most recent head angle:
  double getHeadAngle();

  /////////////////////////////////////////////////////////
  // Compute the head angle, given the index:
  double getHeadAngle(short tindx);

  /////////////////////////////////////////////////////////
  // Point the sonar head.  Zero is straight ahead, opposite the connector,
  // and positive is counter-clockwise when looking down on the instrument
  // from above.
  DeviceIF::Status headAngleCmd(double trainCmd);

  /////////////////////////////////////////////////////////
  // Put the head in scanning mode by calling the following
  // function with a sector angle >0 and < 180 degrees.  Setting "sector"
  // to zero shuts off scanning.
  DeviceIF::Status scanSectorCmd(double sector);

  /////////////////////////////////////////////////////////
  // Return "True" if this is the scanning instrument, and "False" if
  // it is the fixed-beam.
  Boolean isScanning();

  
  protected:

  // Message codes for each method
  enum EchoSounderIFMsgCode {
    GetMsgCode = 13,
    GetHeadAngleMsgCode,
    GetHeadAngle01MsgCode,
    HeadAngleCmdMsgCode,
    ScanSectorCmdMsgCode,
    IsScanningMsgCode
  };

  // Define message structure for each method
  struct GetMsg : Request, Reply {
    DeviceIF::Status returnVal;
    EchoSounderIF::Data data;
  
  } _getMsg;

  struct GetHeadAngleMsg : Request, Reply {
    double returnVal;
  
  } _getHeadAngleMsg;

  struct GetHeadAngle01Msg : Request, Reply {
    double returnVal;
    short tindx;
  
  } _getHeadAngle01Msg;

  struct HeadAngleCmdMsg : Request, Reply {
    DeviceIF::Status returnVal;
    double trainCmd;
  
  } _headAngleCmdMsg;

  struct ScanSectorCmdMsg : Request, Reply {
    DeviceIF::Status returnVal;
    double sector;
  
  } _scanSectorCmdMsg;

  struct IsScanningMsg : Request, Reply {
    Boolean returnVal;
  
  } _isScanningMsg;

};

#endif

