#ifndef COSY_ShafTEncoder
#define COSY_ShafTEncoder

#ifndef COSY_NodeDrv
#include "nodedrv.h"
#endif

#ifndef MARS_MTime
#include "MTime.h"
#endif

class Macs;
class TGLabel;

enum Direction_t { kUndefined, kForward, kBackward };                                                    

class ShaftEncoder : public NodeDrv
{
private:
    LWORDS_t fPos;    // ticks
    WORDS_t  fVel;    // ticks per 5ms
    WORDS_t  fAcc;    // ticks per 25ms^2
    LWORD_t  fPosRes; // Number of ticks per revolution (resolution)
    WORD_t   fTurns;  // Number of possible turns

    TGLabel  *fLabel;     //
    LWORDS_t  fUpdPos;    // ticks

    bool fPosHasChanged;  //!
    bool fDirHasChanged;  //!

    MTime fTime;
    MLog *fReport;

    void HandlePDOType0(const BYTE_t *data, const timeval_t &tv);
    void HandlePDOType1(const BYTE_t *data, const timeval_t &tv);
    void HandlePDOType2(const BYTE_t *data, const timeval_t &tv);

    void ReqPos();

    void Init();
    void CheckConnection();
    // void CheckTwin(Int_t diff) const;

public:
    ShaftEncoder(const BYTE_t nodeid, const char *name=NULL);

    void StopDevice();

    void HandleSDO(WORD_t idx, BYTE_t subidx, LWORD_t val, const timeval_t &tv);
    void HandleSDOOK(WORD_t idx, BYTE_t subidx, LWORD_t data, const timeval_t &tv);

    void HandlePDO1(const BYTE_t *data, const timeval_t &tv) { HandlePDOType2(data, tv); }
    void HandlePDO2(const BYTE_t *data, const timeval_t &tv) { HandlePDOType2(data, tv); }

    double GetMjd();

    ClassDef(ShaftEncoder, 0)
};

#endif
