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

  \author Satofumi KAMIMURA

  $Id: mCameraDevice.cpp 1426 2009-10-19 21:36:07Z satofumi $
*/

#include "mCameraDevice.h"
#include "CameraDevice.h"
#include "MonitorDataHandler.h"
#include "LogNameHolder.h"

using namespace qrk;
using namespace std;


struct mCameraDevice::pImpl
{
  CameraDevice camera_;
  ExecutionType::Type type_;
  MonitorDataHandler* handler_;


  pImpl(void) : type_(ExecutionType::object()->type())
  {
    if ((type_ == ExecutionType::Recording) ||
        (type_ == ExecutionType::Playback)) {
      string log_name = LogNameHolder::object()->name("mCameraDevice");
      handler_ = new MonitorDataHandler(log_name, type_);
    }
  }


  ~pImpl(void)
  {
    delete handler_;
  }


  const char* what(void) const
  {
    // エラーメッセージを記録し、再生できるようにする
    if ((type_ == ExecutionType::Recording) ||
        (type_ == ExecutionType::Playback)) {
      string error_message = camera_.what();
      handler_->fetch(error_message);
      return error_message.c_str();

    } else {
      return camera_.what();
    }
  }


  bool connect(void)
  {
    // connect() については、return 情報のみ管理する
    bool ret = false;
    if (type_ != ExecutionType::Playback) {
      ret = camera_.connect();
    }

    if ((type_ == ExecutionType::Recording) ||
        (type_ == ExecutionType::Playback)) {
      if (handler_->fetch(ret) < 0) {
        disconnect();
        return false;
      }
    }
    return ret;
  }


  void disconnect(void)
  {
    camera_.disconnect();
  }


  bool capture(const char* file_name)
  {
    // 記録タイミングとファイル名を管理する
    bool ret = false;
    if (type_ != ExecutionType::Playback) {
      ret = camera_.capture(file_name);
    }

    if ((type_ == ExecutionType::Recording) ||
        (type_ == ExecutionType::Playback)) {
      string name = file_name;
      handler_->fetch(name);
      handler_->fetch(ret);
    }
    return ret;
  }
};


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


mCameraDevice::~mCameraDevice(void)
{
}


const char* mCameraDevice::what(void) const
{
  return pimpl->what();
}


bool mCameraDevice::connect(void)
{
  return pimpl->connect();
}


void mCameraDevice::disconnect(void)
{
  return pimpl->disconnect();
}


void mCameraDevice::setCaptureSize(int width, int height)
{
  return pimpl->camera_.setCaptureSize(width, height);
}


bool mCameraDevice::capture(const char* file_name)
{
  return pimpl->capture(file_name);
}
