#ifndef QRC_URG_DEVICE_H
#define QRC_URG_DEVICE_H

/*!
  \file
  \brief URG の制御

  \author Satofumi KAMIMURA

  $Id: UrgDevice.h 1669 2010-02-04 08:28:27Z satofumi $
*/

#include "Coordinate.h"
#include "RangeFinder.h"
#include "Timestamp.h"


namespace qrk
{
  //! URG の制御
  class UrgDevice : public Coordinate, public RangeFinder, public Timestamp
  {
  public:
    enum {
      DefaultBaudrate = 115200, // [bps]
    };

    typedef enum {
      GD_Capture,
      MD_Capture,
    } CaptureMode;

    UrgDevice(void);
    ~UrgDevice(void);

    const char* what(void) const;

    long timestamp(void) const;

    bool connect(const char* device, long baudrate = DefaultBaudrate);
    void disconnect(void);
    bool isConnected(void) const;
    void setConnection(Connection* connection);
    Connection* connection(void);

    /*!
      \brief Reboot URG

      \attention Only Top-URG (2010-02-04)
    */
    bool reboot(void);

    bool versionLines(std::vector<std::string>& lines);

    size_t scanMsec(void) const;
    size_t minDistance(void) const;
    size_t maxDistance(void) const;
    size_t maxRange(void) const;
    void setCaptureTimes(size_t times);
    void setCaptureRange(size_t begin_index, size_t end_index);
    void setSkipLines(size_t skip_lines);


    /*!
      \brief データの取得開始

      \param[in] mode データの取得モード
    */
    void setRequestMode(CaptureMode mode);


    void requestData(void);
    bool receiveData(std::vector<long>& data, long* timestamp = NULL);
    size_t rad2index(double radian) const;
    double index2rad(size_t index) const;


    //! レーザを点灯させる
    void laserOn(void);


    /*!
      \brief レーザを消灯させる

      レーザを消灯させる、データの取得処理は中断させる
    */
    void laserOff(void);

  private:
    UrgDevice(const UrgDevice& rhs);
    UrgDevice& operator = (const UrgDevice& rhs);

    struct pImpl;
    std::auto_ptr<pImpl> pimpl;
  };
}

#endif /* !QRC_URG_DEVICE_H */
