/* Blinker
   Copyright 2011-2019 Stefan Schuermans <stefan@blinkenarea.org>
   Copyleft GNU public license - http://www.gnu.org/copyleft/gpl.html
   a blinkenarea.org project */

#ifndef BLINKER_SENDERDEST_IMPL_H
#define BLINKER_SENDERDEST_IMPL_H

#include <string>

#include "Directory.h"
#include "File.h"
#include "Module.h"
#include "Sender.h"
#include "SenderDest.h"
#include "SettingFile.h"

namespace Blinker {

/**
 * @brief constructor
 * @param[in] sender owning sender object
 * @param[in] name destination name
 * @param[in] dirBase base directory
 */
template<typename ADDR, typename SOCK>
Sender<ADDR, SOCK>::Dest::Dest(Sender &sender, const std::string &name,
                               const Directory &dirBase):
  m_sender(sender),
  m_name(name),
  m_fileAddr(dirBase.getFile("addr")),
  m_pData(&sender.m_noFrameData)
{
  // set up
  getAddr();
}

/// destructor
template<typename ADDR, typename SOCK>
Sender<ADDR, SOCK>::Dest::~Dest()
{
  // send "no frame" protocol data to old address
  send(&m_sender.m_noFrameData);
}

/// check for update of configuration
template<typename ADDR, typename SOCK>
void Sender<ADDR, SOCK>::Dest::updateConfig()
{
  // address file was modified -> re-get address
  if (m_fileAddr.checkModified())
    getAddr();
}

/**
 * @brief set current protocol data
 * @param[in] pData protocol data to send to address (empty if unknown)
 */
template<typename ADDR, typename SOCK>
void Sender<ADDR, SOCK>::Dest::setProtoData(const std::string *pData)
{
  // remember new data
  m_pData = pData;

  // send new protocol data to current address
  send(m_pData);
}

/// (re-)get address
template<typename ADDR, typename SOCK>
void Sender<ADDR, SOCK>::Dest::getAddr()
{
  std::string strAddr;

  // send "no frame" protocol data to old address
  send(&m_sender.m_noFrameData);

  // get new address from file
  m_fileAddr.update();

  // send current protocol data to new address
  send(m_pData);
}

/**
 * @brief send protocol data to address
 * @param[in] pData protocol data to send to address (empty if unknown)
 */
template<typename ADDR, typename SOCK>
void Sender<ADDR, SOCK>::Dest::send(const std::string *pData)
{
  if (m_sender.m_pSock && m_fileAddr.m_valid && !pData->empty())
    m_sender.m_pSock->send(*pData, m_fileAddr.m_obj);
}

} // namespace Blinker

#endif // #ifndef BLINKER_SENDERDEST_IMPL_H

