// $Header: https://oberon.oapd.inaf.it/shins/trunk/shins/src/motion_ctrl/niceCallback.h 3857 2022-03-24 17:11:52Z depa $

#pragma once

// STD LIB
#include <fstream>
#include <iostream>
#include <memory>

// BOOST
#include <boost/shared_ptr.hpp>
#include <boost/function.hpp>
// ICE
#include <IceUtil/Mutex.h>
#include <IceUtil/Monitor.h>

// TAN
#include "config.h"
// following header file necessary for cpp file to compile
#include <Nice/Property/BridgeMemFn.hh>
#include <Nice/Property/ActorMemFn.hh>
#include <Basda/Mocca/WheelServiceWorkerInterface.h>
#include <Nice/App/Application.h>
//#include <Nice/Log.h>
#include <Basda/ServiceState.h>
#include <Basda/ServiceStateMachine.h>

#include "obs_ctrl/os_sm.h"
//#include "indiIF.h"


class niceCallback
{
private:
static void sm_dev_in_position(boost::shared_ptr<osfsm::OSFsm>& _ptrStateMachine,
                        IceUtil::Mutex& _mtxStateMachine);
static void decrement_counter(int& _count, IceUtil::Mutex& _mtxCount);
static void increment_counter(int& _count, IceUtil::Mutex& _mtxCount);
static bool is_counter_zero(int& _count, IceUtil::Mutex& _mtxCount);
public:
boost::function<void(const Nice::Completion&)> m_cbFnTest;
niceCallback();
~niceCallback();

//inline void support_funct(boost::shared_ptr<indiIF>& _ptrIndiIF) {return _ptrIndiIF;}

// callback motion complete by name
static void callback_motion_complete(const Nice::Completion & _c,
                                     const std::string & id);
// updates state machine status
static void callback_motion_complete_SM(const Nice::Completion& _c,
                                 boost::shared_ptr<osfsm::OSFsm>& _ptrStateMachine,
                                 IceUtil::Mutex& _mtxStateMachine);
// updates value of indi property throug indiIF interface
//void callback_motion_complete_indi(const Basda::ServiceStateMachine& _state,
//                                   const std::string& _strDevAlias,
//                                   boost::shared_ptr<indiIF>& _ptrIndiIF);

// callback used in multiDevice
void callback_state_change(const Basda::ServiceStateMachine& _state,
                           boost::function<void (const Basda::ServiceStateMachine&,
                                                 const std::string&)>,
                           const std::string& _strDevAlias);

void callback_drot_move_absolute(const Nice::Completion& _c,
                                 boost::function<bool(void)>& _f);

static void callback_motion_complete_count(const Nice::Completion& _c, int& _count,
                                    IceUtil::Mutex& _mtxCount,
                                    boost::shared_ptr<IceUtil::Monitor<IceUtil::Mutex> >& _ptrMonSeq);
// template <typename T>
// void callback_device_move_to_reference(const Nice::Completion& _c, const T& _device)
// {
//   switch (_c.state())
//     {
//     case Nice::OK:
//       _device->moveHomeStart();
//       break;
//     default:
//       break;
//     }
// }

void callback_device_move_to_reference(const Nice::Completion& _c, const Basda::MoccaWheelServiceWorkerInterfacePtr _device);
// {
//   switch (_c.state())
//     {
//     case Nice::OK:
//       _device->moveHomeStart();
//       break;
//     default:
//       break;
//     }
// }
void callback_absolute_encoder_position(const double& _pos);
};
