#ifndef CLUSTER_DEVICE_HH
# define CLUSTER_DEVICE_HH

# include "Syslog.h"

# include "AbstractDevice.hh"

/** @brief Concrete device interface.
 *
 * @param Updater updating management class
 *
 * This class is a concrete device interface that implements
 * all the function of AbstractDevice bassed on informations provided by
 * Updater
 *
 * @pre Updater has to be derived from dummyUpdater
 *
 * @author Frederic Py <fpy@mbari.org>
 */
template<class Updater>
class Device :public AbstractDevice {
public:
  /** @brief devices data encapsulation type
   */
  typedef typename Updater::data_type data_type;

  void name(DeviceIF::Name id) {
//     m_dev->name(id);
    strcpy(id, m_name.c_str());
  }

  bool connected() {
    return m_dev->connected();
  }

  void update() {
    m_updater(*m_dev);
  }

  bool ready() {
    return m_updater.ready();
  }

  /** @brief get last update value.
   *
   * This method provides directly the data taken from Updater
   * on last update. It may be prefered on some cases to the
   * symbolic name association maps has it offers a direct
   * access to data. On the other hand using this method implies
   * a loss on flexibility.
   *
   * @return Last update datas
   */
  data_type const &data() const {
    return m_updater.data();
  }

  /** @brief Constructor
   *
   * @param name A device name
   *
   * Create a new instance and try to connect it
   * to device @e name
   */
  Device(std::pair<Symbol, ArgList const *> const &param) {
    Argument const &arg = param.second->get(param.first);
    m_name = param.first.c_str();


    if( arg.length()==1 ) {
      Syslog::write("Cluster: connecting to \"%s\"", m_name.c_str());
      m_dev = new device_type(m_name.c_str());
    } else {
      Syslog::write("Cluster: connecting to \"%s\" (%s)", 
		    m_name.c_str(), arg[1].c_str());
      m_dev = new device_type(m_name.c_str(), arg[1].c_str());
    }
    fillDB(m_updater);
  }
  
  /** @brief destructor
   *
   * disconnect the subjacent device
   */
  ~Device() {
    delete m_dev;
  }

private:
  /** @brief Subjacent device type.
   *
   * This type indicates what is the subjacent type of the interface
   */
  typedef typename Updater::device_type device_type;
  
  std::string m_name;

  /** @brief subjacent device interface */
  device_type *m_dev;
  /** @brief device updating mangement class */
  Updater m_updater;
 
}; // Device<>

#endif // CLUSTER_DEVICE_HH
