#include "ModbusTKTransport.h"
#include "ZTData.h"
#include "ZTLog.h"
#include "EngLog.h"


CModbusTKTransport::CModbusTKTransport(CModbusRepository *CCRepo, CModbusRepository *SEIRepo)
{
    mMCCodbusRepo = CCRepo;
    mSEIModbusRepo = SEIRepo;
    mZT1CDVState = mZT2CDVState = false;
    mMaintenanceMode = mForceZT1Clear = mForceZT2Clear = false;
    mZT1TKDataList.clear();
    mZT2TKDataList.clear();
    mZT1CCClear = mZT2CCClear = mZT1SEIClear = mZT2SEIClear = false;
    mNewTrainIncoming = false;

    mModbusTKZT1SMState = MODBUS_ZT1_TK_STANDBY_STATE;
    mModbusTKZT2SMState = MODBUS_ZT2_TK_STANDBY_STATE;

    mZT1TKStateMachineTimer = new QTimer();
    mZT1TKStateMachineTimer->setSingleShot(false);
    mZT1TKStateMachineTimer->setInterval(0);
    connect(mZT1TKStateMachineTimer,SIGNAL(timeout()),this,SLOT(ExecZT1SM()));

    mZT2TKStateMachineTimer = new QTimer();
    mZT2TKStateMachineTimer->setSingleShot(false);
    mZT2TKStateMachineTimer->setInterval(0);
    connect(mZT2TKStateMachineTimer,SIGNAL(timeout()),this,SLOT(ExecZT2SM()));

    ResetAlarmCount(ZTGLOBAL_TYPE_ID);
}

CModbusTKTransport::~CModbusTKTransport()
{
    delete mZT1TKStateMachineTimer;
    delete mZT2TKStateMachineTimer;
}

int CModbusTKTransport::ClearTK(int ZT)
{

    if(ZT == ZT1_TYPE_ID)
    {
        //Fill ZT1 alarm regs with 0.
        QList<qint16> Data;
        for(int i = 0; i <= 16; i++) //17 registers (1 flags reg + 16 ranks regs)
        {
            Data.append(0);
        }

        //Clear pannes & itineraire flags
        bool OK = false;
        quint16 PannesReg = mMCCodbusRepo->GetSingleReg(MODBUS_MISC_DATA_BASE_REG_ADD,&OK);

        if(OK == false)
        {
            return RET_ERROR;
        }

        PannesReg &= ~ZT1_V00_ALARM_FLAG_MASK;
        PannesReg &= ~ZT1_PEQ1_ALARM_FLAG_MASK;

        //JFM 2018/10/30 Keep the ITI flag so we can generate secondary ITI alarms in maintenance mode.
        /// PannesReg &= ~ZT1_ALARM_ITI_FLAG_MASK;
        //

        //Clear repo now...
        mMCCodbusRepo->WriteMultipleRegs(MODBUS_ZT1_ALARM_DATA_BASE_REG_ADD,Data);
        mMCCodbusRepo->WriteSingleReg(MODBUS_MISC_DATA_BASE_REG_ADD,PannesReg);

        emit TKUpdated();


    }
    else if(ZT == ZT2_TYPE_ID)
    {
        //Fill ZT2 alarm regs with 0.
        QList<qint16> Data;
        for(int i = 0; i <= 8; i++) //9 registers (1 flags reg + 8 ranks regs)
        {
            Data.append(0);
        }

        //Clear pannes
        bool OK = false;
        quint16 PannesReg = mMCCodbusRepo->GetSingleReg(MODBUS_MISC_DATA_BASE_REG_ADD,&OK);

        if(OK == false)
        {
            return RET_ERROR;
        }

        PannesReg &= ~ZT2_V02_ALARM_FLAG_MASK;
        PannesReg &= ~ZT2_PEQ2_ALARM_FLAG_MASK;

        //Clear repo now...
        mMCCodbusRepo->WriteMultipleRegs(MODBUS_ZT2_ALARM_DATA_BASE_REG_ADD,Data);
        mMCCodbusRepo->WriteSingleReg(MODBUS_MISC_DATA_BASE_REG_ADD,PannesReg);
        emit TKUpdated();
    }
    else
    {
        return RET_ERROR;
    }

    return RET_OK;
}

int CModbusTKTransport::SendTKToCC(int ZT)
{
    if(ZT == ZT1_TYPE_ID)
    {
        int PPIntIndex = 0, PPExtIndex = 0, FNIndex = 0, PGIndex = 0;
        qint16 FlagsReg = 0;
        qint16 PannesReg;

        QList<qint16> DataBuf;

        //Get a local buffer of the repo...
        bool OK;
        DataBuf = mMCCodbusRepo->GetRegs(MODBUS_ZT_DATA_BASE_REG,MODBUS_ZT_TABLE_DATA_SIZE,&OK);
        if(OK == false)
        {
             CEngLog::instance()->AddLogString("Erreur de logique.  ModbusTkTransport::SendTKToCC() ZT1 -> Lecture repository invalide.");
        }


        PannesReg = DataBuf.at(RegOffset(MODBUS_MISC_DATA_BASE_REG_ADD));

        for(int i = 0; i < mZT1TKDataList.size(); i++)
        {
            CZTDetectionData TKData = mZT1TKDataList.at(i);

            switch(TKData.mDetectionID)
            {
                case DETECTION_MAGNETIC_SENSOR_COUNT:
                {
                    PannesReg |= ZT1_V00_ALARM_FLAG_MASK;
                    break;
                }
                case DETECTION_FN_DETECTION:
                {
                    if(FNIndex == 0)
                    {
                        FlagsReg |= ZT1_FN_FLAG_MASK_1;
                        DataBuf[RegOffset(MODBUS_ZT1_RANK_FN_1_REG_ADD)] = (qint16)TKData.mRank;
                    }
                    else if(FNIndex == 1)
                    {
                        FlagsReg |= ZT1_FN_FLAG_MASK_2;
                        DataBuf[RegOffset(MODBUS_ZT1_RANK_FN_2_REG_ADD)] = (qint16)TKData.mRank;
                    }
                    else if(FNIndex == 2)
                    {
                        FlagsReg |= ZT1_FN_FLAG_MASK_3;
                        DataBuf[RegOffset(MODBUS_ZT1_RANK_FN_3_REG_ADD)] = (qint16)TKData.mRank;
                    }
                    else if(FNIndex == 3)
                    {
                        FlagsReg |= ZT1_FN_FLAG_MASK_4;
                        DataBuf[RegOffset(MODBUS_ZT1_RANK_FN_4_REG_ADD)] = (qint16)TKData.mRank;
                    }
                    else
                    {
                        CEngLog::instance()->AddLogString("Erreur de logique.  ModbusTkTransport::SendTKToCC() -> FNIndex > 3");
                    }
                    FNIndex++;
                    break;
                }
                case DETECTION_PG_DETECTION:
                {
                    if(PGIndex == 0)
                    {
                        FlagsReg |= ZT1_PG_FLAG_MASK_1;
                        DataBuf[RegOffset(MODBUS_ZT1_RANK_PG_1_REG_ADD)] = (qint16)TKData.mRank;
                    }
                    else if(PGIndex == 1)
                    {
                        FlagsReg |= ZT1_PG_FLAG_MASK_2;
                        DataBuf[RegOffset(MODBUS_ZT1_RANK_PG_2_REG_ADD)] = (qint16)TKData.mRank;
                    }
                    else if(PGIndex == 2)
                    {
                        FlagsReg |= ZT1_PG_FLAG_MASK_3;
                        DataBuf[RegOffset(MODBUS_ZT1_RANK_PG_3_REG_ADD)] = (qint16)TKData.mRank;
                    }
                    else if(PGIndex == 3)
                    {
                        FlagsReg |= ZT1_PG_FLAG_MASK_4;
                        DataBuf[RegOffset(MODBUS_ZT1_RANK_PG_4_REG_ADD)] = (qint16)TKData.mRank;
                    }
                    else
                    {
                        CEngLog::instance()->AddLogString("Erreur de logique.  ModbusTkTransport::SendTKToCC() -> PGIndex > 3");
                    }
                    PGIndex++;
                    break;
                }
                case DETECTION_PPI_DETECTION:
                {
                    if(PPIntIndex == 0)
                    {
                        FlagsReg |= ZT1_PP_INT_FLAG_MASK_1;
                        DataBuf[RegOffset(MODBUS_ZT1_RANK_PP_INT_1_REG_ADD)] = (qint16)TKData.mRank;
                    }
                    else if(PPIntIndex == 1)
                    {
                        FlagsReg |= ZT1_PP_INT_FLAG_MASK_2;
                        DataBuf[RegOffset(MODBUS_ZT1_RANK_PP_INT_2_REG_ADD)] = (qint16)TKData.mRank;
                    }
                    else if(PPIntIndex == 2)
                    {
                        FlagsReg |= ZT1_PP_INT_FLAG_MASK_3;
                        DataBuf[RegOffset(MODBUS_ZT1_RANK_PP_INT_3_REG_ADD)] = (qint16)TKData.mRank;
                    }
                    else if(PPIntIndex == 3)
                    {
                        FlagsReg |= ZT1_PP_INT_FLAG_MASK_4;
                        DataBuf[RegOffset(MODBUS_ZT1_RANK_PP_INT_4_REG_ADD)] = (qint16)TKData.mRank;
                    }
                    else
                    {
                        CEngLog::instance()->AddLogString("Erreur de logique.  ModbusTkTransport::SendTKToCC() -> PPIntIndex ZT1 > 3");
                    }
                    PPIntIndex++;
                    break;
                }
                case DETECTION_PPE_DETECTION:
                {
                    if(PPExtIndex == 0)
                    {
                        FlagsReg |= ZT1_PP_EXT_FLAG_MASK_1;
                        DataBuf[RegOffset(MODBUS_ZT1_RANK_PP_EXT_1_REG_ADD)] = (qint16)TKData.mRank;
                    }
                    else if(PPExtIndex == 1)
                    {
                        FlagsReg |= ZT1_PP_EXT_FLAG_MASK_2;
                        DataBuf[RegOffset(MODBUS_ZT1_RANK_PP_EXT_2_REG_ADD)] = (qint16)TKData.mRank;
                    }
                    else if(PPExtIndex == 2)
                    {
                        FlagsReg |= ZT1_PP_EXT_FLAG_MASK_3;
                        DataBuf[RegOffset(MODBUS_ZT1_RANK_PP_EXT_3_REG_ADD)] = (qint16)TKData.mRank;
                    }
                    else if(PPExtIndex == 3)
                    {
                        FlagsReg |= ZT1_PP_EXT_FLAG_MASK_4;
                        DataBuf[RegOffset(MODBUS_ZT1_RANK_PP_EXT_4_REG_ADD)] = (qint16)TKData.mRank;
                    }
                    else
                    {
                        CEngLog::instance()->AddLogString("Erreur de logique.  ModbusTkTransport::SendTKToCC() -> PPExtIndex ZT1 > 3");
                    }
                    PPExtIndex++;
                    break;
                }
                case DETECTION_PEQ1_DETECTION:
                {
                    PannesReg |= ZT1_PEQ1_ALARM_FLAG_MASK;
                    break;
                }
            }
        }

        //Update the modbus repo to send the alarms...
        DataBuf[RegOffset(MODBUS_ZT1_ALARM_DATA_BASE_REG_ADD)] = FlagsReg;
        DataBuf[RegOffset(MODBUS_MISC_DATA_BASE_REG_ADD)] = PannesReg;
        mMCCodbusRepo->WriteMultipleRegs(MODBUS_ZT_DATA_BASE_REG,DataBuf);
        emit TKUpdated();

    }
    else if(ZT == ZT2_TYPE_ID)
    {
        int PPIntIndex = 0, PPExtIndex = 0;
        qint16 FlagsReg = 0;
        qint16 PannesReg;

        QList<qint16> DataBuf;

        //Get a local buffer of the repo...
        bool OK;
        DataBuf = mMCCodbusRepo->GetRegs(MODBUS_ZT_DATA_BASE_REG,MODBUS_ZT_TABLE_DATA_SIZE,&OK);
        if(OK == false)
        {
             CEngLog::instance()->AddLogString("Erreur de logique.  ModbusTkTransport::SendTKToCC() ZT2 -> Lecture repository invalide.");
        }

        PannesReg = DataBuf.at(RegOffset(MODBUS_MISC_DATA_BASE_REG_ADD));

        for(int i = 0; i < mZT2TKDataList.size(); i++)
        {
            CZTDetectionData TKData = mZT2TKDataList.at(i);

            switch(TKData.mDetectionID)
            {

                case DETECTION_PEQ2_DETECTION:
                {
                    PannesReg |= ZT2_PEQ2_ALARM_FLAG_MASK;
                    break;
                }
                case DETECTION_ZT2_MAGNETIC_SENSOR_COUNT:
                {
                    PannesReg |= ZT2_V02_ALARM_FLAG_MASK;
                    break;
                }
                case DETECTION_ZT2_PPI_DETECTION:
                {
                    if(PPIntIndex == 0)
                    {
                        FlagsReg |= ZT2_PP_INT_FLAG_MASK_1;
                        DataBuf[RegOffset(MODBUS_ZT2_RANK_PP_INT_1_REG_ADD)] = (qint16)TKData.mRank;
                    }
                    else if(PPIntIndex == 1)
                    {
                        FlagsReg |= ZT2_PP_INT_FLAG_MASK_2;
                        DataBuf[RegOffset(MODBUS_ZT2_RANK_PP_INT_2_REG_ADD)] = (qint16)TKData.mRank;
                    }
                    else if(PPIntIndex == 2)
                    {
                        FlagsReg |= ZT2_PP_INT_FLAG_MASK_3;
                        DataBuf[RegOffset(MODBUS_ZT2_RANK_PP_INT_3_REG_ADD)] = (qint16)TKData.mRank;
                    }
                    else if(PPIntIndex == 3)
                    {
                        FlagsReg |= ZT2_PP_INT_FLAG_MASK_4;
                        DataBuf[RegOffset(MODBUS_ZT2_RANK_PP_INT_4_REG_ADD)] = (qint16)TKData.mRank;
                    }
                    else
                    {
                        CEngLog::instance()->AddLogString("Erreur de logique.  ModbusTkTransport::SendTKToCC() -> PPIntIndex ZT2 > 3");
                    }
                    PPIntIndex++;
                    break;
                }
                case DETECTION_ZT2_PPE_DETECTION:
                {
                    if(PPExtIndex == 0)
                    {
                        FlagsReg |= ZT2_PP_EXT_FLAG_MASK_1;
                        DataBuf[RegOffset(MODBUS_ZT2_RANK_PP_EXT_1_REG_ADD)] = (qint16)TKData.mRank;
                    }
                    else if(PPExtIndex == 1)
                    {
                        FlagsReg |= ZT2_PP_EXT_FLAG_MASK_2;
                        DataBuf[RegOffset(MODBUS_ZT2_RANK_PP_EXT_2_REG_ADD)] = (qint16)TKData.mRank;
                    }
                    else if(PPExtIndex == 2)
                    {
                        FlagsReg |= ZT2_PP_EXT_FLAG_MASK_3;
                        DataBuf[RegOffset(MODBUS_ZT2_RANK_PP_EXT_3_REG_ADD)] = (qint16)TKData.mRank;
                    }
                    else if(PPExtIndex == 3)
                    {
                        FlagsReg |= ZT2_PP_EXT_FLAG_MASK_4;
                        DataBuf[RegOffset(MODBUS_ZT2_RANK_PP_EXT_4_REG_ADD)] = (qint16)TKData.mRank;
                    }
                    else
                    {
                        CEngLog::instance()->AddLogString("Erreur de logique.  ModbusTkTransport::SendTKToCC() -> PPExtIndex ZT2 > 3");
                    }
                    PPExtIndex++;
                    break;
                 }
            }
        }

         //Update the modbus repo to send the alarms...
        DataBuf[RegOffset(MODBUS_ZT2_ALARM_DATA_BASE_REG_ADD)] = FlagsReg;
        DataBuf[RegOffset(MODBUS_MISC_DATA_BASE_REG_ADD)] = PannesReg;
        mMCCodbusRepo->WriteMultipleRegs(MODBUS_ZT_DATA_BASE_REG,DataBuf);
        emit TKUpdated();

    }
    else
    {
        CEngLog::instance()->AddLogString("Erreur de logique.  ModbusTkTransport::SendTKToCC() -> Index de ZT invalide!!!");
        return RET_ERROR;
    }

    return RET_OK;
}




bool CModbusTKTransport::IsZT2TKProcessing()
{
    if(mModbusTKZT2SMState != MODBUS_ZT2_TK_STANDBY_STATE)
    {
        return true;
    }
    return false;
}

bool CModbusTKTransport::IsZT1TKProcessing()
{
    if(mModbusTKZT1SMState != MODBUS_ZT1_TK_STANDBY_STATE)
    {
        return true;
    }
    return false;
}
bool CModbusTKTransport::IsTKProcessing()
{
    if(IsZT1TKProcessing() || IsZT2TKProcessing())
        return true;

    return false;
}

int CModbusTKTransport::AddNewZT1Detection(CZTDetectionData Detection)
{
    mZT1TKDataList.append(Detection);
    return RET_OK;
}
int CModbusTKTransport::AddNewZT2Detection(CZTDetectionData Detection)
{
    mZT2TKDataList.append(Detection);
    return RET_OK;
}
unsigned int CModbusTKTransport::BeginTKEmission()
{

    if(mZT1TKDataList.size() > 0)
    {
        if(GetDetectionConfig()->mZTDetectionConfig[DETECTION_FCT_ZT1].TKActive == false)
        {
            mZT1TKDataList.clear();
        }
        else if(mModbusTKZT1SMState == MODBUS_ZT1_TK_STANDBY_STATE)
        {
            mModbusTKZT1SMState = MODBUS_ZT1_TK_SHOW_STATE;
            mZT1TKStateMachineTimer->start(0);
        }
        else if(mMaintenanceMode == true && mModbusTKZT1SMState == MODBUS_ZT1_TK_WAIT_FOR_CLEAR_STATE)
        {
            //When we are in maintenance mode and we are already sending the alarms, just add the new alarm to the modbus buffer.
            SendTKToCC(ZT1_TYPE_ID);
        }
    }


    if(mZT2TKDataList.size() > 0)
    {
        if(GetDetectionConfig()->mZTDetectionConfig[DETECTION_FCT_ZT2].TKActive == false)
        {
            mZT2TKDataList.clear();
        }
        else if(mModbusTKZT2SMState == MODBUS_ZT2_TK_STANDBY_STATE)
        {
            mModbusTKZT2SMState = MODBUS_ZT2_TK_SHOW_STATE;
            mZT2TKStateMachineTimer->start(0);
        }
        else if(mMaintenanceMode == true && mModbusTKZT2SMState == MODBUS_ZT2_TK_WAIT_FOR_CLEAR_STATE)
        {
            //In maintenance mode, just add the new alarm to the modbus buffer.
            SendTKToCC(ZT2_TYPE_ID);
        }
    }


    return RET_OK;
}
unsigned int CModbusTKTransport::SetInputStates(bool AN1State, bool ZT1CDVState, bool AN2State, bool ZT2CDVState)
{
    Q_UNUSED(AN2State)
    Q_UNUSED(AN1State)

    mZT1CDVState = ZT1CDVState;
    mZT2CDVState = ZT2CDVState;
    return RET_OK;
}

unsigned int CModbusTKTransport::ClearTKForNewTrain()
{
    if(mModbusTKZT1SMState == MODBUS_ZT1_TK_WAIT_FOR_CLEAR_STATE)
    {
        mNewTrainIncoming = true;
        return RET_OK;
    }

    mNewTrainIncoming = false;
    return RET_ERROR;
}

unsigned int CModbusTKTransport::CancelAllTK()
{

    ClearTK(ZT1_TYPE_ID);
    ClearTK(ZT2_TYPE_ID);

    mModbusTKZT1SMState = MODBUS_ZT1_TK_STANDBY_STATE;
    mModbusTKZT2SMState = MODBUS_ZT2_TK_STANDBY_STATE;

    mZT1TKDataList.clear();
    mZT2TKDataList.clear();


    //exec the SM once
    mZT1TKStateMachineTimer->start();
    mZT2TKStateMachineTimer->start();
    ResetAlarmCount(ZTGLOBAL_TYPE_ID);

    return RET_OK;
}

unsigned int CModbusTKTransport::CancelMaintenanceCurrentTK()
{
    int ret = RET_ERROR;

    if(mMaintenanceMode == false)
    {
        return ret;
    }

    if(mModbusTKZT1SMState == MODBUS_ZT1_TK_WAIT_FOR_CLEAR_STATE)
    {
        mForceZT1Clear = true;
        ret = RET_OK;
     }

    if(mModbusTKZT2SMState == MODBUS_ZT2_TK_WAIT_FOR_CLEAR_STATE)
    {
        mForceZT2Clear = true;
        ret = RET_OK;
    }

    return ret;

}

unsigned int CModbusTKTransport::ExitMaintenance()
{
    mMaintenanceMode = false;
    mForceZT1Clear = false;
    mForceZT2Clear = false;
    CancelAllTK();

    return RET_OK;
}

unsigned int CModbusTKTransport::EnterMaintenance()
{
    if(IsTKProcessing())
    {
        return RET_ERROR;
    }

    CancelAllTK();
    mMaintenanceMode = true;
    mForceZT1Clear = false;
    mForceZT2Clear = false;

    return RET_OK;
}

void CModbusTKTransport::ExecZT1SM()
{
    switch(mModbusTKZT1SMState)
    {
        case MODBUS_ZT1_TK_SHOW_STATE:
        {

            SendTKToCC(ZT1_TYPE_ID);  //Mise à jour de la table Modbus avec les données des alarmes actives.

            mModbusTKZT1SMState = MODBUS_ZT1_TK_WAIT_FOR_CLEAR_STATE;

            CZTLog::instance()->AddLogString("Émission des alarmes PCC",true);
            for(int i = 0; i < mZT1TKDataList.size(); i++)
            {
                LogTK(mZT1TKDataList.at(i));
            }

            if(mMaintenanceMode)
            {
                emit TKOutputStatesChanged(true,false);
            }

            break;
        }
        case MODBUS_ZT1_TK_WAIT_FOR_CLEAR_STATE:
        {
            if(mZT1CCClear == true || mZT1SEIClear == true || (mMaintenanceMode == true && mForceZT1Clear == true))
            {
                ClearTK(ZT1_TYPE_ID); //Remise à zéro des données d'alarmes dans la table modbus.

                mModbusTKZT1SMState = MODBUS_ZT1_TK_STANDBY_STATE;

                if(mMaintenanceMode == true)
                {
                    if(mForceZT1Clear == true)
                    {
                        mForceZT1Clear = false;
                        CZTLog::instance()->AddLogString("Acquitement manuel de la TK ZT1",true);
                    }
                    else
                    {
                        CZTLog::instance()->AddLogString("Acquitement ZTC ou FCYCLE détectée",true);
                    }

                    emit TKOutputStatesChanged(false,false);

                }
                else
                {
                    CZTLog::instance()->AddLogString("Acquitement ZTC ou FCYCLE détectée",true);
                }
            }
            else if(mZT1CDVState == false && mMaintenanceMode == false)
            {
                //The train has left... clear the alarms...
                CZTLog::instance()->AddLogString("Libération du CDV de quai ZT1.  Acquitement automatique des alarmes ZT1 au PCC",true);
                ClearTK(ZT1_TYPE_ID);
                mModbusTKZT1SMState = MODBUS_ZT1_TK_STANDBY_STATE;
            }
            else if(mNewTrainIncoming)
            {
                //A new train is incoming and is on the ZT CDV.  Clear the alarms
                CZTLog::instance()->AddLogString("Un nouveau train arrive en ZT1. Acquitement automatique des alarmes ZT1 au PCC",true);
                ClearTK(ZT1_TYPE_ID);
                mModbusTKZT1SMState = MODBUS_ZT1_TK_STANDBY_STATE;
                mNewTrainIncoming = false;
            }

            break;
        }
        case MODBUS_ZT1_TK_STANDBY_STATE:
        {
            mZT1TKDataList.clear();
            mZT1TKStateMachineTimer->stop();
            ResetAlarmCount(ZT1_TYPE_ID);
            mNewTrainIncoming = false;

//            //In maintenance mode, it is possible to have ZT2 events at the same time
//            //than ZT1.  So if any ZT2 events are waiting in the qeue, send them...
//            if(mMaintenanceMode)
//            {
//                if(mZT2TKDataList.size() > 0)
//                {
//                    BeginTKEmission();
//                }
//            }

            break;
        }
    }
}

void CModbusTKTransport::ExecZT2SM()
{
    switch(mModbusTKZT2SMState)
    {
        case MODBUS_ZT2_TK_SHOW_STATE:
        {

            SendTKToCC(ZT2_TYPE_ID);  //Mise à jour de la table Modbus avec les données des alarmes actives.

            mModbusTKZT2SMState = MODBUS_ZT2_TK_WAIT_FOR_CLEAR_STATE;

            CZTLog::instance()->AddLogString("Émission des alarmes PCC",true);
            for(int i = 0; i < mZT2TKDataList.size(); i++)
            {
                LogTK(mZT2TKDataList.at(i));
            }

            if(mMaintenanceMode)
            {
                emit TKOutputStatesChanged(false,true);
            }
            break;
        }
        case MODBUS_ZT2_TK_WAIT_FOR_CLEAR_STATE:
        {
            if(mZT2CCClear == true || mZT2SEIClear == true || (mMaintenanceMode == true && mForceZT2Clear == true))
            {
                ClearTK(ZT2_TYPE_ID); //Remise à zéro des données d'alarmes dans la table modbus.

                mModbusTKZT2SMState = MODBUS_ZT2_TK_STANDBY_STATE;

                if(mMaintenanceMode == true)
                {
                    if(mForceZT2Clear == true)
                    {
                        mForceZT2Clear = false;
                        CZTLog::instance()->AddLogString("Acquitement manuel de la TK ZT2",true);
                    }
                    else
                    {
                        CZTLog::instance()->AddLogString("Acquitement ZTC ou FCYCLE détectée",true);
                    }

                    emit TKOutputStatesChanged(false,false);

                }
                else
                {
                    CZTLog::instance()->AddLogString("Acquitement ZTC ou FCYCLE détectée",true);
                }
            }
            else if(mZT2CDVState == false && mMaintenanceMode == false)
            {
                //The train has left... clear the alarms...
                CZTLog::instance()->AddLogString("Libération du CDV N+1 ZT2.  Acquitement automatique des alarmes ZT2 au PCC",true);
                ClearTK(ZT2_TYPE_ID);
                mModbusTKZT2SMState = MODBUS_ZT2_TK_STANDBY_STATE;
            }

            break;
        }
        case MODBUS_ZT2_TK_STANDBY_STATE:
        {
            mZT2TKDataList.clear();
            mZT2TKStateMachineTimer->stop();
            ResetAlarmCount(ZT2_TYPE_ID);

//            //In maintenance mode, it is possible to have ZT1 events at the same time
//            //than ZT2.  So if any ZT1 events are waiting in the qeue, send them...
//            if(mMaintenanceMode)
//            {
//                if(mZT1TKDataList.size() > 0)
//                {
//                    BeginTKEmission();
//                }
//            }

            break;
        }
    }
}

void CModbusTKTransport::ModbusCCUpdated()
{
    qint16 ClearReg = mMCCodbusRepo->GetSingleReg(MODBUS_CC_AN_BASE_REG_ADD);
    mZT1CCClear = (ClearReg & (MODBUS_CC_FCYCLE_ZT1_FLAG_MASK)) != 0;
    mZT2CCClear = (ClearReg & (MODBUS_CC_FCYCLE_ZT2_FLAG_MASK)) != 0;
   // qDebug("ZT1Clr = %d",mZT1Clear);
}


void CModbusTKTransport::ModbusSEIClearUpdate(bool ZT1Clear, bool ZT2Clear)
{
    mZT1SEIClear = ZT1Clear;
    mZT2SEIClear = ZT2Clear;
}
