#include "INDIMotion.hpp"
#include <stdlib.h>


using pcf::IndiProperty;
using pcf::IndiElement;
using namespace pcf;
//using namespace std;
using namespace Ice;
using namespace boost::assign;


INDIMotion::INDIMotion(const std::string &szName,
		       const std::string &szDriverVersion,
		       const std::string &szProtocolVersion,
		       const std::string &svcPath,
  		       int argc, char* argv[])
  :IndiDriver(szName, szDriverVersion, szProtocolVersion)
{
  enableVerboseMode(true); 

  // configure for one log entry per line
  m_log.enableClearAfterLog( true );
  
  // set up the status property
  m_status = IndiProperty(IndiProperty::Text);
  m_status.setDevice(szName);
  m_status.setName("status");
  m_status.setPerm(IndiProperty::ReadOnly);
  m_status.setState(IndiProperty::Idle);
  m_status.add(IndiElement("value"));  

  m_cmdPos = IndiProperty(IndiProperty::Number);
  m_cmdPos.setDevice(szName);
  m_cmdPos.setName("cmdPos");
  m_cmdPos.setPerm(IndiProperty::ReadWrite);
  m_cmdPos.setState(IndiProperty::Idle);
  m_cmdPos.add(IndiElement("value"));  

  m_actualPos = IndiProperty(IndiProperty::Text);
  m_actualPos.setDevice(szName);
  m_actualPos.setName("actualPos");
  m_actualPos.setPerm(IndiProperty::ReadOnly);
  m_actualPos.setState(IndiProperty::Idle);
  m_actualPos.add(IndiElement("value"));  

  // initialize wheel application
  m_wheelApp = new wheelNiceApp(svcPath);
  std::cout << m_wheelApp->getSvcPath() << std::endl;
  m_log << "----Service path " << svcPath << "----" << std::endl;
  m_wheelApp->init(argc, argv);
  
  m_log << "---Costruttore fin qui ci siamo---" << std::endl;
}


INDIMotion::~INDIMotion()
{
  if (m_wheelApp != nullptr)
    delete m_wheelApp;
  //
}


void INDIMotion::handleGetProperties(const pcf::IndiProperty &ipRecv)
{
  // ignore if not our device
  if (ipRecv.hasValidDevice() && ipRecv.getDevice() != getName())
    return;
    
  
  // publish definition if want all properties or a specific one
  if (!ipRecv.hasValidName() || ipRecv.getName() == m_status.getName())
    sendDefProperty (m_status);
  if (!ipRecv.hasValidName() || ipRecv.getName() == m_cmdPos.getName())
    sendDefProperty (m_cmdPos);
  if (!ipRecv.hasValidName() || ipRecv.getName() == m_actualPos.getName())
    {
      int pos = -1;
      pos = m_wheelApp->getPosition();
      m_actualPos["value"] = pos;
      m_actualPos.setState (IndiProperty::Ok);
      sendSetProperty (m_actualPos);
      sendDefProperty (m_actualPos);     
    }
}


void INDIMotion::handleNewProperty( const pcf::IndiProperty &ipRecv )
{
  m_log << "** INDIMotion::handleNewProperty **" << std::endl;
  if (ipRecv.getName() == m_cmdPos.getName()) 
    {
      // received a new value for property m_cmdPos
      
      // extract value
      int v = ipRecv["value"];
      
      // fill
      m_cmdPos["value"] = v;  
      m_cmdPos.setState (IndiProperty::Ok);
      sendSetProperty (m_cmdPos);
      // INDI Property has been updated. The corresponding TAN service
      // has to be moved to the requested position TBD
      
      m_actualPos["value"] = "UNKNOWN";  // here should be the named position label
      m_actualPos.setState (IndiProperty::Ok);
      sendSetProperty (m_actualPos);

      m_status["value"] = m_wheelApp->runNamedPos(v);
      m_status.setState (IndiProperty::Ok);
      sendSetProperty(m_status);
    }
}

void INDIMotion::execute()
{
  // m_log << "merda" << std::endl;
  // log << pcf::Logger::enumInfo << "from execute" << std::endl;
}


std::string INDIMotion::getSvcPath()
{
  return m_wheelApp->getSvcPath();
}

