// -*- C++ -*-
/*!
 * @file  CaptureTimedCameraImage.h
 * @brief Camera Capture Module using OpenCV
 * @date  $Date$
 *
 * $Id$
 */

#ifndef CAPTURETIMEDCAMERAIMAGE_H
#define CAPTURETIMEDCAMERAIMAGE_H

#include <rtm/Manager.h>
#include <rtm/DataFlowComponentBase.h>
#include <rtm/CorbaPort.h>
#include <rtm/DataInPort.h>
#include <rtm/DataOutPort.h>
#include <rtm/idl/BasicDataTypeSkel.h>
#include <rtm/idl/ExtendedDataTypesSkel.h>
#include <rtm/idl/InterfaceDataTypesSkel.h>
#include <cv.h>
#include <highgui.h>

// Service implementation headers
// <rtc-template block="service_impl_h">
#include "ImgSVC_impl.h"

// </rtc-template>

// Service Consumer stub headers
// <rtc-template block="consumer_stub_h">
#include "ImgStub.h"
// </rtc-template>

using namespace RTC;
using namespace Img;

typedef struct CameraParam_ {
  cv::Size imageSize;
  cv::Mat cameraMatrix;
  cv::Mat distCoeffs;
  cv::Mat map1, map2;
}CameraParam;

/*!
 * @class CaptureTimedCameraImage
 * @brief Camera Capture Module using OpenCV
 *
 */
class CaptureTimedCameraImage
  : public RTC::DataFlowComponentBase
{
 public:
  /*!
   * @brief constructor
   * @param manager Maneger Object
   */
  CaptureTimedCameraImage(RTC::Manager* manager);

  /*!
   * @brief destructor
   */
  ~CaptureTimedCameraImage();

  // <rtc-template block="public_attribute">
  
  // </rtc-template>

  // <rtc-template block="public_operation">
  
  // </rtc-template>

  /***
   *
   * The initialize action (on CREATED->ALIVE transition)
   * formaer rtc_init_entry() 
   *
   * @return RTC::ReturnCode_t
   * 
   * 
   */
   virtual RTC::ReturnCode_t onInitialize();

  /***
   *
   * The finalize action (on ALIVE->END transition)
   * formaer rtc_exiting_entry()
   *
   * @return RTC::ReturnCode_t
   * 
   * 
   */
   virtual RTC::ReturnCode_t onFinalize();

  /***
   *
   * The startup action when ExecutionContext startup
   * former rtc_starting_entry()
   *
   * @param ec_id target ExecutionContext Id
   *
   * @return RTC::ReturnCode_t
   * 
   * 
   */
  // virtual RTC::ReturnCode_t onStartup(RTC::UniqueId ec_id);

  /***
   *
   * The shutdown action when ExecutionContext stop
   * former rtc_stopping_entry()
   *
   * @param ec_id target ExecutionContext Id
   *
   * @return RTC::ReturnCode_t
   * 
   * 
   */
  // virtual RTC::ReturnCode_t onShutdown(RTC::UniqueId ec_id);

  /***
   * カメラデバイスのオープン、カメラパラメータの読み込
   * みを実行する．
   *
   * The activated action (Active state entry action)
   * former rtc_active_entry()
   *
   * @param ec_id target ExecutionContext Id
   *
   * @return RTC::ReturnCode_t
   * 
   * 
   */
   virtual RTC::ReturnCode_t onActivated(RTC::UniqueId ec_id);

  /***
   * カメラデバイスのクローズを実行する．
   *
   * The deactivated action (Active state exit action)
   * former rtc_active_exit()
   *
   * @param ec_id target ExecutionContext Id
   *
   * @return RTC::ReturnCode_t
   * 
   * 
   */
   virtual RTC::ReturnCode_t onDeactivated(RTC::UniqueId ec_id);

  /***
   * 画像のキャプチャを実行する．コンフィギュレーション
   * パラメータにより，レンズ歪補正を合わせて実行する．
   *
   * The execution action that is invoked periodically
   * former rtc_active_do()
   *
   * @param ec_id target ExecutionContext Id
   *
   * @return RTC::ReturnCode_t
   * 
   * 
   */
   virtual RTC::ReturnCode_t onExecute(RTC::UniqueId ec_id);

  /***
   * カメラデバイスのクローズ、パラメータのリセットを実
   * 行する．
   *
   * The aborting action when main logic error occurred.
   * former rtc_aborting_entry()
   *
   * @param ec_id target ExecutionContext Id
   *
   * @return RTC::ReturnCode_t
   * 
   * 
   */
   virtual RTC::ReturnCode_t onAborting(RTC::UniqueId ec_id);

  /***
   *
   * The error action in ERROR state
   * former rtc_error_do()
   *
   * @param ec_id target ExecutionContext Id
   *
   * @return RTC::ReturnCode_t
   * 
   * 
   */
  // virtual RTC::ReturnCode_t onError(RTC::UniqueId ec_id);

  /***
   *
   * The reset action that is invoked resetting
   * This is same but different the former rtc_init_entry()
   *
   * @param ec_id target ExecutionContext Id
   *
   * @return RTC::ReturnCode_t
   * 
   * 
   */
  // virtual RTC::ReturnCode_t onReset(RTC::UniqueId ec_id);
  
  /***
   *
   * The state update action that is invoked after onExecute() action
   * no corresponding operation exists in OpenRTm-aist-0.2.0
   *
   * @param ec_id target ExecutionContext Id
   *
   * @return RTC::ReturnCode_t
   * 
   * 
   */
  // virtual RTC::ReturnCode_t onStateUpdate(RTC::UniqueId ec_id);

  /***
   *
   * The action that is invoked when execution context's rate is changed
   * no corresponding operation exists in OpenRTm-aist-0.2.0
   *
   * @param ec_id target ExecutionContext Id
   *
   * @return RTC::ReturnCode_t
   * 
   * 
   */
  // virtual RTC::ReturnCode_t onRateChanged(RTC::UniqueId ec_id);


 protected:
  // <rtc-template block="protected_attribute">
  
  // </rtc-template>

  // <rtc-template block="protected_operation">
  
  // </rtc-template>

  // Configuration variable declaration
  // <rtc-template block="config_declare">
  /*!
   * 複数カメラが接続された環境でのカメラIDを指定する
   * - Name: カメラID camera_id
   * - DefaultValue: 0
   */
  int m_camera_id;
  /*!
   * 出力画像のカラー。グレースケール（GRAY）またはカラー
   * （RGB）から選択する。
   * - Name: 出力カラーフォーマット output_color_format
   * - DefaultValue: RGB
   * - Constraint: GRAY or RGB
   */
  std::string m_output_color_format;
  /*!
   * 
   * - Name:  camera_param_filename
   * - DefaultValue: camera.yml
   */
  std::string m_camera_param_filename;
  /*!
   * 
   * - Name:  undistortion_flag
   * - DefaultValue: 0
   */
  bool m_undistortion_flag;
  /*!
   * 起動時に自動で連続キャプチャを実行するフラグ。ただ
   * し、サービスポートから連続キャプチャのstart/stop指令があっ
   * た場合、サービスポート側が優先される。
   * - Name:  cap_continuous_flag
   * - DefaultValue: 1
   */
  bool m_cap_continuous_flag;
  // </rtc-template>

  // DataInPort declaration
  // <rtc-template block="inport_declare">
  
  // </rtc-template>


  // DataOutPort declaration
  // <rtc-template block="outport_declare">
  TimedCameraImage m_image;
  /*!
   * 出力される画像データ．コンフィギュレーションパラメ
   * ータによって歪補正後または補正前のどちらかの画像が出力
   * される．
   * - Type: Img::TimedCameraImage
   */
  OutPort<TimedCameraImage> m_imageOut;
  
  // </rtc-template>

  // CORBA Port declaration
  // <rtc-template block="corbaport_declare">
  /*!
   */
  RTC::CorbaPort m_CameraCaptureServicePortPort;
  
  // </rtc-template>

  // Service declaration
  // <rtc-template block="service_declare">
  /*!
   */
  CameraCaptureServiceSVC_impl m_CameraCaptureService;
  
  // </rtc-template>

  // Consumer declaration
  // <rtc-template block="consumer_declare">
  
  // </rtc-template>

 private:
  cv::VideoCapture cap;
  cv::Mat cap_img, nChannels_img;
  int width, height, depth, channels;
  CameraParam cam_param;
  // <rtc-template block="private_attribute">
  
  // </rtc-template>

  // <rtc-template block="private_operation">
  
  // </rtc-template>

};


extern "C"
{
  DLL_EXPORT void CaptureTimedCameraImageInit(RTC::Manager* manager);
};

#endif // CAPTURETIMEDCAMERAIMAGE_H
