#ifndef QRK_M_BEEGO_DRIVE_H
#define QRK_M_BEEGO_DRIVE_H

/*!
  \file
  \brief モニタ対応の BeegoDrive クラス

  \author Satofumi KAMIMURA

  $Id: mBeegoDrive.h 1583 2009-12-20 02:12:07Z satofumi $
*/

#include "Coordinate.h"
#include "Running.h"
#include "WheelDirect.h"
#include "Timestamp.h"
#if 0
#include "motor_t.h"
#include "encoder_t.h"
#include "wheel_t.h"
#include "body_t.h"
#endif


namespace qrk
{
  //! モニタ対応の BeegoDrive クラス
  class mBeegoDrive
    : public Coordinate, public Running, public WheelDirect, public Timestamp
  {
  public:
    enum {
      DefaultBaudrate = 115200, // [bps]
    };
    mBeegoDrive(void);
    ~mBeegoDrive(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);

    void followLine(const Position<long>& line,
                    const Coordinate* coordinate = NULL);
    void followLine(long x, long y, const Angle& angle,
                    const Coordinate* coordinate = NULL);

    void stopLine(const Position<long>& line,
                  const Coordinate* coordinate = NULL);
    void stopLine(long x, long y, const Angle& angle,
                  const Coordinate* coordinate = NULL);

    void followCircle(const Point<long>& center, long radius,
                      const Coordinate* coordinate = NULL);
    void followCircle(long x, long y, long radius,
                      const Coordinate* coordinate = NULL);

    void stopCircle(const Point<long>& center, long radius, const Angle& angle,
                    const Coordinate* coordinate = NULL);
    void spin(const Angle& angle);
    void rotate(const Angle& angle, const Coordinate* coordinate = NULL);

    void stop(void);
    void freeServo(void);

    Position<long> position(const Coordinate* coordinate = NULL) const;
    long maxStraightVelocity(void) const;
    long straightVelocity(void) const;
    Angle rotateVelocity(void) const;

    void changeRobotPosition(const Position<long>& to,
                             const Position<long>& from);

#if 0
    void setRobotPosition(const Position<long>& position,
                          const Coordinate* coordinate = NULL);
    void setRobotPositionOffset(const Position<long>& offset);
#endif
    void setStraightVelocity(long mm_per_sec);
    void setRotateVelocity(const Angle& angle_per_sec);
    void setStraightAcceleration(long mm_per_sec2);
    void setRotateAcceleration(const Angle& angle_per_sec2);

    bool isStable(void) const;

    void setWheelVelocity(int id, long mm_per_sec);

    std::string currentCommand(void) const;
    void saveCommand(void);
    void restoreCommand(void);
    void commitParameters(void);

#if 0
    void setMotorParameter(int id, const motor_t& motor);
    void setEncoderParameter(int id, const encoder_t& encoder);
    void setWheelParameter(int id, const wheel_t& wheel);
    void setBodyParameter(const body_t& body);
#endif

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

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

#endif /* !QRK_M_BEEGO_DRIVE_H */
