// $Header: https://oberon.oapd.inaf.it/shins/trunk/shins/src/tcs_iif/iifApp.h 3983 2022-07-04 08:43:50Z depa $

#pragma once


#include <config.h>
#include <Nice/App/Application.h>
#include <Nice/App/ConfigClient.h>
//#include <Nice/Map/NPoint.h>
#include <Basda/Mocca/Constant.h>
// #include <Basda/Mocca/WheelServiceWorkerInterface.h>
#include <Ltcs/Iif/PropertyName.h>
#include <Ltcs/Iif/ServiceWorkerInterface.h>
#include <LbtoIIFInterface.h>

#include <fstream>
#include <iostream>
#include <iomanip>
#include <boost/typeof/typeof.hpp> // BOOST_AUTO

class iifApp : public Nice::Application
{
 public:
    iifApp(int argc, char* argv[])
    {
        Nice::Application::init ( argc, argv );
    }

    ~iifApp()
    {
       U8_LOG("iifApp::" << __FUNCTION__ << " ~ Goodbye");
       int status = EXIT_SUCCESS;
       status = Application::end(status);
    }


    /** @brief That method introduce the user how to start the application. It will be shown every time when the user called the application on a wrong way. */
    virtual int usage ( int );

    /** @brief The run method will be started through the main method. It keeps the motor control implementation. */
    virtual int run ( int argc, char* argv[] );


    /** @brief A call back method in order to terminate the application. */
    virtual void interruptCallback ( int _sig );

    int writeTrajOnFile(const Nice::SeqSeqDouble & _traj);

    template<typename IFTYPE> 
    IceUtil::Handle<IFTYPE> connect(const std::string & _alias)
    {
        Nice::Endpoint ep = Nice::Endpoint::fromString(std::string("[ALIAS=") + _alias + ", TIMEOUT=180]");
        U3_LOG("string : " << std::string("[ALIAS=") + _alias + ", TIMEOUT=180]" << "; Endpoint : " << ep);
        Nice::AppConfigClientPtr con =  Nice::AppConfigClient::connectWithEndpointAtNode ( ep, _alias );
        return  IFTYPE::create(_alias);
    }

private:
    Ltcs::IifServiceWorkerInterfacePtr m_iif;

    int PresetTelescopeNoAO(const lbto::position2& _target,
                            const lbto::position2& _guide,
                            const std::string& _telescopeMode);

    int PresetTelescopeWithAO(const lbto::position2& _target,
                              const lbto::position2& _guide,
                              const lbto::position2& _AOreference,
                              const std::string& _telescopeMode);

    int RunAO(const std::string& _AOmode);

    int SendWavefront(const lbto::SeqWF& _zernikeC);

    int MoveFocus(const std::string& _ope);

};
