#ifndef NODEDRV_H
#define NODEDRV_H

#include "log.h"
#include "gendef.h"

class Network;

class NodeDrv : public Log
{
private:
    Network *fNetwork;
    BYTE_t   fId;

    int fError;

protected:
    void SetError(int err) { fError = err; }
    void DelError()        { fError = 0; }
    int  GetError()        { return fError; }

public:
    NodeDrv(BYTE_t nodeid, ostream &out=cout);

    BYTE_t   GetId()      { return fId; }
    Network *GetNetwork() { return fNetwork; }

    virtual void InitDevice(Network *net);
    virtual void StopDevice() = 0;

    bool HasError()        { return fError; }

    virtual void HandleSDO(WORD_t idx, BYTE_t subidx, LWORD_t val, struct timeval *tv);
    virtual void HandleSDOOK(WORD_t idx, BYTE_t subidx);
    virtual void HandleSDOError(LWORD_t data);

    virtual void HandlePDO1(BYTE_t *data, struct timeval *tv) {};
    virtual void HandlePDO2(BYTE_t *data, struct timeval *tv) {};
    virtual void HandlePDO3(BYTE_t *data, struct timeval *tv) {};
    virtual void HandlePDO4(BYTE_t *data, struct timeval *tv) {};

    void SendPDO1(BYTE_t data[8]);
    void SendPDO2(BYTE_t data[8]);
    void SendPDO1(BYTE_t m0=0, BYTE_t m1=0, BYTE_t m2=0, BYTE_t m3=0,
                  BYTE_t m4=0, BYTE_t m5=0, BYTE_t m6=0, BYTE_t m7=0);
    void SendPDO2(BYTE_t m0=0, BYTE_t m1=0, BYTE_t m2=0, BYTE_t m3=0,
                  BYTE_t m4=0, BYTE_t m5=0, BYTE_t m6=0, BYTE_t m7=0);

    void SendSDO(WORD_t idx, BYTE_t subidx, BYTE_t val);
    void SendSDO(WORD_t idx, BYTE_t subidx, WORD_t val);
    void SendSDO(WORD_t idx, BYTE_t subidx, LWORD_t val);

    void SendSDO(WORD_t idx, BYTE_t val);
    void SendSDO(WORD_t idx, WORD_t val);
    void SendSDO(WORD_t idx, LWORD_t val=0);

    void SendNMT(BYTE_t cmd);

    void RequestSDO(WORD_t idx, BYTE_t subidx=0);

    void WaitForNextPdo1();
    void WaitForNextPdo2();
    void WaitForNextPdo3();
    void WaitForNextPdo4();

    void WaitForSdos();
    void WaitForSdo(WORD_t idx, BYTE_t subidx=0);

    void EnableCanMsg(BYTE_t fcode);
};

#endif
