#ifndef SHAFTENCODER_H
#define SHAFTENCODER_H

#include "timer.h"
#include "nodedrv.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;
    LWORDS_t  fUpdPos;   // ticks
    WORDS_t   fUpdVel;   // ticks per 5ms
    WORDS_t   fUpdAcc;   // ticks per 25ms^2

    bool fPosHasChanged;

    Timer fTime;

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

    void ReqPos();

public:
    ShaftEncoder(const BYTE_t nodeid, const char *name=NULL, MLog &out=gLog);
    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, timeval_t *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, timeval_t *tv) { HandlePDOType2(data, tv); }
    void HandlePDO2(BYTE_t *data, timeval_t *tv) { HandlePDOType2(data, tv); }

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

    double GetTime();
    double GetMjd();

    void SetPreset(LWORD_t pre=0);

    void DisplayVal();

    bool PosHasChanged() const { return fPosHasChanged; }
    void ResetPosHasChanged() { fPosHasChanged = false; }

    ClassDef(ShaftEncoder, 0)
};

#endif
