// $Header$

#ifndef __ADCWORKERTHREAD_H__
#define __ADCWORKERTHREAD_H__ value

#include <cmath>

#include <pthread.h>

#include <Basda/ServiceStateMachine.h>
#include <Basda/Mocca/WheelServiceWorkerInterface.h>
#include <LbtoIIFInterface2.h>
#include <Ltcs/Iif/ServiceWorkerInterface.h>
#include <Ltcs/Iif/PropertyName.h>

#include "util/constants.h"
#include "util/shins_util.h"


namespace su = shins::util;
namespace suc = shins::util::constants;

class AdcWorkerThread // : public Nice::Thread
{
private:
    Basda::MoccaWheelServiceWorkerInterfacePtr m_adc1;
    Basda::MoccaWheelServiceWorkerInterfacePtr m_adc2;
    bool m_EndTask;
    bool m_bTaskEnded;
    double getAdc(double lbt_pressure, double lbt_temp, double elevation);
    Basda::ServiceStateMachine m_StateMachine;
    void WorkerThread();
    double m_CO;            // Constant Offset;
    double m_P0;            // Pressure Offset [mbar] (default=733)
    double m_P1;            // Pressure slope [arcsec/mbar] (for complete SHARK-NIR wavelength range P1 = 0.00063)
    double m_T0;            // Temperature Offset [K] (default 273.14);
    double m_T1;            // Temperature Slope [arcse/K] (for complete SHARK-NIR wavelength range T1 = -0.0018)
    double m_Adc1Ref;       // Starting Position for ADC1
    double m_Adc2Ref;       // Starting Position for ADC2
    double m_DrotRef;       // Reference Position for DROT
    double m_coRotation;    // Corotation Offset in DEGREE
    double m_counterRotation;// CounterRotation Offset in DEGREE
    int m_UpdateInterval;   // Interval in seconds between two automatic corrections;
    double m_TargetPos1;
    double m_TargetPos2;
    std::string m_TargetUnit;
    bool m_bSetPosition;
    Ice::PropertiesPtr m_props;

    bool m_bTest0, m_bTest1, m_bTest2, m_bTest3;

public:
    AdcWorkerThread(const Basda::MoccaWheelServiceWorkerInterfacePtr& _adc1,
                    const Basda::MoccaWheelServiceWorkerInterfacePtr& _adc2,
                    bool (* adccallback)(double & pressure, double & temperature, double & elevation, double & drot_pos),
                    Ice::PropertiesPtr m_props);
    ~AdcWorkerThread();
    void SetCorrectionParameters(double co, double p0, double p1, double t0, double t1);
//    void moveAbsoluteStart(double pos1, double pos2, std::string _unit);
//    void moveAbsoluteWait(Nice::Time _timeout);
    void SetMode(std::string mode);
    std::string GetMode();
    static void * run(void * pContext);
    bool (* m_adcCallback)(double & pressure, double & temperature, double & elevation, double & drot_pos);
    void setFlags(uint64_t flags, uint64_t more_flags);
    void unsetFlags(uint64_t flags, uint64_t more_flags);
    void toggleFlags(uint64_t flags, uint64_t more_flags);
    void setAdcCoRotationOffset(double corotation);
    void setAdcCounterRotationOffset(double counterrotation);
    double getCoRotation(){return m_coRotation;};
    double getCounterRotation(){ return m_counterRotation;};
};

// typedef IceUtil::Handle<AdcWorkerThread> AdcWorkerThreadPtr;

#endif
