/*******************************************************************************
*                                                                              *
* Société de Transports de Montréal.                                    	   *
* 2012                                                                         *
*                                                                              *
* Projet Zones Tests                                                           *
*                                                                              *
*                                                                              *
*                                                                              *
*******************************************************************************/
/*
    Description:
	Page d'ingénierie.  Contient des information spécifique à l'ingénierie et
	permet d'éxécuter des tâches réservées à l'ingénierie.

*/

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

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

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


#include "EngineeringPage.h"
#include <QPainter>
#include "GlobalDefine.h"
#include <QDialog>
#include <QMainWindow>
#include "Zonetest.h"
#include <QDateTime>
#include <QFont>
#include <QTextCodec>
#include <QGraphicsProxyWidget>
#include <QDir>
#include <QMessageBox>
#include <QFont>
#include <QFrame>
#include "ZTLog.h"
#include "TrainLogFileMgr.h"
#include <QFileDialog>
#include <QTextStream>
#include "RamMonitor.h"

//#include <stdio.h>

CEngineeringPage::~CEngineeringPage()
{
    for(int Btn = 0; Btn < GENERIC_OUTPUT_NB_ID; Btn++)
        delete OutputToggleBtn[Btn];

    for(int led = 0; led < GENERIC_INPUT_NB_ID; led++)
        delete mInputLeds[led];

    for(int led = 0; led < mInputLedsCDV.size(); led++)
        delete mInputLedsCDV.at(led);

}

CEngineeringPage::CEngineeringPage(QGraphicsWidget *Parent)
{
	setParentItem(Parent);

	mProgramHandle = 0;
	mPCIIO = 0;
	mStation = 0;
	mDisablePassword = false;
    mInputMasks = 0;
    mCDVList = 0;

	mInputModulePtr = 0;

	mPasswordPrompt = new CPasswordPrompt(Parent);
	mPasswordPrompt->setZValue(1);
	mPasswordPrompt->hide();
	connect(mPasswordPrompt,SIGNAL(PasswordValid()),this,SLOT(PasswordValid()));
	connect(mPasswordPrompt,SIGNAL(Canceled()),this,SLOT(PasswordInvalid()));


	mBackgroundRect = new QGraphicsRectItem(boundingRect(), this);
    QBrush BackgroundBrush(QColor(245, 245, 255,200));
	mBackgroundRect->setBrush(BackgroundBrush);

	mCancelButton = new CTextButtonWidget("Fermer");
	mCancelButton->setParentItem(this);
	connect(mCancelButton,SIGNAL(TxtButtonClicked(CTextButtonWidget*)),this,SLOT(ButtonClicked(CTextButtonWidget*)));

	mConvertCSVButton = new CTextButtonWidget("Convertir .CSV");
	mConvertCSVButton->setParentItem(this);
    mConvertCSVButton->setPos(350,280);
	connect(mConvertCSVButton,SIGNAL(TxtButtonClicked(CTextButtonWidget*)),this,SLOT(ButtonClicked(CTextButtonWidget*)));


	mTestButton = new CTextButtonWidget("Test");
	mTestButton->setParentItem(this);
    mTestButton->setPos(350,310);
	connect(mTestButton,SIGNAL(TxtButtonClicked(CTextButtonWidget*)),this,SLOT(ButtonClicked(CTextButtonWidget*)));

    mModbusDataBtn = new CTextButtonWidget("Modbus");
    mModbusDataBtn->setParentItem(this);
    mModbusDataBtn->setPos(450,310);
    connect(mModbusDataBtn,SIGNAL(TxtButtonClicked(CTextButtonWidget*)),this,SLOT(ButtonClicked(CTextButtonWidget*)));


	mInfoUpdateTimer = new QTimer();
	mInfoUpdateTimer->setSingleShot(false);
	mInfoUpdateTimer->stop();
	connect(mInfoUpdateTimer,SIGNAL(timeout()),this,SLOT(UpdateInfo()));

	mRAMUsageText = new QGraphicsTextItem(this);
	mRAMUsageText->setPos(50,20);

	mPCIIODataText = new QGraphicsTextItem(this);
	mPCIIODataText->setPos(50,50);

	mExternalInputDataText = new QGraphicsTextItem(this);
    mExternalInputDataText->setPos(50,80);


    mIntLazerProbeValue = new QGraphicsTextItem(this);
    mIntLazerProbeValue->setPos(400,20);
    mIntLazerProbeValue->setPlainText("Sonde Lazer Int: ?");

    mExtLazerProbeValue = new QGraphicsTextItem(this);
    mExtLazerProbeValue->setPos(400,50);
    mExtLazerProbeValue->setPlainText("Sonde Lazer Ext: ?");

	mAnalogSDFValue = new QGraphicsTextItem(this);
    mAnalogSDFValue->setPos(600,20);
	mAnalogSDFValue->setPlainText("4-20mA SDF: ?");


	mExportZT1CSVChkBx = new QCheckBox("Exporter automatiquement CSV ZT1");
	QGraphicsProxyWidget *Proxy = new QGraphicsProxyWidget(this);
	Proxy->setWidget(mExportZT1CSVChkBx);
    Proxy->setPos(50,110);
	connect(mExportZT1CSVChkBx,SIGNAL(stateChanged(int)),this,SLOT(ZT1AutoCSVCheckBoxChanged(int)));

	mExportZT2CSVChkBx = new QCheckBox("Exporter automatiquement CSV ZT2");
	Proxy = new QGraphicsProxyWidget(this);
	Proxy->setWidget(mExportZT2CSVChkBx);
    Proxy->setPos(50,140);
	connect(mExportZT2CSVChkBx,SIGNAL(stateChanged(int)),this,SLOT(ZT2AutoCSVCheckBoxChanged(int)));

    mHighResLogging = new QCheckBox("Log haute resolution");
    Proxy = new QGraphicsProxyWidget(this);
    Proxy->setWidget(mHighResLogging);
    Proxy->setPos(50,170);
    connect(mHighResLogging,SIGNAL(stateChanged(int)),this,SLOT(HighResLogCheckBoxChanged(int)));

    mKeepAllMPM10Logs = new QCheckBox("Conserver tous les Logs MPM10");
    Proxy = new QGraphicsProxyWidget(this);
    Proxy->setWidget(mKeepAllMPM10Logs);
    Proxy->setPos(350,110);
    connect(mKeepAllMPM10Logs,SIGNAL(stateChanged(int)),this,SLOT(KeepAllMPM10LogsCheckBoxChanged(int)));

    mKeepZT1Logs = new QCheckBox("Conserver les Logs ZT1");
    Proxy = new QGraphicsProxyWidget(this);
    Proxy->setWidget(mKeepZT1Logs);
    Proxy->setPos(350,140);
    connect(mKeepZT1Logs,SIGNAL(stateChanged(int)),this,SLOT(KeepZT1LogsCheckBoxChanged(int)));

    mKeepZT2Logs = new QCheckBox("Conserver les Logs ZT2");
    Proxy = new QGraphicsProxyWidget(this);
    Proxy->setWidget(mKeepZT2Logs);
    Proxy->setPos(350,170);
    connect(mKeepZT2Logs,SIGNAL(stateChanged(int)),this,SLOT(KeepZT2LogsCheckBoxChanged(int)));


    QGraphicsTextItem *NbLogFilesLabel = new QGraphicsTextItem(this);
    NbLogFilesLabel->setPlainText("Nb. Max passages\nà conserver");
    NbLogFilesLabel->setPos(350,195);

    mNbLogFilesSpinBox = new QSpinBox();
    Proxy = new QGraphicsProxyWidget(this);
    Proxy->setWidget(mNbLogFilesSpinBox);
    Proxy->setPos(475,200);
    mNbLogFilesSpinBox->resize(70,30);
    mNbLogFilesSpinBox->setMinimum(1);
    mNbLogFilesSpinBox->setMaximum(1000);
    mNbLogFilesSpinBox->setValue(100);
    connect(mNbLogFilesSpinBox,SIGNAL(valueChanged(int)),this,SLOT(MaxNbLogFilesChanged(int)));


    mNbLogsText = new QGraphicsTextItem(this);
    mNbLogsText->setPlainText("");
    mNbLogsText->setPos(50,250);

    mDeleteLogsButton = new CTextButtonWidget("Effacer fichiers");
    mDeleteLogsButton->setParentItem(this);
    mDeleteLogsButton->setPos(50,280);
    connect(mDeleteLogsButton,SIGNAL(TxtButtonClicked(CTextButtonWidget*)),this,SLOT(ButtonClicked(CTextButtonWidget*)));

	mArchiveLogsButton = new CTextButtonWidget("Archiver fichiers");
	mArchiveLogsButton->setParentItem(this);
	mArchiveLogsButton->setPos(200,280);
	connect(mArchiveLogsButton,SIGNAL(TxtButtonClicked(CTextButtonWidget*)),this,SLOT(ButtonClicked(CTextButtonWidget*)));

	mDeleteEngLogBtn = new CTextButtonWidget("Détruire EngLog");
	mDeleteEngLogBtn->setParentItem(this);
	mDeleteEngLogBtn->setPos(50,310);
	connect(mDeleteEngLogBtn,SIGNAL(TxtButtonClicked(CTextButtonWidget*)),this,SLOT(ButtonClicked(CTextButtonWidget*)));

    mDeleteZTLogButton = new CTextButtonWidget("Détruire ZTLog");
    mDeleteZTLogButton->setParentItem(this);
    mDeleteZTLogButton->setPos(200,310);
    connect(mDeleteZTLogButton,SIGNAL(TxtButtonClicked(CTextButtonWidget*)),this,SLOT(ButtonClicked(CTextButtonWidget*)));


	mUSBFlashDetectionTxt = new QGraphicsTextItem(this);
	mUSBFlashDetectionTxt->setPos(50,340);
	mUSBFlashDetectionTxt->setPlainText("");

	mPGCalibrationSwitch = new CToggleButtonWidget("./Images/Slider_Green.png","./Images/Slider_Red.png",this,"Calibration PG");
    mPGCalibrationSwitch->setPos(730, 150);
	mPGCalibrationSwitch->resize(50,30);
	connect(mPGCalibrationSwitch,SIGNAL(ButtonToggled(CToggleButtonWidget*)),this,SLOT(PGCalibBtnToggled(CToggleButtonWidget*)));

	mPGTresholdValueSpinBox = new QSpinBox();
	Proxy = new QGraphicsProxyWidget(this);
	Proxy->setWidget(mPGTresholdValueSpinBox);
    Proxy->setPos(740,190);
	mPGTresholdValueSpinBox->resize(70,30);
	mPGTresholdValueSpinBox->setMinimum(1);
	mPGTresholdValueSpinBox->setMaximum(2000);
	mPGTresholdValueSpinBox->setValue(255);

	mPGNbPassagesForCalibSpinBox = new QSpinBox();
	Proxy = new QGraphicsProxyWidget(this);
	Proxy->setWidget(mPGNbPassagesForCalibSpinBox);
    Proxy->setPos(790,150);
	mPGNbPassagesForCalibSpinBox->resize(50,30);
	mPGNbPassagesForCalibSpinBox->setMinimum(1);
    mPGNbPassagesForCalibSpinBox->setMaximum(ZT_SM_MAX_NB_PG_CALIB_PASSAGES);
	mPGNbPassagesForCalibSpinBox->setValue(10);

	QGraphicsTextItem *Text = new QGraphicsTextItem(this);
    Text->setPos(845,140);
    Text->setPlainText("Passages\npour calibration ");

    mPGValueSetBtn = new CTextButtonWidget("Changer Seuil",0,30);
	mPGValueSetBtn->setParentItem(this);
    mPGValueSetBtn->setPos(820,190);
	connect(mPGValueSetBtn,SIGNAL(TxtButtonClicked(CTextButtonWidget*)),this,SLOT(ButtonClicked(CTextButtonWidget*)));

	mCopyCalibValueBtn = new CTextButtonWidget("Copier",0,30);
	mCopyCalibValueBtn->setParentItem(this);
    mCopyCalibValueBtn->setPos(780,230);
	connect(mCopyCalibValueBtn,SIGNAL(TxtButtonClicked(CTextButtonWidget*)),this,SLOT(ButtonClicked(CTextButtonWidget*)));
	mCopyCalibValueBtn->hide();

	Text = new QGraphicsTextItem(this);
    Text->setPos(710 - 80,190);
	Text->setPlainText("Valeur seuil PG: ");

	mCalibResultText = new QGraphicsTextItem(this);
    mCalibResultText->setPos(710 - 80,230);
	mCalibResultText->setPlainText("Valeur seuil PG calibration: Calib. non effectuée");

	mActualPGTresholdValueText = new QGraphicsTextItem(this);
    mActualPGTresholdValueText->setPos(710 - 80,260);


}

void CEngineeringPage::Init()
{
	QGraphicsTextItem *Label = new QGraphicsTextItem(this);
	QFont font;
	font.setPointSize(12);
	font.setBold(true);
	Label->setFont(font);

	Label->setPlainText("Contrôle manuel des TK (ATTENTION !!!)");
	QString ONPixmapFilePath = "./Images/Slider_Green.png";
	QString OFFPixmapFilePath = "./Images/Slider_Red.png";
	QSizeF SlideButtonSize(50,30);
	int OriginY = 400, OriginX = 90;
	int row = OriginY, col = OriginX;
	QString label;
	unsigned int ButtonData;
    mInputMasks = mStation->GetInputMasks();
    mCDVList = mStation->GetCDVList();
	GenericOutputMasks_t * OutputMasks = mStation->GetOutputMasks();
	Label->setPos(OriginX-30,OriginY-30);

	for(int Btn = 0; Btn < GENERIC_OUTPUT_NB_ID; Btn++)
	{
		switch(Btn)
		{
			case GENERIC_OUTPUT_VP1_ID:
			{
				label = "VP1";
				ButtonData = OutputMasks->OutputVP1Mask;
				break;
			}
			case GENERIC_OUTPUT_VP2_ID:
			{
				label = "VP2";
				ButtonData = OutputMasks->OutputVP2Mask;
				break;
			}
			case GENERIC_OUTPUT_VP3_ID:
			{
				label = "VP3";
				ButtonData = OutputMasks->OutputVP3Mask;
				break;
			}
			case GENERIC_OUTPUT_VP4_ID:
			{
				label = "VP4";
				ButtonData = OutputMasks->OutputVP4Mask;
				break;
			}
			case GENERIC_OUTPUT_VP5_ID:
			{
				label = "VP5";
				ButtonData = OutputMasks->OutputVP5Mask;
				break;
			}
			case GENERIC_OUTPUT_VP6_ID:
			{
                row += 40, col = OriginX;
				label = "VP6";
				ButtonData = OutputMasks->OutputVP6Mask;
				break;
			}
			case GENERIC_OUTPUT_DPE_ID:
			{
				label = "PPE";
				ButtonData = OutputMasks->OutputDPEMask;
				break;
			}
			case GENERIC_OUTPUT_DPI_ID:
			{
				label = "PPI";
				ButtonData = OutputMasks->OutputDPIMask;
				break;
			}
			case GENERIC_OUTPUT_V00_ID:
			{
				label = "V00";
				ButtonData = OutputMasks->OutputV00Mask;
				break;
			}
			case GENERIC_OUTPUT_VF1_ID:
			{
				label = "VF1";
				ButtonData = OutputMasks->OutputVF1Mask;
				break;
			}
			case GENERIC_OUTPUT_VF2_ID:
			{
				label = "VF2";
				ButtonData = OutputMasks->OutputVF2Mask;
                row += 40, col = OriginX;
				break;
			}
			case GENERIC_OUTPUT_VF3_ID:
			{
				label = "VF3";
				ButtonData = OutputMasks->OutputVF3Mask;
				break;
			}
			case GENERIC_OUTPUT_VF4_ID:
			{
				ButtonData = OutputMasks->OutputVF4Mask;
				label = "VF4";
				break;
			}
			case GENERIC_OUTPUT_VF5_ID:
			{
				label = "VF5";
				ButtonData = OutputMasks->OutputVF5Mask;
				break;
			}
			case GENERIC_OUTPUT_DPG_ID:
			{
				label = "DPG";
				ButtonData = OutputMasks->OutputDPGMask;
				break;
			}
			case GENERIC_OUTPUT_DFR_ID:
			{
                row += 40, col = OriginX;
				label = "DFR";
				ButtonData = OutputMasks->OutputDFRMask;
				break;
			}
			case GENERIC_OUTPUT_RF_ID:
			{
				label = "RF";
				ButtonData = OutputMasks->OutputRFMask;
				break;
			}
			case GENERIC_OUTPUT_VEL_ID:
			{
				label = "VEL";
				ButtonData = OutputMasks->OutputVELMask;
				break;
			}
			case GENERIC_OUTPUT_VEL2_ID:
			{
				label = "VEL2";
				ButtonData = OutputMasks->OutputVEL2Mask;
				break;
			}
			case GENERIC_OUTPUT_WP1_ID:
			{
				label = "WP1";
				ButtonData = OutputMasks->OutputWP1Mask;
				break;
			}
			case GENERIC_OUTPUT_WP2_ID:
			{
                row += 40, col = OriginX;
				label = "WP2";
				ButtonData = OutputMasks->OutputWP2Mask;
				break;
			}
			case GENERIC_OUTPUT_WP3_ID:
			{
				label = "WP3";
				ButtonData = OutputMasks->OutputWP3Mask;
				break;
			}
			case GENERIC_OUTPUT_WP4_ID:
			{
				label = "WP4";
				ButtonData = OutputMasks->OutputWP4Mask;
				break;
			}
			case GENERIC_OUTPUT_WP5_ID:
			{
				label = "WP5";
				ButtonData = OutputMasks->OutputWP5Mask;
				break;
			}
			case GENERIC_OUTPUT_WP6_ID:
			{
				label = "WP6";
				ButtonData = OutputMasks->OutputWP6Mask;
				break;
			}
			case GENERIC_OUTPUT_DPI2_ID:
			{
                row += 40, col = OriginX;
				label = "PPI2";
				ButtonData = OutputMasks->OutputDPI2Mask;
				break;
			}
			case GENERIC_OUTPUT_DPE2_ID:
			{
				label = "PPE2";
				ButtonData = OutputMasks->OutputDPE2Mask;
				break;
			}
			case GENERIC_OUTPUT_V002_ID:
			{
				label = "V002";
				ButtonData = OutputMasks->OutputV002Mask;
				break;
			}
			case GENERIC_OUTPUT_RF2_ID:
			{
				label = "RF2";
				ButtonData = OutputMasks->OutputRF2Mask;
				break;
			}
			case GENERIC_OUTPUT_PEQ1_ID:
			{
				label = "PEQ1";
				ButtonData = OutputMasks->OutputPEQ1Mask;
				break;
			}
			case GENERIC_OUTPUT_PEQ2_ID:
			{
                row += 40, col = OriginX;
				label = "PEQ2";
				ButtonData = OutputMasks->OutputPEQ2Mask;
				break;
			}
			case GENERIC_OUTPUT_WATCHDOG_ID:
			{
				label = "VIGIE";
				ButtonData = OutputMasks->OutputWatchdogMask;
				break;
			}
		}

		OutputToggleBtn[Btn] = new CToggleButtonWidget(ONPixmapFilePath,OFFPixmapFilePath,this,label);
		OutputToggleBtn[Btn]->setPos(col,row);
		OutputToggleBtn[Btn]->resize(SlideButtonSize);
		OutputToggleBtn[Btn]->SetData(ButtonData);
		connect(OutputToggleBtn[Btn],SIGNAL(ButtonToggled(CToggleButtonWidget*)),this,SLOT(OutputToggled(CToggleButtonWidget*)));
		col += 100;
	}

    OriginY = 400, OriginX = 580;
    row = OriginY, col = OriginX;

    Label = new QGraphicsTextItem(this);
    Label->setFont(font);
    Label->setPlainText("État des entrées");
    Label->setPos(OriginX + 10, OriginY - 30);



    for(int led = 0; led < GENERIC_INPUT_NB_ID; led++)
    {
        switch(led)
        {
            case GENERIC_INPUT_ZT1_S1_ID:
            {
                label = "ZT1 S1";
                break;
            }
            case GENERIC_INPUT_ZT1_S2_ID:
            {
                label = "ZT1 S2";
                break;
            }
            case GENERIC_INPUT_ZT1_PI_ID:
            {
                label = "ZT1 PI";
                break;
            }
            case GENERIC_INPUT_ZT1_PE_ID:
            {
                label = "ZT1 PE";
                break;
            }
            case GENERIC_INPUT_ZT1_FN_ID:
            {
                label = "ZT1 FN";
                break;
            }
            case GENERIC_INPUT_ZT2_S1_ID:
            {
                label = "ZT2 S1";
                break;
            }
            case GENERIC_INPUT_ZT2_PI_ID:
            {
                label = "ZT2 PI";
                break;
            }
            case GENERIC_INPUT_ZT2_PE_ID:
            {
                row += 60, col = OriginX;
                label = "ZT2 PE";
                break;
            }
            case GENERIC_INPUT_ZT1_ITI_ID:
            {
                label = "ZT1 ITI";
                break;
            }
            case GENERIC_INPUT_ZT2_ITI_ID:
            {
                label = "ZT2 ITI";
                break;
            }
            case GENERIC_INPUT_ZT1_AN_ID:
            {
                label = "ZT1 AN";
                break;
            }
            case GENERIC_INPUT_ZT2_AN_ID:
            {
                label = "ZT2 AN";
                break;
            }
            case GENERIC_INPUT_ZT1_ARF_ID:
            {
                label = "ZT1 ARF";
                break;
            }
            case GENERIC_INPUT_ZT2_ARF_ID:
            {
                label = "ZT2 ARF";
                break;
            }
            case GENERIC_INPUT_STATION_ID_0_ID:
            {
                row += 60, col = OriginX;
                label = "ID1";
                break;
            }
            case GENERIC_INPUT_STATION_ID_1_ID:
            {

                label = "ID2";
                break;
            }
            case GENERIC_INPUT_STATION_ID_2_ID:
            {
                label = "ID3";
                break;
            }
            case GENERIC_INPUT_STATION_ID_3_ID:
            {
                label = "ID4";
                break;
            }
        }

        mInputLeds[led] = new CLedWidget(label,this);
        mInputLeds[led]->setPos(col,row);

        col += 60;
    }

    row += 60, col = OriginX;

    for(int led = 0; led < mCDVList->size(); led++)
    {
        label = mCDVList->at(led)->GetLabel();

        CLedWidget *NewLedWidget = new CLedWidget(label,this);
        NewLedWidget->setPos(col,row);

        if((led+1)%7 == 0)
        {
            col = OriginX;
            row += 60;
        }
        else
        {
            col +=60;
        }

        mInputLedsCDV.append(NewLedWidget);
    }
}

void CEngineeringPage::BindPointers(CZoneTest *ProgramHandle,CInputModule *InputModulePtr, COutputModule *OutputModulePtr, CPCIIOMgr *PCIIO,CZTSettingsData *ZTSettings,CUSBDriveInterface *USBInterface,CStation *StationPtr,CAnalogInputModule *AnalogInterface)
{
	mProgramHandle = ProgramHandle;
	mInputModulePtr = InputModulePtr;
	mOutputModulePtr = OutputModulePtr;

	mAnalogInterface = AnalogInterface;


	mPCIIO = PCIIO;
	mZTSettings = ZTSettings;
	mUSBInterfacePtr = USBInterface;
	mStation = StationPtr;

	mAutoExportZT1CSV = mZTSettings->mAutoExportZT1CSV;
	mAutoExportZT2CSV = mZTSettings->mAutoExportZT2CSV;
	mExportZT1CSVChkBx->setChecked(mAutoExportZT1CSV);
	mExportZT2CSVChkBx->setChecked(mAutoExportZT2CSV);

	mPGTresholdValueSpinBox->setValue(mProgramHandle->GetPGTreshold());
	mPGCalibTresholdValue = mProgramHandle->GetPGTreshold();
	mActualPGTresholdValueText->setPlainText(QString().sprintf("Valeur seuil PG actuelle %d",mProgramHandle->GetPGTreshold()));
}

void CEngineeringPage::UpdateInfo()
{
	unsigned int PCIInputs = mPCIIO->GetInputs();
	QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"));
	QString String;
	QTextStream Stream(&String);

//	Stream.setPadChar('1');
//	Stream.setFieldAlignment(QTextStream::AlignRight);
	Stream.setCodec("UTF-8");
	Stream.setIntegerBase(16);
//	Stream.setFieldWidth(0);
	Stream << QString("Entrées PCI: [0x") << PCIInputs << "] : [0b";
	Stream.setIntegerBase(2);
//	Stream.setFieldWidth(16);
	Stream << PCIInputs << "]";

	mPCIIODataText->setPlainText(String);

    unsigned int ExtModuleInputs  = mInputModulePtr->GetInputs();

	String.clear();
	Stream.setIntegerBase(16);
//	Stream.setFieldWidth(0);
    Stream << QString("Entrées Externes: [0x") << ExtModuleInputs << "] : [0b";
	Stream.setIntegerBase(2);
//	Stream.setFieldWidth(32);
    Stream << ExtModuleInputs << "]";
	mExternalInputDataText->setPlainText(String);

	if(mUSBInterfacePtr->IsDriveDetected())
		mUSBFlashDetectionTxt->setPlainText(QString().sprintf("Clef USB détectée : %s",mUSBInterfacePtr->GetDrivePath().toLatin1().data()));
	else
		mUSBFlashDetectionTxt->setPlainText("Clef USB non détectée");

	long rss = CRamMonitor::instance()->GetRamUsage();
	mRAMUsageText->setPlainText(QString().sprintf("Utilisation RAM: %ld [%ldk]",rss,rss/1024));

	double reading;

	if(mAnalogInterface != 0)
    {
		mAnalogInterface->GetAnalogInput(mStation->GetAnalogAcqChannels()->SDFAcquisitionChannel,reading);
//        float value = (float)reading;
//		value -= 32767/2;
//        value *= 10;
//		value /= 32767/2;
		mAnalogSDFValue->setPlainText(QString().sprintf("4-20mA SDF: %f",reading));
    }

    mInputLeds[GENERIC_INPUT_ZT1_S1_ID]->SetLed((PCIInputs & mInputMasks->InputZT1S1Mask) != 0);
    mInputLeds[GENERIC_INPUT_ZT1_S2_ID]->SetLed((PCIInputs & mInputMasks->InputZT1S2Mask) != 0);
    mInputLeds[GENERIC_INPUT_ZT1_PI_ID]->SetLed((PCIInputs & mInputMasks->InputZT1PIMask) != 0);
    mInputLeds[GENERIC_INPUT_ZT1_PE_ID]->SetLed((PCIInputs & mInputMasks->InputZT1PEMask) != 0);
    mInputLeds[GENERIC_INPUT_ZT1_FN_ID]->SetLed((PCIInputs & mInputMasks->InputZT1FNMask) != 0);
    mInputLeds[GENERIC_INPUT_ZT2_S1_ID]->SetLed((PCIInputs & mInputMasks->InputZT2S1Mask) != 0);
    mInputLeds[GENERIC_INPUT_ZT2_PI_ID]->SetLed((PCIInputs & mInputMasks->InputZT2PIMask) != 0);
    mInputLeds[GENERIC_INPUT_ZT2_PE_ID]->SetLed((PCIInputs & mInputMasks->InputZT2PEMask) != 0);
    mInputLeds[GENERIC_INPUT_ZT1_ITI_ID]->SetLed((ExtModuleInputs & mInputMasks->InputZT1ITIMask) != 0);
    mInputLeds[GENERIC_INPUT_ZT2_ITI_ID]->SetLed((ExtModuleInputs & mInputMasks->InputZT2ITIMask) != 0);
    mInputLeds[GENERIC_INPUT_ZT1_AN_ID]->SetLed((ExtModuleInputs & mInputMasks->InputZT1ANMask) != 0);
    mInputLeds[GENERIC_INPUT_ZT2_AN_ID]->SetLed((ExtModuleInputs & mInputMasks->InputZT2ANMask) != 0);
    mInputLeds[GENERIC_INPUT_ZT1_ARF_ID]->SetLed((ExtModuleInputs & mInputMasks->InputZT1ARFMask) != 0);
    mInputLeds[GENERIC_INPUT_ZT2_ARF_ID]->SetLed((ExtModuleInputs & mInputMasks->InputZT2ARFMask) != 0);
    mInputLeds[GENERIC_INPUT_STATION_ID_0_ID]->SetLed((ExtModuleInputs & STATION_KEY_ID_0_MASK) != 0);
    mInputLeds[GENERIC_INPUT_STATION_ID_1_ID]->SetLed((ExtModuleInputs & STATION_KEY_ID_1_MASK) != 0);
    mInputLeds[GENERIC_INPUT_STATION_ID_2_ID]->SetLed((ExtModuleInputs & STATION_KEY_ID_2_MASK) != 0);
    mInputLeds[GENERIC_INPUT_STATION_ID_3_ID]->SetLed((ExtModuleInputs & STATION_KEY_ID_3_MASK) != 0);

    for(int led = 0; led < mCDVList->size(); led++)
    {
        mInputLedsCDV.at(led)->SetLed(!mCDVList->at(led)->IsOccupied());
    }


	#ifdef OUTPUT_EXTIO_SAMPLE_RATE

	long int sampletime = mExtIOInterface->GetSampleRate();
	float samplerate = 1/((float)sampletime / 1000);
	qDebug("ExtIO Sample rate: %ld, %f",sampletime,samplerate);
	#endif
}

void CEngineeringPage::resizeEvent(QGraphicsSceneResizeEvent *event)
{
	Q_UNUSED(event)
	mBackgroundRect->setRect(boundingRect());
	mCancelButton->setPos(50,boundingRect().height()-50);
}

void CEngineeringPage::ButtonClicked(CTextButtonWidget *BtnPtr)
{
	if(BtnPtr == mCancelButton)
	{
		mProgramHandle->CloseEngineeringPageRequest();
	}
    else if(BtnPtr == mDeleteLogsButton)
    {
        DeleteAllLogs();
    }
	else if(BtnPtr == mArchiveLogsButton)
	{
		if(mUSBInterfacePtr->IsDriveDetected() == false)
		{
			QMessageBox MsgBox;
			MsgBox.setText("Veuillez insérer une clef USB");
			MsgBox.exec();
		}
		else
		{
			ArchiveLogFiles();
		}
	}
	else if(BtnPtr == mPGValueSetBtn)
	{
		CZTLog::instance()->AddLogString(QString().sprintf("Seuil PG changé. Ancien: %d, Nouveau: %d",mProgramHandle->GetPGTreshold(),mPGTresholdValueSpinBox->value()),true);
		mProgramHandle->SetPGTreshold(mPGTresholdValueSpinBox->value());
		mActualPGTresholdValueText->setPlainText(QString().sprintf("Valeur seuil PG actuelle %d",mProgramHandle->GetPGTreshold()));
	}
	else if(BtnPtr == mCopyCalibValueBtn)
	{
		mPGTresholdValueSpinBox->setValue(mPGCalibTresholdValue);
	}
	else if(BtnPtr == mConvertCSVButton)
	{
		QString FilePath = QFileDialog::getOpenFileName(0, tr("Fichier de passage"), "./Trains", tr("Passages (*.csv)"));

		if(FilePath.isEmpty() == false)
		{
			CTrainLogFileMgr::instance()->SaveBINFromCSV(FilePath);
		}

	}
    else if(BtnPtr == mDeleteEngLogBtn)
	{
		CEngLog::instance()->DeleteEngLogFile();
	}
    else if(BtnPtr == mDeleteZTLogButton)
    {
        CZTLog::instance()->DeleteLogFile();
    }
	else if(BtnPtr == mTestButton)
	{
	}
    else if(BtnPtr == mModbusDataBtn)
    {
        mProgramHandle->OpenModbusDataPageRequest();
    }
}

void CEngineeringPage::showEvent(QShowEvent *event)
{
	Q_UNUSED(event)
	UpdateInfo();
	mInfoUpdateTimer->start(1000);
    RefreshLogsList();
    mActualPGTresholdValueText->setPlainText(QString().sprintf("Valeur seuil PG actuelle %d",mProgramHandle->GetPGTreshold()));
    mPGTresholdValueSpinBox->setValue(mProgramHandle->GetPGTreshold());
}
void CEngineeringPage::hideEvent(QHideEvent *event)
{
	Q_UNUSED(event)
	mInfoUpdateTimer->stop();
}

void CEngineeringPage::ShowPage()
{
	if(mDisablePassword == true)
	{
		show();
		CZTLog::instance()->AddLogString("Page d'ingénierie, mot de passe désactivé.  Ouverture de la page",true);
	}
	else
	{
		mPasswordPrompt->RequestPassword();
		CZTLog::instance()->AddLogString("Page d'ingénierie, demande du mot de passe");
	}
}

void CEngineeringPage::PasswordValid()
{
	mPasswordPrompt->hide();
	CZTLog::instance()->AddLogString("Page d'ingénierie, mot de passe valide.  Ouverture de la page",true);
	show();
}

void CEngineeringPage::PasswordInvalid()
{
	mPasswordPrompt->hide();
	mProgramHandle->CloseEngineeringPageRequest();
	CZTLog::instance()->AddLogString("Mot de passe invalide",true);
}

void CEngineeringPage::ZT1AutoCSVCheckBoxChanged(int state)
{
	if(state == Qt::Checked)
		mAutoExportZT1CSV = true;
	else if(state == Qt::Unchecked)
		mAutoExportZT1CSV = false;

	mProgramHandle->SaveAutoExportCSVSettings(mAutoExportZT1CSV,mAutoExportZT2CSV);
}

void CEngineeringPage::ZT2AutoCSVCheckBoxChanged(int state)
{
	if(state == Qt::Checked)
		mAutoExportZT2CSV = true;
	else if(state == Qt::Unchecked)
		mAutoExportZT2CSV = false;

	mProgramHandle->SaveAutoExportCSVSettings(mAutoExportZT1CSV,mAutoExportZT2CSV);
}

void CEngineeringPage::HighResLogCheckBoxChanged(int state)
{
    if(mProgramHandle == 0)
        return;
    if(isVisible() == false)
        return;

    if(state == Qt::Checked)
    {
        mProgramHandle->HighResLogging(true);
    }
    else
    {
        mProgramHandle->HighResLogging(false);
    }
}

void CEngineeringPage::KeepAllMPM10LogsCheckBoxChanged(int state)
{
    if(mProgramHandle == 0)
        return;
    if(isVisible() == false)
        return;

    if(state == Qt::Checked)
    {
        mProgramHandle->KeepAllMPM10Logs(true);
    }
    else
    {
        mProgramHandle->KeepAllMPM10Logs(false);
    }
}

void CEngineeringPage::KeepZT1LogsCheckBoxChanged(int state)
{
    if(mProgramHandle == 0)
        return;
    if(isVisible() == false)
        return;

    if(state == Qt::Checked)
    {
        mProgramHandle->KeepAllZT1Logs(true);
    }
    else
    {
        mProgramHandle->KeepAllZT1Logs(false);
    }
}

void CEngineeringPage::KeepZT2LogsCheckBoxChanged(int state)
{
    if(mProgramHandle == 0)
        return;
    if(isVisible() == false)
        return;

    if(state == Qt::Checked)
    {
        mProgramHandle->KeepAllZT2Logs(true);
    }
    else
    {
        mProgramHandle->KeepAllZT2Logs(false);
    }
}

void CEngineeringPage::MaxNbLogFilesChanged(int value)
{
    if(mProgramHandle == 0)
        return;
    if(isVisible() == false)
        return;

    mProgramHandle->SetLogFilesNumber(value);
}

void CEngineeringPage::RefreshLogsList()
{
    QStringList LogFilters;
    LogFilters << "*.bin";
    QDir LogDir("./Trains/");

    LogDir.setFilter(QDir::Files | QDir::NoDotAndDotDot);
    LogDir.setNameFilters(LogFilters);
    LogDir.setSorting(QDir::Name);

    mLogFilesList = LogDir.entryInfoList();

    mNbLogsText->setPlainText(QString().sprintf("Nombre de fichiers de passages: %d",mLogFilesList.size()));
}

void CEngineeringPage::DeleteAllLogs()
{
	QStringList LogFilters;
	LogFilters << "*.bin" << "*.csv";
    QDir LogDir("./Trains/");

	LogDir.setFilter(QDir::Files | QDir::NoDotAndDotDot);
	LogDir.setNameFilters(LogFilters);
	LogDir.setSorting(QDir::Name);

	for(int i = 0; i < LogDir.entryInfoList().size(); i++)
    {
		QFile::remove(LogDir.entryInfoList().at(i).absoluteFilePath());
    }

    RefreshLogsList();
	mProgramHandle->TrainFilesChanged();
}

void CEngineeringPage::ZTLogFilesSettings(int NbLogFiles, bool KeepMPM10Logs, bool KeepZT1Logs, bool KeepZT2Logs)
{
    if(KeepMPM10Logs == true)
        mKeepAllMPM10Logs->setCheckState(Qt::Checked);

    if(KeepZT1Logs == true)
        mKeepZT1Logs->setCheckState(Qt::Checked);

    if(KeepZT2Logs == true)
        mKeepZT2Logs->setCheckState(Qt::Checked);

    mNbLogFilesSpinBox->setValue(NbLogFiles);
}

void CEngineeringPage::ArchiveLogFiles()
{
	 RefreshLogsList();

	QString PathName = mUSBInterfacePtr->GetDrivePath();
	PathName += "/ArchiveLogZT_";
	PathName += mStation->GetStationShortName();
	PathName += QDateTime::currentDateTime().toString("_yyyyMMdd");
	QDir TargetDir(PathName);

	TargetDir.mkdir(PathName);	//If the directory does not exist, it will be created.

	//copy files
	QStringList LogFilters;
	LogFilters << "*.bin" << "*.csv";
    QDir LogDir("./Trains/");

	LogDir.setFilter(QDir::Files | QDir::NoDotAndDotDot);
	LogDir.setNameFilters(LogFilters);
	LogDir.setSorting(QDir::Name);
	for(int i = 0; i < LogDir.entryInfoList().size(); i++)
	{
		QString DestFileName = PathName;
		DestFileName += "/";
		DestFileName += LogDir.entryInfoList().at(i).fileName();
		QFile::copy(LogDir.entryInfoList().at(i).absoluteFilePath(),DestFileName);
	}

    system("sync");
//	DeleteAllLogs();
	mProgramHandle->TrainFilesChanged();

}

void CEngineeringPage::OutputToggled(CToggleButtonWidget *Button)
{
	if(Button->GetButtonState() == TOGGLE_BUTTON_ON)
	{
		mOutputModulePtr->SetOutputFlags(Button->GetData());
	}
	else
	{
		mOutputModulePtr->ClearOutputFlags(Button->GetData());
	}
}

void CEngineeringPage::PGCalibBtnToggled(CToggleButtonWidget *Btn)
{
	if(Btn == mPGCalibrationSwitch)
	{
		if(mPGCalibrationSwitch->GetButtonState() ==TOGGLE_BUTTON_ON)
		{
			if(mProgramHandle->StartPGCalibrationRequest(mPGNbPassagesForCalibSpinBox->value()) == false)
			{
				mPGCalibrationSwitch->SetButtonState(TOGGLE_BUTTON_OFF);
				QMessageBox MsgBox;
				MsgBox.setText("La Zone Tests est active\nVeuillez attendre qu'elle se libère");
				MsgBox.exec();
			}
			else
			{
				mCalibResultText->setPlainText("Valeur seuil PG calibration: Calib. en cours");
				mCopyCalibValueBtn->hide();
				CZTLog::instance()->AddLogString("Calibration PG démarrée.",true);
			}
		}
		else
		{

			if(mProgramHandle->StopPGCalibrationRequest() == false)
			{
				mPGCalibrationSwitch->SetButtonState(TOGGLE_BUTTON_ON);
				QMessageBox MsgBox;
				MsgBox.setText("La Zone Tests est active\nVeuillez attendre qu'elle se libère");
				MsgBox.exec();
				return;
			}
			else
			{
				mPGCalibrationSwitch->SetButtonState(TOGGLE_BUTTON_OFF);
				mCopyCalibValueBtn->hide();
				mCalibResultText->setPlainText("Valeur seuil PG calibration: Calib. non effectuée");
				CZTLog::instance()->AddLogString("Calibration PG annulée par l'utilisateur",true);

			}

		}
	}
}

void CEngineeringPage::LazerProbeDataAvailable(unsigned int Data, unsigned int ProbeID)
{
    if(!isVisible())
        return;

    QString ProbeData;
    ProbeData.clear();
    if(ProbeID == LAZER_PROBE_TYPE_EXTERNAL)
    {
        ProbeData.sprintf("Sonde Lazer Ext: %d",Data);
        mExtLazerProbeValue->setPlainText(ProbeData);
    }
    else
    {
        ProbeData.sprintf("Sonde Lazer Ixt: %d",Data);
        mIntLazerProbeValue->setPlainText(ProbeData);
    }

}

void CEngineeringPage::PGCalibFinished(int Treshold)
{
    mPGCalibrationSwitch->SetButtonState(TOGGLE_BUTTON_OFF);
	mCalibResultText->setPlainText(QString().sprintf("Valeur seuil PG calibration: %d",Treshold));
	mPGCalibTresholdValue = Treshold;
	mCopyCalibValueBtn->show();
	mProgramHandle->StopPGCalibrationRequest();
	CZTLog::instance()->AddLogString(QString().sprintf("Calibration PG terminée.  Seuil calculé: %d",Treshold),true);
}

void CEngineeringPage::PGCalibUpdate(int CurTrain, int TotalTrain)
{
	mCalibResultText->setPlainText(QString().sprintf("Valeur seuil PG calibration: Calib. en cours: Train %d / %d",CurTrain,TotalTrain));
	CZTLog::instance()->AddLogString(QString().sprintf("Calibration PG: Passage du train %d/%d",CurTrain,TotalTrain),true);
}

//Grab the mouse if the user clicks outside buttons
void CEngineeringPage::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
	Q_UNUSED(event)
}
void CEngineeringPage::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
	Q_UNUSED(event)
}
