#ifndef SHAFTENCODER_H
#define SHAFTENCODER_H

#include "timer.h"
#include "nodedrv.h"

#include <pthread.h>

class TGLabel;

class ShaftEncoder : public NodeDrv
{
private:
    LWORDS_t fPos;   // ticks
    WORDS_t  fVel;   // ticks per 5ms
    WORDS_t  fAcc;   // ticks per 25ms^2
    WORDS_t  fTurn;  // Number of turn
    LWORD_t  fTicks; // Number of ticks per turn
    WORD_t   fTurns; // Number of possible turns

    TGLabel **fLabel;

    Timer fTime;

    pthread_t fThread;

    static void *MapUpdateThread(void *se);
    void UpdateThread();

    void HandlePDOType0(BYTE_t *data);
    void HandlePDOType1(BYTE_t *data);
    void HandlePDOType2(BYTE_t *data, struct timeval *tv);

    void ReqPos();

public:
    ShaftEncoder(BYTE_t nodeid, ostream &out=cout);
    virtual ~ShaftEncoder();

    void InitDevice(Network *);

    void StartDevice();
    void StopDevice();

    void SetDisplay(TGLabel **label) { fLabel = label; }

    void HandleSDO(WORD_t idx, BYTE_t subidx, LWORD_t val, struct timeval *tv);
    void HandleSDOOK(WORD_t idx, BYTE_t subidx) { NodeDrv::HandleSDOOK(idx, subidx); }
    void HandleSDOError(LWORD_t data)           { NodeDrv::HandleSDOError(data); }

    void HandlePDO1(BYTE_t *data, struct timeval *tv) { HandlePDOType2(data, tv); }
    void HandlePDO2(BYTE_t *data, struct timeval *tv) { HandlePDOType2(data, tv); }

    LWORDS_t GetPos() { return fPos+fTurn*fTicks; }

    double GetTime();
    double GetMjd();

    void SetPreset(LWORD_t pre=0);
};

#endif
