/*******************************************************************************/
/*
    Description:
    Classe qui gère la communication Modbus avec la Commande Centralisée
    Elle sert à interpréter et construire les messages reçus ou destinés à la CC
*/

/* ************************************************************************** */
/* Revision:
### YYYMMDD JFM
    Verision d'origine.

### YYYYMMDD Description du besoin ou du bug
    Description du changement.
 */

/* ************************************************************************** */

#ifndef CMODBUSSLAVE_H
#define CMODBUSSLAVE_H

#include <QObject>
#include "ModbusBackend.h"
#include <QTcpServer>
#include "ModbusRepository.h"
#include <QTimer>

enum eModbusCCTrainTypes
{
    MODBUS_CC_TRAIN_TYPE_MR63 = 63,
    MODBUS_CC_TRAIN_TYPE_MR73 = 73,
    MODBUS_CC_TRAIN_TYPE_MPM10 = 10,
    MODBUS_CC_TRAIN_TYPE_MAINTENANCE = 0,
    MODBUS_CC_TRAIN_TYPE_INVALID_ATS_OFFLINE = 98,
    MODBUS_CC_TRAIN_TYPE_INVALID_SERVICE_REBOOT = 97,
    MODBUS_CC_TRAIN_TYPE_INVALID_NOT_UPDATED = 99,
    MODBUS_CC_TRAIN_TYPE_INVALID_SACL_OFFLINE = 96,

    MODBUS_CC_TRAIN_TYPE_MAX_VALUE
};


class CModbusCCMgr : public CModbusBackend
{
    Q_OBJECT
public:
    explicit CModbusCCMgr(CModbusRepository *Repo, int ModbusPort, int DevID);
    virtual ~CModbusCCMgr();

    int StartModbusCCServer();
    int CloseModbusCCServer();
    bool IsModbusConnected();
    static bool CheckForCCPartner(const int msTimeout, const int port);



    virtual void RegistersDatabaseUpdated(quint16 StartAddress, quint16 Length);
    virtual void ModbusRequestException(quint8 ExceptionCode, quint8 FctCode);



    //Helper functions
    QList<qint16> GetZT1TrainComposition();     //Retourne la composition du train actuelle pour ZT1
    QList<qint16> GetZT2TrainComposition();     //Retourne la composition du train actuelle pour ZT1
    bool GetZT1InhibitionFlag();    //Retourne l'état de l'inhibition de ZT1
    int ClearZT1InhibitionFlag();   //Désactive l'inhibition ZT1
    bool GetZT2InhibitionFlag();    //Retourne l'état de l'inhibition de ZT2
    int ClearZT2InhibitionFlag();   //Désactive l'inhibition ZT2
    qint16 GetZT1TrainType();       //Retourne le type de train actuel ZT1
    qint16 GetZT2TrainType();       //Retourne le type de train actuel ZT2
    qint16 GetZT1RawTrainType();       //Retourne le type de train
    qint16 GetZT2RawTrainType();       //Retourne le type de train
    int SetZTWatchdogEnabled(bool Enabled); //Permet de désactiver le Watchdog de la ZT (pour le mode entretien)
    int SetActivatedITI(int ITI);           //Fixe l'itinéraire ZT1 cheminé par le train pour en informer la CC
    
private:
    QTcpServer *mModbusServer;                      //L'instance du serveur TCP
    int mModbusPort;                                //Le port Modbus
    QTimer *mZTWatchdogTimer, *mCCWatchdogTimer;
    quint16 mZTWatchdog;
    qint16 mCCWatchdogState;        //Valeur du watchdog
    bool mCCLinkState;              //État du lien modbus, false lorsque le watchdog CC expire.
    QDateTime *mLastDateTime;
    bool mZTWatchdogEnabled;

    int ResetCCRepository();
    quint8 BCDToDecByte(const quint8 byte);
    quint16 BCDToDecWord(const quint16 word);

signals:
    void RepoHasChanged();
    void ModbusCCConnected(qint32 LocalIP, qint32 RemoteIP);
    void ModbusCCDisconnected();
    void ModbusCCLinkLost();
    void ModbusCCLinkRecovered();
    void ModbusDateTimeReceived(QDateTime *DateTime);
    
public slots:
    void NewModbusConnection();
    void ConnectionLost();
    void ModbusZTWatchdogTimeout();
    void ModbusCCWatchdogTimeout();
};

#endif // CMODBUSSLAVE_H
