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

  \author Satofumi KAMIMURA

  $Id: mUrgDistance.cpp 1422 2009-10-18 13:48:05Z satofumi $
*/

#include "mUrgDistance.h"
#include "ExecutionType.h"
#include "DeviceManager.h"
#include "TcpipSocket.h"

using namespace qrk;


struct mUrgDistance::pImpl
{
  UrgDistance urg_;
  ExecutionType::Type type_;
  Connection* created_connection_;


  pImpl(void)
    : type_(ExecutionType::object()->type()), created_connection_(NULL)
  {
    if (type_ == ExecutionType::Simulation) {
      created_connection_ = new TcpipSocket;
      urg_.setConnection(created_connection_);
    }
  }


  ~pImpl(void)
  {
    delete created_connection_;
  }
};


mUrgDistance::mUrgDistance(void) : pimpl(new pImpl)
{
}


mUrgDistance::~mUrgDistance(void)
{
}


const char* mUrgDistance::what(void) const
{
  return pimpl->urg_.what();
}


bool mUrgDistance::connect(const char* device, long baudrate)
{
  DeviceManager device_manager;
  long port;

  switch (pimpl->type_) {
  case ExecutionType::Simulation:
    // ポート番号を取得し、TCP/IP として接続する
    port = device_manager.port(device);
    return pimpl->urg_.connect("localhost", port);
    break;

  case ExecutionType::RealDevice:
  case ExecutionType::Monitoring:
  case ExecutionType::Recording:
    // 指定されたデバイスにシリアルとして接続する
    return pimpl->urg_.connect(device, baudrate);
    break;

  case ExecutionType::Playback:
    // !!! 接続しない
    // !!! 記録しておいた結果を読み出して返す
    // !!!
    return false;
    break;
  }

  return false;
}


void mUrgDistance::disconnect(void)
{
  pimpl->urg_.disconnect();
}


bool mUrgDistance::isConnected(void) const
{
  return pimpl->urg_.isConnected();
}


void mUrgDistance::setConnection(Connection* connection)
{
  pimpl->urg_.setConnection(connection);
}


Connection* mUrgDistance::connection(void)
{
  return pimpl->urg_.connection();
}


size_t mUrgDistance::scanMsec(void) const
{
  return pimpl->urg_.scanMsec();
}


size_t mUrgDistance::minDistance(void) const
{
  return pimpl->urg_.minDistance();
}


size_t mUrgDistance::maxDistance(void) const
{
  return pimpl->urg_.maxDistance();
}


size_t mUrgDistance::maxRange(void) const
{
  return pimpl->urg_.maxRange();
}


#if 0
void mUrgDistance::setTimestamp(long timestamp)
{
  pimpl->urg_.setTimestamp(timestamp);
}
#endif


void mUrgDistance::setCaptureTimes(size_t times)
{
  pimpl->urg_.setCaptureTimes(times);
}


void mUrgDistance::setCaptureRange(size_t begin_index, size_t end_index)
{
  pimpl->urg_.setCaptureRange(begin_index, end_index);
}


void mUrgDistance::setSkipLines(size_t skip_lines)
{
  pimpl->urg_.setSkipLines(skip_lines);
}


void mUrgDistance::setRequestMode(UrgDevice::CaptureMode mode)
{
  pimpl->urg_.setRequestMode(mode);
}


void mUrgDistance::requestData(void)
{
  pimpl->urg_.requestData();
}


bool mUrgDistance::receiveData(std::vector<long>& data, long* timestamp)
{
  return pimpl->urg_.receiveData(data, timestamp);
}


bool mUrgDistance::receiveData(void)
{
  return pimpl->urg_.receiveData();
}


long mUrgDistance::at(size_t index) const
{
  return pimpl->urg_.at(index);
}


size_t mUrgDistance::rad2index(double radian) const
{
  return pimpl->urg_.rad2index(radian);
}


double mUrgDistance::index2rad(size_t index) const
{
  return pimpl->urg_.index2rad(index);
}


void mUrgDistance::laserOn(void)
{
  pimpl->urg_.laserOn();
}


void mUrgDistance::laserOff(void)
{
  pimpl->urg_.laserOff();
}
