
#include "DiscreteTKTransport.h"
#include "EngLog.h"
#include "ZTLog.h"
#include <QTextStream>
#include "ZTData.h"
#include <QTextCodec>

CDiscreteTKTransport::CDiscreteTKTransport()
{
   // mTKInterface = this;
    mOutputMasks = 0;
    mOutputModule = 0;


    mMaintenanceMode = false;
    mForceZT1Clear = false;
    mForceZT2Clear = false;


    mClearZT1AlarmMask = mClearZT2AlarmMask = 0;
    mAN1State = mZT1CDVState = mAN2State = mZT2CDVState = false;

    mZT1TKGeneratorState = TK_GENERATOR_ZT1_STANDBY_STATE;
    mZT2TKGeneratorState = TK_GENERATOR_ZT2_STANDBY_STATE;

//    mZT1TKBuffer.clear();
    mZT1TKDataList.clear();
//    mZT2TKBuffer.clear();
    mZT2TKDataList.clear();
    mZT1CurTKIndex = 0;
    mZT2CurTKIndex = 0;

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

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

    ResetAlarmCount(ZTGLOBAL_TYPE_ID);
}

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

void CDiscreteTKTransport::BindPointers(GenericOutputMasks_t *OutputMasks, COutputModule *OutputModule)
{
    mOutputMasks = OutputMasks;
    mOutputModule = OutputModule;



    mClearZT1AlarmMask = mOutputMasks->OutputVP1Mask | mOutputMasks->OutputVP2Mask | mOutputMasks->OutputVP3Mask | mOutputMasks->OutputVP4Mask |\
                         mOutputMasks->OutputVP5Mask | mOutputMasks->OutputVP6Mask | mOutputMasks->OutputVF1Mask | mOutputMasks->OutputVF2Mask |\
                         mOutputMasks->OutputVF3Mask | mOutputMasks->OutputVF4Mask | mOutputMasks->OutputVF5Mask | mOutputMasks->OutputDPEMask |\
                         mOutputMasks->OutputDPIMask | mOutputMasks->OutputV00Mask | mOutputMasks->OutputDPGMask | mOutputMasks->OutputDFRMask |\
                         mOutputMasks->OutputPEQ1Mask;

    mClearZT2AlarmMask = mOutputMasks->OutputWP1Mask | mOutputMasks->OutputWP2Mask | mOutputMasks->OutputWP3Mask | mOutputMasks->OutputWP4Mask |\
                         mOutputMasks->OutputWP5Mask | mOutputMasks->OutputWP6Mask | mOutputMasks->OutputDPI2Mask | mOutputMasks->OutputDPE2Mask |\
                         mOutputMasks->OutputV002Mask | mOutputMasks->OutputPEQ2Mask;
}

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

unsigned int CDiscreteTKTransport::BeginTKEmission()
{

    if(IsTKProcessing())
        return RET_ERROR;


//	if(IsZT1TKProcessing() == false)
    {
        if(mZT1TKDataList.size() > 0)
        {
            if(GetDetectionConfig()->mZTDetectionConfig[DETECTION_FCT_ZT1].TKActive == false)
            {
           //     mZT1TKBuffer.clear();
                mZT1TKDataList.clear();
            }
            else if(mZT1TKGeneratorState == TK_GENERATOR_ZT1_STANDBY_STATE)
            {
                mZT1TKGeneratorState = TK_ZT1_GENERATOR_SHOW_TK_STATE;
                mOutputModule->ClearOutputFlags(mClearZT1AlarmMask);	//make shure no TK was displayed to PCC
                mZT1TKStateMachineTimer->start(0);
            }
        }
    }

//	if(IsZT2TKProcessing() == false)
    {
        if(mZT2TKDataList.size() > 0)
        {
            if(GetDetectionConfig()->mZTDetectionConfig[DETECTION_FCT_ZT2].TKActive == false)
            {
            //    mZT2TKBuffer.clear();
                mZT2TKDataList.clear();
            }
            else if(mZT2TKGeneratorState == TK_GENERATOR_ZT2_STANDBY_STATE)
            {
                mZT2TKGeneratorState = TK_ZT2_GENERATOR_SHOW_TK_STATE;
                mOutputModule->ClearOutputFlags(mClearZT2AlarmMask);	//make shure no TK was displayed to PCC
                mZT2TKStateMachineTimer->start(0);
            }
        }
    }

    return RET_OK;
}

unsigned int CDiscreteTKTransport::SetInputStates(bool AN1State, bool ZT1CDVState, bool AN2State, bool ZT2CDVState)
{
    mAN1State = AN1State;
    mZT1CDVState = ZT1CDVState;
    mAN2State = AN2State;
    mZT2CDVState = ZT2CDVState;

    return RET_OK;
}


unsigned int CDiscreteTKTransport::ClearTKForNewTrain()
{
    return RET_OK;
}

void CDiscreteTKTransport::ExecZT1SM()
{
    switch(mZT1TKGeneratorState)
    {
        case TK_ZT1_GENERATOR_SHOW_TK_STATE:
        {
            if(mZT1CurTKIndex >= mZT1TKDataList.size())
            {
                mZT1TKGeneratorState = TK_GENERATOR_ZT1_STANDBY_STATE;
            }
            else
            {
                SendTKToCC(mZT1TKDataList.at(mZT1CurTKIndex++));
//                mOutputModule->SetOutputFlags(mZT1TKBuffer.at(mZT1CurTKIndex++));
                mZT1TKGeneratorState = TK_ZT1_GENERATOR_WAIT_FOR_AN1_STATE;

                CZTLog::instance()->AddLogString("Émission d'une TK ZT1 au PCC",true);
                LogTK(mZT1TKDataList.at(mZT1CurTKIndex-1));


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

            break;
        }
        case TK_ZT1_GENERATOR_WAIT_FOR_AN1_STATE:
        {
            if(mAN1State == true || (mMaintenanceMode == true && mForceZT1Clear == true))
            {
                //clear the TK bits
             //   mOutputModule->ClearOutputFlags(mClearZT1AlarmMask);
                ClearTK(ZT1_TYPE_ID);
                mZT1RefTimer.start();
                mZT1TKGeneratorState = TK_ZT1_GENERATOR_SHOW_ZERO_STATE;

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

                    emit TKOutputStatesChanged(false,false);

                }
                else
                {
                    CZTLog::instance()->AddLogString("Acquitement AN1 détectée",true);
                }
            }
            else if(mZT1CDVState == false && mMaintenanceMode == false)
            {
                //Enter the auto acquitment TK generation mode...
                //A TK is already output, make shure it's there long enough.
                CZTLog::instance()->AddLogString("Libération du CDV de quai ZT1.  Début de l'acquitement automatique",true);
                mZT1RefTimer.start();
                mZT1TKGeneratorState = TK_ZT1_GENERATOR_AUTO_WAIT_FOR_TIMEOUT_STATE;
            }

            break;
        }
        case TK_ZT1_GENERATOR_SHOW_ZERO_STATE:
        {
            if(mZT1RefTimer.elapsed() >= TK_GENERATOR_SHOW_ZERO_TIMEOUT)
            {
                mZT1TKGeneratorState = TK_ZT1_GENERATOR_SHOW_TK_STATE;
            }
            break;
        }
        case TK_ZT1_GENERATOR_AUTO_SHOW_TK_AUTO_STATE:
        {
            if(mZT1CurTKIndex >= mZT1TKDataList.size())
            {
                mZT1TKGeneratorState = TK_GENERATOR_ZT1_STANDBY_STATE;
            }
            else
            {
                //mOutputModule->SetOutputFlags(mZT1TKBuffer.at(mZT1CurTKIndex++));
                SendTKToCC(mZT1TKDataList.at(mZT1CurTKIndex++));
                mZT1RefTimer.start();
                mZT1TKGeneratorState = TK_ZT1_GENERATOR_AUTO_WAIT_FOR_TIMEOUT_STATE;
                CZTLog::instance()->AddLogString("Émission d'une TK ZT1 au PCC",true);
                LogTK(mZT1TKDataList.at(mZT1CurTKIndex-1));
            }
            break;
        }
        case TK_ZT1_GENERATOR_AUTO_WAIT_FOR_TIMEOUT_STATE:
        {
            if(mZT1RefTimer.elapsed() >= TK_GENERATOR_AUTOMATIC_SHOW_TK_TIMEOUT)
            {
                //mOutputModule->ClearOutputFlags(mClearZT1AlarmMask);
                ClearTK(ZT1_TYPE_ID);
                mZT1RefTimer.start();
                mZT1TKGeneratorState = TK_ZT1_GENERATOR_AUTO_SHOW_ZERO_STATE;
                CZTLog::instance()->AddLogString("Acquitement automatique TK ZT1",true);
            }
            break;
        }
        case TK_ZT1_GENERATOR_AUTO_SHOW_ZERO_STATE:
        {
            if(mZT1RefTimer.elapsed() >= TK_GENERATOR_SHOW_ZERO_TIMEOUT)
            {
                //emit next TK
                mZT1TKGeneratorState = TK_ZT1_GENERATOR_AUTO_SHOW_TK_AUTO_STATE;
            }
            break;
        }

        case TK_GENERATOR_ZT1_STANDBY_STATE:
        {
      //      mZT1TKBuffer.clear();
            mZT1TKDataList.clear();
            mZT1CurTKIndex = 0;
            mZT1TKStateMachineTimer->stop();
            ResetAlarmCount(ZTGLOBAL_TYPE_ID);

            //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 CDiscreteTKTransport::ExecZT2SM()
{
    switch(mZT2TKGeneratorState)
    {
        case TK_ZT2_GENERATOR_SHOW_TK_STATE:
        {
            if(mZT2CurTKIndex >= mZT2TKDataList.size())
            {
                mZT2TKGeneratorState = TK_GENERATOR_ZT2_STANDBY_STATE;
            }
            else
            {
         //       mOutputModule->SetOutputFlags(mZT2TKBuffer.at(mZT2CurTKIndex++));
                SendTKToCC(mZT2TKDataList.at(mZT2CurTKIndex++));
                mZT2TKGeneratorState = TK_ZT2_GENERATOR_WAIT_FOR_AN2_STATE;
                CZTLog::instance()->AddLogString("Émission d'une TK ZT2 au PCC",true);
                LogTK(mZT2TKDataList.at(mZT2CurTKIndex-1));
                if(mMaintenanceMode)
                {
                    emit TKOutputStatesChanged(false,true);
                }
            }
            break;
        }
        case TK_ZT2_GENERATOR_WAIT_FOR_AN2_STATE:
        {
            if(mAN2State == true || (mMaintenanceMode == true && mForceZT2Clear == true))
            {
                //clear the TK bits
              //  mOutputModule->ClearOutputFlags(mClearZT2AlarmMask);
                ClearTK(ZT2_TYPE_ID);
                mZT2RefTimer.start();
                mZT2TKGeneratorState = TK_ZT2_GENERATOR_SHOW_ZERO_STATE;
                if(mMaintenanceMode == true)
                {
                    if(mForceZT2Clear == true)
                    {
                        mForceZT2Clear = false;
                        CZTLog::instance()->AddLogString("Acquitement manuel de la TK ZT2",true);
                    }
                    else
                    {
                        CZTLog::instance()->AddLogString("Acquitement AN2 détectée",true);
                    }

                    emit TKOutputStatesChanged(false,false);
                }
                else
                {
                    CZTLog::instance()->AddLogString("Acquitement AN2 détectée",true);
                }
            }
            else if(mZT2CDVState ==  false && mMaintenanceMode == false)
            {
                //Enter the auto acquitment TK generation mode...
                //A TK is already output, make shure it's there long enough.
                CZTLog::instance()->AddLogString("Libération du CDV ZT2.  Début de l'acquitement automatique",true);
                mZT2RefTimer.start();
                mZT2TKGeneratorState = TK_ZT2_GENERATOR_AUTO_WAIT_FOR_TIMEOUT_STATE;
            }
            break;
        }
        case TK_ZT2_GENERATOR_SHOW_ZERO_STATE:
        {
            if(mZT2RefTimer.elapsed() >= TK_GENERATOR_SHOW_ZERO_TIMEOUT)
            {
                mZT2TKGeneratorState = TK_ZT2_GENERATOR_SHOW_TK_STATE;
            }
            break;
        }
        case TK_ZT2_GENERATOR_AUTO_SHOW_TK_AUTO_STATE:
        {
            if(mZT2CurTKIndex >= mZT2TKDataList.size())
            {
                mZT2TKGeneratorState = TK_GENERATOR_ZT2_STANDBY_STATE;
            }
            else
            {
              //  mOutputModule->SetOutputFlags(mZT2TKBuffer.at(mZT2CurTKIndex++));
                SendTKToCC(mZT2TKDataList.at(mZT2CurTKIndex++));
                mZT2RefTimer.start();
                mZT2TKGeneratorState = TK_ZT2_GENERATOR_AUTO_WAIT_FOR_TIMEOUT_STATE;
                CZTLog::instance()->AddLogString("Émission d'une TK ZT2 au PCC",true);
                //LogTK(mZT2TKBuffer.at(mZT2CurTKIndex-1));
                LogTK(mZT2TKDataList.at(mZT2CurTKIndex-1));
            }
            break;
        }
        case TK_ZT2_GENERATOR_AUTO_WAIT_FOR_TIMEOUT_STATE:
        {
            if(mZT2RefTimer.elapsed() >= TK_GENERATOR_AUTOMATIC_SHOW_TK_TIMEOUT)
            {
                //mOutputModule->ClearOutputFlags(mClearZT2AlarmMask);
                ClearTK(ZT2_TYPE_ID);
                mZT2RefTimer.start();
                mZT2TKGeneratorState = TK_ZT2_GENERATOR_AUTO_SHOW_ZERO_STATE;
                CZTLog::instance()->AddLogString("Acquitement automatique ZT2",true);
            }
            break;
        }
        case TK_ZT2_GENERATOR_AUTO_SHOW_ZERO_STATE:
        {
            if(mZT2RefTimer.elapsed() >= TK_GENERATOR_SHOW_ZERO_TIMEOUT)
            {
                //emit next TK
                mZT2TKGeneratorState = TK_ZT2_GENERATOR_AUTO_SHOW_TK_AUTO_STATE;
            }
            break;
        }

        case TK_GENERATOR_ZT2_STANDBY_STATE:
        {
      //      mZT2TKBuffer.clear();
            mZT2TKDataList.clear();
            mZT2CurTKIndex = 0;
            mZT2TKStateMachineTimer->stop();
            ResetAlarmCount(ZTGLOBAL_TYPE_ID);

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

            break;
        }
    }
}

quint32 CDiscreteTKTransport::IntegerToBCDZT1(quint32 Value)
{
    quint32 BCD = 0;

    if(Value >= 20)
    {
        BCD |= mOutputMasks->OutputVP6Mask;
        Value -= 20;
    }
    if(Value >= 10)
    {
        BCD |= mOutputMasks->OutputVP5Mask;
        Value -= 10;
    }

    if((Value & 1) != 0)
        BCD |= mOutputMasks->OutputVP1Mask;

    if((Value & 2) != 0)
        BCD |= mOutputMasks->OutputVP2Mask;

    if((Value & 4) != 0)
        BCD |= mOutputMasks->OutputVP3Mask;

    if((Value & 8) != 0)
        BCD |= mOutputMasks->OutputVP4Mask;

    return BCD;
}

quint32 CDiscreteTKTransport::IntegerToBCDFN(quint32 Value)
{
    quint32 BCD = 0;

    if(Value >= 10)
    {
        BCD |= mOutputMasks->OutputVF5Mask;
        Value -= 10;
    }

    if((Value & 1) != 0)
        BCD |= mOutputMasks->OutputVF1Mask;

    if((Value & 2) != 0)
        BCD |= mOutputMasks->OutputVF2Mask;

    if((Value & 4) != 0)
        BCD |= mOutputMasks->OutputVF3Mask;

    if((Value & 8) != 0)
        BCD |= mOutputMasks->OutputVF4Mask;

    return BCD;
}

quint32 CDiscreteTKTransport::IntegerToBCDZT2(quint32 Value)
{
    quint32 BCD = 0;

    if(Value >= 20)
    {
        BCD |= mOutputMasks->OutputWP6Mask;
        Value -= 20;
    }
    if(Value >= 10)
    {
        BCD |= mOutputMasks->OutputWP5Mask;
        Value -= 10;
    }

    if((Value & 1) != 0)
        BCD |= mOutputMasks->OutputWP1Mask;

    if((Value & 2) != 0)
        BCD |= mOutputMasks->OutputWP2Mask;

    if((Value & 4) != 0)
        BCD |= mOutputMasks->OutputWP3Mask;

    if((Value & 8) != 0)
        BCD |= mOutputMasks->OutputWP4Mask;

    return BCD;
}

unsigned int CDiscreteTKTransport::CancelAllTK()
{
    mOutputModule->ClearOutputFlags(mClearZT1AlarmMask);
    mOutputModule->ClearOutputFlags(mClearZT2AlarmMask);

    mZT1TKGeneratorState = TK_GENERATOR_ZT1_STANDBY_STATE;
    mZT2TKGeneratorState = TK_GENERATOR_ZT2_STANDBY_STATE;

   // mZT1TKBuffer.clear();
    mZT1TKDataList.clear();
  //  mZT2TKBuffer.clear();
    mZT2TKDataList.clear();


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

    return RET_OK;
}

unsigned int CDiscreteTKTransport::CancelMaintenanceCurrentTK()
{

    if(mZT1TKGeneratorState == TK_ZT1_GENERATOR_WAIT_FOR_AN1_STATE)
    {
        mForceZT1Clear = true;
        return RET_OK;
    }
    else if(mZT2TKGeneratorState == TK_ZT2_GENERATOR_WAIT_FOR_AN2_STATE)
    {
        mForceZT2Clear = true;
        return RET_OK;
    }
    return RET_ERROR;
}


unsigned int CDiscreteTKTransport::ExitMaintenance()
{
//	if(mMaintenanceMode == false)
//	{
//		return RET_ERROR;
//	}


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

    return RET_OK;
}

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

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

    return RET_OK;
}

bool CDiscreteTKTransport::IsTKProcessing()
{
    if(mZT1TKGeneratorState == TK_GENERATOR_ZT1_STANDBY_STATE &&
       mZT2TKGeneratorState == TK_GENERATOR_ZT2_STANDBY_STATE)
    {
        return false;
    }

    return true;
}

bool CDiscreteTKTransport::IsZT1TKProcessing()
{
    if(mZT1TKGeneratorState == TK_GENERATOR_ZT1_STANDBY_STATE)
    {
        return false;
    }

    return true;
}

bool CDiscreteTKTransport::IsZT2TKProcessing()
{
    if(mZT2TKGeneratorState == TK_GENERATOR_ZT2_STANDBY_STATE)
    {
        return false;
    }

    return true;
}

//void CDiscreteTKTransport::LogTK(CZTDetectionData DetectionData)
//{
//    QString str = "TK envoyée: ";
//    QTextStream stream(&str);
//    stream.setCodec("UTF-8");

//    stream << QString::fromUtf8(CZTData::GetErrorString(DetectionData.mDetectionID));
//    stream << " | Rang:  " << DetectionData.mRank;
//    CZTLog::instance()->AddLogString(str,true);
//}

//void CDiscreteTKTransport::LogTK(quint32 Value)
//{
//    QString str = "Output: ";
//    QTextStream stream(&str);

//    stream << "VP1 " <<
//              "VP2 " <<
//              "VP3 " <<
//              "VP4 " <<
//              "VP5 " <<
//              "VP6 " <<
//              "VF1 " <<
//              "VF2 " <<
//              "VF3 " <<
//              "VF4 " <<
//              "VF5 " <<
//              "WP1 " <<
//              "WP2 " <<
//              "WP3 " <<
//              "WP4 " <<
//              "WP5 " <<
//              "WP6 " <<
//              "DPE " <<
//              "DPI " <<
//              "V00 " <<
//              "DPG " <<
//              "DFR " <<
//              "RF  " <<
//              "RF2 " <<
//              "VEL " <<
//              "VEL2 " <<
//              "DPI2 " <<
//              "DPE2 " <<
//              "V002 " <<
//              "PEQ1 " <<
//              "PEQ2 " <<
//              "WDOG ";

//    CZTLog::instance()->AddLogString(str,true);
//    str.clear();

//    stream << "        " <<
//              " " << ((Value & mOutputMasks->OutputVP1Mask) != 0) << "  " <<
//              " " << ((Value & mOutputMasks->OutputVP2Mask) != 0) << "  " <<
//              " " << ((Value & mOutputMasks->OutputVP3Mask) != 0) << "  " <<
//              " " << ((Value & mOutputMasks->OutputVP4Mask) != 0) << "  " <<
//              " " << ((Value & mOutputMasks->OutputVP5Mask) != 0) << "  " <<
//              " " << ((Value & mOutputMasks->OutputVP6Mask) != 0) << "  " <<
//              " " << ((Value & mOutputMasks->OutputVF1Mask) != 0) << "  " <<
//              " " << ((Value & mOutputMasks->OutputVF2Mask) != 0) << "  " <<
//              " " << ((Value & mOutputMasks->OutputVF3Mask) != 0) << "  " <<
//              " " << ((Value & mOutputMasks->OutputVF4Mask) != 0) << "  " <<
//              " " << ((Value & mOutputMasks->OutputVF5Mask) != 0) << "  " <<
//              " " << ((Value & mOutputMasks->OutputWP1Mask) != 0) << "  " <<
//              " " << ((Value & mOutputMasks->OutputWP2Mask) != 0) << "  " <<
//              " " << ((Value & mOutputMasks->OutputWP3Mask) != 0) << "  " <<
//              " " << ((Value & mOutputMasks->OutputWP4Mask) != 0) << "  " <<
//              " " << ((Value & mOutputMasks->OutputWP5Mask) != 0) << "  " <<
//              " " << ((Value & mOutputMasks->OutputWP6Mask) != 0) << "  " <<
//              " " << ((Value & mOutputMasks->OutputDPEMask) != 0) << "  " <<
//              " " << ((Value & mOutputMasks->OutputDPIMask) != 0) << "  " <<
//              " " << ((Value & mOutputMasks->OutputV00Mask) != 0) << "  " <<
//              " " << ((Value & mOutputMasks->OutputDPGMask) != 0) << "  " <<
//              " " << ((Value & mOutputMasks->OutputDFRMask) != 0) << "  " <<
//              " "  << ((Value & mOutputMasks->OutputRFMask) != 0)  << "  " <<
//              " " << ((Value & mOutputMasks->OutputRF2Mask) != 0) << "  " <<
//              " " << ((Value & mOutputMasks->OutputVELMask) != 0) << "  " <<
//              "  " << ((Value & mOutputMasks->OutputVEL2Mask) != 0) << "  " <<
//              "  " << ((Value & mOutputMasks->OutputDPI2Mask) != 0) << "  " <<
//              "  " << ((Value & mOutputMasks->OutputDPE2Mask) != 0) << "  " <<
//              "  " << ((Value & mOutputMasks->OutputV002Mask) != 0) << "  " <<
//              "  " << ((Value & mOutputMasks->OutputPEQ1Mask) != 0) << "  " <<
//              "  " << ((Value & mOutputMasks->OutputPEQ2Mask) != 0) << "  " <<
//              "  " << ((Value & mOutputMasks->OutputWatchdogMask) != 0) << "  ";


//    CZTLog::instance()->AddLogString(str,true);

//}

int CDiscreteTKTransport::SendTKToCC(CZTDetectionData TKData)
{
    quint32 TKFlags = 0;
    quint32 Rank = TKData.mRank;


    switch(TKData.mDetectionID)
    {
        case DETECTION_MAGNETIC_SENSOR_COUNT:
        {

            TKFlags |= mOutputMasks->OutputV00Mask;
            TKFlags |= IntegerToBCDZT1(Rank);
            mOutputModule->SetOutputFlags(TKFlags);
            break;
        }
        case DETECTION_FN_DETECTION:
        {
            TKFlags |= mOutputMasks->OutputDFRMask;
            TKFlags |= IntegerToBCDFN(Rank);
            mOutputModule->SetOutputFlags(TKFlags);
            break;
        }
        case DETECTION_PG_DETECTION:
        {
            TKFlags |= mOutputMasks->OutputDPGMask;
            TKFlags |= IntegerToBCDZT1(Rank);
            mOutputModule->SetOutputFlags(TKFlags);
            break;
        }
        case DETECTION_PPI_DETECTION:
        {
            TKFlags |= mOutputMasks->OutputDPIMask;
            TKFlags |= IntegerToBCDZT1(Rank);
            mOutputModule->SetOutputFlags(TKFlags);
            break;
        }
        case DETECTION_PPE_DETECTION:
        {
            TKFlags |= mOutputMasks->OutputDPEMask;
            TKFlags |= IntegerToBCDZT1(Rank);
            mOutputModule->SetOutputFlags(TKFlags);
            break;
        }
        case DETECTION_PEQ1_DETECTION:
        {
            TKFlags |= mOutputMasks->OutputPEQ1Mask;
            TKFlags |= IntegerToBCDZT1(Rank);
            mOutputModule->SetOutputFlags(TKFlags);
            break;
        }
        case DETECTION_PEQ2_DETECTION:
        {
            TKFlags |= mOutputMasks->OutputPEQ2Mask;
            TKFlags |= IntegerToBCDZT2(Rank);
            mOutputModule->SetOutputFlags(TKFlags);
            break;
        }
        case DETECTION_ZT2_MAGNETIC_SENSOR_COUNT:
        {
            TKFlags |= mOutputMasks->OutputV002Mask;
            TKFlags |= IntegerToBCDZT2(Rank);
            mOutputModule->SetOutputFlags(TKFlags);

            break;
        }
        case DETECTION_ZT2_PPI_DETECTION:
        {
            TKFlags |= mOutputMasks->OutputDPI2Mask;
            TKFlags |= IntegerToBCDZT2(Rank);
            mOutputModule->SetOutputFlags(TKFlags);
            break;
        }
        case DETECTION_ZT2_PPE_DETECTION:
        {
            TKFlags |= mOutputMasks->OutputDPE2Mask;
            TKFlags |= IntegerToBCDZT2(Rank);
            mOutputModule->SetOutputFlags(TKFlags);
            break;
        }
    }

    return RET_OK;
}

int CDiscreteTKTransport::ClearTK(int ZT)
{
    if(ZT == ZT1_TYPE_ID)
    {
        mOutputModule->ClearOutputFlags(mClearZT1AlarmMask);
    }
    else if(ZT == ZT2_TYPE_ID)
    {
        mOutputModule->ClearOutputFlags(mClearZT2AlarmMask);
    }
    else
    {
        return RET_ERROR;
    }

    return RET_OK;
}
