/*
 * seqITcs.hpp
 *
 *  Created on: Apr 6, 2022
 *      Author: fulvio
 */

#ifndef OBS_CTRL_SEQITCS_HPP_
#define OBS_CTRL_SEQITCS_HPP_

#include <string>

// LBTO IIF
#include <LbtoIIFInterface2.h>
#include <Ltcs/Iif/ServiceWorkerInterface.h>
#include <Ltcs/Iif/PropertyName.h>

#include "util/Macro.h"
#include "util/convert.h"
#include "util/shins_util.h"

#define EXIT_WARNING 2

namespace su = shins::util;

class SeqTcs
{
public:
    SeqTcs(Ice::PropertiesPtr prop);
    ~SeqTcs();

    Ltcs::IifServiceWorkerInterfacePtr & getIifInterface(){return m_iif_svc;};

    su::EServiceStatus Connect();
    bool CheckConnection(bool bThrow = true);
    void abortCommand();
// sequencerI calls:
    int BinocularControl(const std::string &_flag);
    int PresetTelescope(const std::map<std::string, std::string> &_telSup);
//    int PresetTelescopeWithAO(const lbto::position2 &_target, const lbto::position2 &_guide,
//        const lbto::position2 &_AOreference, const std::string &_telescopeMode, const std::string &_AOmode);
    int PresetTelescope(const lbto::SeqPos2 &_stars, const lbto::SeqPos2 & _refs, const std::string &_telescopeMode, const std::string &_AoMode);
    int SetNonSidereal(const lbto::nonsidereal & ns);
    int OffsetPointing(const std::map<std::string, std::string> &_tel_sup);
    int RunAO(const std::map<std::string, std::string> &_telSup);
    int SendWavefront(const lbto::SeqWF &_zernikeC, const std::string &_ope);
    int MoveFocus(double _absPos, const std::string &_ope);
    int OffsetZAO(double deltaZ, const std::string & side);
    int OffsetXYAO(double DeltaX, double DeltaY, const std::string & side);
    int ApplyWaffleAO(const std::map<std::string, std::string> &_telSup);
    int pointingCorrectionStart(Ice::Float _freq, Ice::Int &_thrdID);
    int pointingCorrectionStop(Ice::Int _thrdID);
    static const su::STcsPreset & GetPresetInformation();
    static lbto::result iifGetParameters(lbto::SeqDD);

    void setFlags(uint64_t flags, uint64_t more_flags)
    {
        if(flags & shins::flags::TCS_SINGLE_SIDE_MODE)
        {
            m_bSingleSideMode = true;
            U9_LLOG("Single Side Mode : ON");
        }
    };
    void unsetFlags(uint64_t flags, uint64_t more_flags)
    {
        if(flags & shins::flags::TCS_SINGLE_SIDE_MODE)
        {
            m_bSingleSideMode = false;
            U9_LLOG("Single Side Mode : OFF");
        }
    };
    void toggleFlags(uint64_t flags, uint64_t more_flags)
    {
        if(flags & shins::flags::TCS_SINGLE_SIDE_MODE)
        {
            m_bSingleSideMode = !m_bSingleSideMode;
            U9_LLOG("Single Side Mode : " << (m_bSingleSideMode ? "ON" : "OFF"));
        }
    };


private:
    static SeqTcs * m_pSeqTcs;
    Ltcs::IifServiceWorkerInterfacePtr m_iif_svc;
    bool m_bSingleSideMode;
    Nice::AppConfigClientPtr m_ConfigClient;
    su::EServiceStatus m_service_status;
    std::string m_service;

    void LogResult(const lbto::result & res, int line);
    IceUtil::Mutex m_TcsMutex;
    std::map<std::string, std::string> m_mapTcsKeywords;
    int ValidatePresetSetup(const std::map<std::string, std::string> & _telSetup);
    int IsReachable(bool except);
    bool m_BinocularLeftPreset, m_BinocularRightPreset;
    std::string m_leftTelescopeMode, m_rightTelescopeMode;
    std::string m_leftAoMode, m_rightAoMode;
    std::string m_ReferenceSide;
    std::string m_BinocularFlag;
    std::string m_TargetType;
    double m_TargetRaRate;
    double m_TargetDecRate;
    double m_TargetTime;
    std::string m_TargetFile;
    std::map<std::string, std::string> m_LeftPreset, m_RightPreset;
    lbto::SeqPos2 m_leftStars, m_leftRef, m_rightStars, m_rightRef;

    int ValidateOffsetSetup(const std::map<std::string, std::string> & _telSetup);
    std::map<std::string, std::string> m_LeftOffset, m_RightOffset;
    bool m_BinocularLeftOffset, m_BinocularRightOffset;
    double m_LeftOffsetX, m_LeftOffsetY, m_RightOffsetX, m_RightOffsetY;
    std::string m_LeftCoordSys, m_LeftMoveType, m_RightCoordSys, m_RightMoveType;
    su::STcsPreset m_TcsPreset;
};


#endif /* OBS_CTRL_SEQITCS_HPP_ */
