/*******************************************************************************
*                                                                              *
* Société de Transports de Montréal.                                    	   *
* 2012                                                                         *
*                                                                              *
* Projet Zones Tests                                                           *
*                                                                              *
*                                                                              *
*                                                                              *
*******************************************************************************/
/*
    Description:
	Page de sélection des options (sélection des fonctions de détection, ingénierie,
	mode entretien, etc.).

*/

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

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

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


#include "DatabaseMgrPage.h"
#include <QPainter>
#include "GlobalDefine.h"
#include <QDialog>
#include <QMainWindow>
#include "OutilZT.h"
#include <QDateTime>
#include <QFont>
#include <QFileDialog>
#include <QTextEdit>
#include "OutilZT.h"
#include <QGraphicsProxyWidget>
#include <QListView>
#include <QTreeView>
#include <QList>
#include <TrainLogFileMgr.h>
#include <QCoreApplication>
#include <QMessageBox>
#include <QFileInfo>
#include <QCoreApplication>


CDatabaseMgrPage::~CDatabaseMgrPage()
{
    delete mDatabaseImporterThread;
    delete mDatabaseImporterWorkerThread;
}

CDatabaseMgrPage::CDatabaseMgrPage(QGraphicsWidget *Parent, bool EngMode)
{
	Q_UNUSED(Parent)

	mProgramHandle = 0;

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

    QGraphicsTextItem *Title = new QGraphicsTextItem("Base de données",this);
	QFont font;
	font.setPointSize(18);
	Title->setFont(font);
	Title->setPos(40,10);

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

    mImportDataButton = new CTextButtonWidget("Importer");
    mImportDataButton->setParentItem(this);
    mImportDataButton->setPos(125,200);
    connect(mImportDataButton,SIGNAL(TxtButtonClicked(CTextButtonWidget*)),this,SLOT(ButtonClicked(CTextButtonWidget*)));
    mImportDataButton->hide();


    mCancelImportButton = new CTextButtonWidget("Annuler");
    mCancelImportButton->setParentItem(this);
    mCancelImportButton->setPos(125,200);
    mCancelImportButton->hide();
    connect(mCancelImportButton,SIGNAL(TxtButtonClicked(CTextButtonWidget*)),this,SLOT(ButtonClicked(CTextButtonWidget*)));




    Title = new QGraphicsTextItem("Importation de passages",this);
    font.setPointSize(14);
    Title->setFont(font);
    Title->setPos(40,70);

    QPen RectPen;
    RectPen.setWidth(2);
    QGraphicsRectItem *ImportZoneFrame = new QGraphicsRectItem(this);
    ImportZoneFrame->setRect(QRectF(0,0,230,230));
    ImportZoneFrame->setPos(40,100);
    ImportZoneFrame->setPen(RectPen);

    QGraphicsProxyWidget *WidgetProxy = new QGraphicsProxyWidget(this);
    mImportErrorDataOnlyChkBx = new QCheckBox("Seulement les déclenchements");
    WidgetProxy->setWidget(mImportErrorDataOnlyChkBx);
    WidgetProxy->setPos(60,110);
    mImportErrorDataOnlyChkBx->setChecked(false);

    WidgetProxy = new QGraphicsProxyWidget(this);
    mFilterDuplicateChkBx = new QCheckBox("Filtrer les doublons");
    WidgetProxy->setWidget(mFilterDuplicateChkBx);
    WidgetProxy->setPos(60,140);
    mFilterDuplicateChkBx->setChecked(true);

    WidgetProxy = new QGraphicsProxyWidget(this);
    mImportInPlace = new QCheckBox("Importer en place");
    WidgetProxy->setWidget(mImportInPlace);
    WidgetProxy->setPos(60,170);
    mImportInPlace->setChecked(true);

//    WidgetProxy = new QGraphicsProxyWidget(this);
//    mDeleteSourceDataChkBx = new QCheckBox("Effacer données sources");
//    WidgetProxy->setWidget(mDeleteSourceDataChkBx);
//    WidgetProxy->setPos(60,170);



    mProgressBar = new QProgressBar();
    WidgetProxy = new QGraphicsProxyWidget(this);
    WidgetProxy->setWidget(mProgressBar);
    WidgetProxy->setPos(60,240);

    font.setPointSize(8);
    mProgressStatusText = new QGraphicsTextItem(this);
    mProgressStatusText->setFont(font);
    mProgressStatusText->setPos(60,260);
    mProgressStatusText->setPlainText("Progrès de l'importation");


    mDatabaseImporterWorkerThread = new CDatabaseImporterThread();
    mDatabaseImporterThread = new QThread();
    mDatabaseImporterWorkerThread->moveToThread(mDatabaseImporterThread);
    connect(mDatabaseImporterThread,SIGNAL(started()),mDatabaseImporterWorkerThread,SLOT(ExecuteThread()));
    connect(mDatabaseImporterWorkerThread,SIGNAL(DatabaseImportFinished(bool,QStringList*)),this,SLOT(DatabaseImportFinished(bool,QStringList*)));
    connect(mDatabaseImporterWorkerThread,SIGNAL(ResetProgressBar()),mProgressBar,SLOT(reset()));
    connect(mDatabaseImporterWorkerThread,SIGNAL(SetProgressBarRange(int,int)),mProgressBar,SLOT(setRange(int,int)));
    connect(mDatabaseImporterWorkerThread,SIGNAL(SetProgressBarVal(int)),mProgressBar,SLOT(setValue(int)));
    connect(mDatabaseImporterWorkerThread,SIGNAL(SetProgressText(QString)),this,SLOT(SetProgressText(QString)));
    connect(mDatabaseImporterWorkerThread,SIGNAL(DatabaseArchiveFinished(bool,int)),this,SLOT(DatabaseArchiveFinished(bool,int)));


    Title = new QGraphicsTextItem("Maintenance de la BD",this);
    font.setPointSize(14);
    Title->setFont(font);
    Title->setPos(350,70);

    QGraphicsRectItem *MaintenanceZoneFrame = new QGraphicsRectItem(this);
    MaintenanceZoneFrame->setRect(QRectF(0,0,320,240));
    MaintenanceZoneFrame->setPos(350,100);
    MaintenanceZoneFrame->setPen(RectPen);

    mDeleteDBDuplicatesBtn = new CTextButtonWidget("Effacer doublons");
    mDeleteDBDuplicatesBtn->setParentItem(this);
    mDeleteDBDuplicatesBtn->setPos(360,110);
    connect(mDeleteDBDuplicatesBtn,SIGNAL(TxtButtonClicked(CTextButtonWidget*)),this,SLOT(ButtonClicked(CTextButtonWidget*)));
    mDeleteDBDuplicatesBtn->hide();

    mDeleteNonErrorLogs = new CTextButtonWidget("Effacer passages sans décl.");
    mDeleteNonErrorLogs->setParentItem(this);
    mDeleteNonErrorLogs->setPos(360,140);
    connect(mDeleteNonErrorLogs,SIGNAL(TxtButtonClicked(CTextButtonWidget*)),this,SLOT(ButtonClicked(CTextButtonWidget*)));

    mDeleteZTLogFiles = new CTextButtonWidget("Effacer fichiers ZTLOG orphelins");
    mDeleteZTLogFiles->setParentItem(this);
    mDeleteZTLogFiles->setPos(360,170);
    connect(mDeleteZTLogFiles,SIGNAL(TxtButtonClicked(CTextButtonWidget*)),this,SLOT(ButtonClicked(CTextButtonWidget*)));

    mRebuildDatabaseFile = new CTextButtonWidget("Reconstruire le fichier BD");
    mRebuildDatabaseFile->setParentItem(this);
    mRebuildDatabaseFile->setPos(360,200);
    connect(mRebuildDatabaseFile,SIGNAL(TxtButtonClicked(CTextButtonWidget*)),this,SLOT(ButtonClicked(CTextButtonWidget*)));

    mArchiveDatabase = new CTextButtonWidget("Archiver les passages");
    mArchiveDatabase->setParentItem(this);
    mArchiveDatabase->setPos(360,230);
    connect(mArchiveDatabase,SIGNAL(TxtButtonClicked(CTextButtonWidget*)),this,SLOT(ButtonClicked(CTextButtonWidget*)));

    mArchiveKeepDays = new QSpinBox();
    WidgetProxy = new QGraphicsProxyWidget(this);
    WidgetProxy->setWidget(mArchiveKeepDays);
    WidgetProxy->setPos(525,230);
    mArchiveKeepDays->setMaximum(100);
    mArchiveKeepDays->setMinimum(0);
    mArchiveKeepDays->setValue(10);
    mArchiveKeepDays->setSuffix(" Jours conservés");
    mArchiveKeepDays->resize(140,30);


    mDBMaintenanceProgressBar = new QProgressBar();
    WidgetProxy = new QGraphicsProxyWidget(this);
    WidgetProxy->setWidget(mDBMaintenanceProgressBar);
    WidgetProxy->setPos(360,275);

    font.setPointSize(8);
    mDBMaintenanceProgressStatusText = new QGraphicsTextItem(this);
    mDBMaintenanceProgressStatusText->setFont(font);
    mDBMaintenanceProgressStatusText->setPos(360,305);
    mDBMaintenanceProgressStatusText->setPlainText("");

    if(EngMode == false)
    {
        mDeleteDBDuplicatesBtn->hide();
        mDeleteNonErrorLogs->hide();
        mDeleteZTLogFiles->hide();
        mRebuildDatabaseFile->hide();
        mDBMaintenanceProgressBar->hide();
        mDBMaintenanceProgressStatusText->hide();
        mFilterDuplicateChkBx->hide();
    }

    font.setPointSize(12);
    mDBFileCountText = new QGraphicsTextItem(this);
    mDBFileCountText->setFont(font);
    mDBFileCountText->setPos(300,10);
    mDBFileCountText->setPlainText("Nombre de passages: 440\nNombre de fichiers ZTLog: 30");

}

void CDatabaseMgrPage::resizeEvent(QGraphicsSceneResizeEvent *event)
{
	Q_UNUSED(event)
	mBackgroundRect->setRect(boundingRect());
}

void CDatabaseMgrPage::ButtonClicked(CTextButtonWidget *BtnPtr)
{
    if(BtnPtr == mCancelButton)
    {
        hide();
    }
    else if(BtnPtr == mImportDataButton)
    {
        ImportData(mImportErrorDataOnlyChkBx->isChecked(), mFilterDuplicateChkBx->isChecked());
    }
    else if(BtnPtr == mCancelImportButton)
    {
        mDatabaseImporterWorkerThread->KillThread();
    }
    else if(BtnPtr == mDeleteDBDuplicatesBtn)
    {
        CleanDBDuplicates();
    }
    else if(BtnPtr == mDeleteNonErrorLogs)
    {
        if(QMessageBox::question(0,"Attention","Voulez vous vraiment éliminer les passages\nsans déclenchements?\nCette action est irréversible",QMessageBox::Yes,QMessageBox::No) == QMessageBox::Yes)
        {
            CleanDBNormalPasses();
        }
    }
    else if(BtnPtr == mDeleteZTLogFiles)
    {
        if(QMessageBox::question(0,"Attention","Voulez vous vraiment éliminer les fichiers orphelins?\nCette action est irréversible",QMessageBox::Yes,QMessageBox::No) == QMessageBox::Yes)
        {
            CleanSingleZTLogFiles();
        }
    }
    else if(BtnPtr == mRebuildDatabaseFile)
    {
        mProgramHandle->RebuildDatabaseFile();
    }
    else if(BtnPtr == mArchiveDatabase)
    {
        ArchiveDB();
    }
}


bool CDatabaseMgrPage::ImportData(bool OnlyErrorLogs, bool FilterDuplicates)
{



    //Ask the user to select the data source directories...
    QStringList SelectedDirs;
    SelectedDirs.clear();
    QFileDialog FileDlg;


    FileDlg.setFileMode(QFileDialog::DirectoryOnly);

    QListView *l = FileDlg.findChild<QListView*>("listView");
    if (l)
    {
        l->setSelectionMode(QAbstractItemView::MultiSelection);
    }
    QTreeView *t = FileDlg.findChild<QTreeView*>();
    if (t)
    {
        t->setSelectionMode(QAbstractItemView::MultiSelection);
    }
    if(FileDlg.exec() == QDialog::Rejected)
    {
        return false;
    }

    SelectedDirs = FileDlg.selectedFiles();

    if(SelectedDirs.isEmpty())
        return false;

    mDatabaseImporterWorkerThread->SetDatabasePath(mProgramHandle->GetLogDataPath());
    mDatabaseImporterWorkerThread->SetImporParams(SelectedDirs,FilterDuplicates,OnlyErrorLogs);
    mDatabaseImporterWorkerThread->SetLogMgrHandle(mLogMgrHandle);
    mDatabaseImporterWorkerThread->SetThreadTask(CDatabaseImporterThread::DATABASE_THREAD_IMPORT_LOGS_TASK);

    mCancelButton->hide();
    mImportDataButton->hide();
    mCancelImportButton->show();

    mDatabaseImporterThread->start();

    return true;
}


bool CDatabaseMgrPage::CleanDBDuplicates()
{

   int NbDeletedFiles = 0;
   QList<CLogElement*> *LogsList = mLogMgrHandle->GetLogsList();

   mDBMaintenanceProgressStatusText->setPlainText("Analyse en cours");
   mDBMaintenanceProgressBar->setRange(0,LogsList->size());
   for(int i = 0; i < LogsList->size(); i++)
   {
       mDBMaintenanceProgressBar->setValue(i+1);
       for(int j = i+1; j < LogsList->size(); j++)
       {
           QCoreApplication::processEvents();

           if((LogsList->at(i)->mZTLogType == ZT1_LOG_TYPE) && (LogsList->at(j)->mZTLogType == ZT1_LOG_TYPE))
           {
               CZT1LogElement *ZT1LogElement_A = (CZT1LogElement*)LogsList->at(i);
               CZT1LogElement *ZT1LogElement_B = (CZT1LogElement*)LogsList->at(j);

               if(ZT1LogElement_A->mStationName == ZT1LogElement_B->mStationName)
               {
                   if(ZT1LogElement_A->mPassageDateTime == ZT1LogElement_B->mPassageDateTime)
                   {
                       //delete file from element B...
                       DeleteFile(ZT1LogElement_B->mLogFileName);
                       NbDeletedFiles++;
                       mDBMaintenanceProgressStatusText->setPlainText(QString().sprintf("Analyse en cours\n%d passages éliminés",NbDeletedFiles));
                   }
               }
           }
           else if((LogsList->at(i)->mZTLogType == ZT2_LOG_TYPE) && (LogsList->at(j)->mZTLogType == ZT2_LOG_TYPE))
           {
               CZT2LogElement *ZT2LogElement_A = (CZT2LogElement*)LogsList->at(i);
               CZT2LogElement *ZT2LogElement_B = (CZT2LogElement*)LogsList->at(j);

               if(ZT2LogElement_A->mStationName == ZT2LogElement_B->mStationName)
               {
                   if(ZT2LogElement_A->mPassageDateTime == ZT2LogElement_B->mPassageDateTime)
                   {
                       //delete file from element B...
                       DeleteFile(ZT2LogElement_B->mLogFileName);
                       NbDeletedFiles++;
                       mDBMaintenanceProgressStatusText->setPlainText(QString().sprintf("Analyse en cours\n%d passages éliminés",NbDeletedFiles));
                   }
               }
           }
       }
   }

   mDBMaintenanceProgressStatusText->setPlainText(QString().sprintf("Analyse des doublons terminée\n%d passages éliminés",NbDeletedFiles));
   mProgramHandle->LogsDatabaseChanged(0);

   return true;
}

bool CDatabaseMgrPage::CleanDBNormalPasses()
{
    int NbDeletedFiles = 0;
    QList<CLogElement*> *LogsList = mLogMgrHandle->GetLogsList();

    mDBMaintenanceProgressStatusText->setPlainText("Analyse en cours");
    mDBMaintenanceProgressBar->setRange(0,LogsList->size());
    for(int i = 0; i < LogsList->size(); i++)
    {
        mDBMaintenanceProgressBar->setValue(i+1);
        QCoreApplication::processEvents();

        if(LogsList->at(i)->mZTLogType == ZT1_LOG_TYPE)
        {
            CZT1LogElement *ZT1LogElement = (CZT1LogElement*)LogsList->at(i);

            if(ZT1LogElement->mZTDetections.size() == 0 /*&& ZT1LogElement->mFlags.mIsProblematicPassage != 1*/ && ZT1LogElement->mFileProtected == false)
            {

                DeleteFile(ZT1LogElement->mLogFileName);
                NbDeletedFiles++;
                mDBMaintenanceProgressStatusText->setPlainText(QString().sprintf("Analyse en cours\n%d passages éliminés",NbDeletedFiles));
            }
        }
        else
        {
            CZT2LogElement *ZT2LogElement = (CZT2LogElement*)LogsList->at(i);

            if(ZT2LogElement->mZTDetections.size() == 0 /*&& ZT2LogElement->mFlags.mIsProblematicPassage != 1*/ && ZT2LogElement->mFileProtected == false)
            {

                //delete file from element B...
                DeleteFile(ZT2LogElement->mLogFileName);
                NbDeletedFiles++;
                mDBMaintenanceProgressStatusText->setPlainText(QString().sprintf("Analyse en cours\n%d passages éliminés",NbDeletedFiles));
            }
        }
    }

    mDBMaintenanceProgressStatusText->setPlainText(QString().sprintf("Analyse des passages terminée\n%d passages éliminés",NbDeletedFiles));
    mProgramHandle->LogsDatabaseChanged(0);

    return true;
}

bool CDatabaseMgrPage::CleanSingleZTLogFiles()
{
     QList<CZTLogFileInfo> *ZTLogFilesList;

     ZTLogFilesList = mZTLogFilesManager->GetZTLogsList();

     if(ZTLogFilesList->size() == 0)
         return true;

     mDBMaintenanceProgressStatusText->setPlainText("Analyse en cours");
     mDBMaintenanceProgressBar->setRange(0,ZTLogFilesList->size());
     int NbRemoved = 0;
     for(int i = 0; i < ZTLogFilesList->size(); i++)
     {
         mDBMaintenanceProgressBar->setValue(i+1);
         QFileInfo ZTLogFile(ZTLogFilesList->at(i).mZTLogFilePath);
         QDir ZTLogFileDir = ZTLogFile.absoluteDir();

         ZTLogFileDir.setFilter(QDir::Files | QDir::NoDotAndDotDot);
         if(ZTLogFileDir.entryList().size() == 1)
         {
             NbRemoved++;
             if(ZTLogFileDir.remove(ZTLogFile.absoluteFilePath()))
             {
                 //qDebug("Removed %s",ZTLogFile.absoluteFilePath().toUtf8().data());
             }
             ZTLogFileDir.rmdir(ZTLogFile.absolutePath());
             {
                 //qDebug("Removed %s",ZTLogFile.absolutePath().toUtf8().data());
             }
             ZTLogFilesList->removeAt(i);
             i--;
         }
     }
     mDBMaintenanceProgressStatusText->setPlainText(QString().sprintf("Analyse des fichiers terminée\n%d fichiers ZTLOG éliminés",NbRemoved));
     mDBMaintenanceProgressBar->setRange(0,ZTLogFilesList->size());
     mProgramHandle->ZTLogFilesChanged();

     return true;
}

bool CDatabaseMgrPage::ArchiveDB()
{

    mDatabaseImporterWorkerThread->SetDatabasePath(mProgramHandle->GetLogDataPath());
    mDatabaseImporterWorkerThread->SetLogMgrHandle(mLogMgrHandle);
    mDatabaseImporterWorkerThread->SetThreadTask(CDatabaseImporterThread::DATABASE_THREAD_ARCHIVE_DB_TASK);
    QDate FilterDate = QDate::currentDate().addDays(-1 * (mArchiveKeepDays->value()));
    mDatabaseImporterWorkerThread->SetDatabaseFilters(FilterDate);

    mDatabaseImporterThread->start();

    return true;

}

void CDatabaseMgrPage::DatabaseImportFinished(bool ret,QStringList* FilesList)
{
    if(ret == false)
    {
        mProgressBar->reset();
        mProgressStatusText->setPlainText("Importation non terminée...");
    }

    mDatabaseImporterThread->quit();
    mCancelButton->show();
    mImportDataButton->show();
    mCancelImportButton->hide();
    if(ret == true)
    {
        mProgramHandle->LogsDatabaseChanged(FilesList);
        FilesList->clear();
        delete FilesList;
    }
}

void CDatabaseMgrPage::DatabaseArchiveFinished(bool success, int IgnoredFiles)
{
    mProgramHandle->RebuildDatabaseFile();
    mDatabaseImporterThread->quit();
    mCancelButton->show();
    mImportDataButton->show();
    mCancelImportButton->hide();
}

void CDatabaseMgrPage::SetProgressText(QString Text)
{
    mProgressStatusText->setPlainText(Text);
}

bool CDatabaseMgrPage::DeleteFile(QString FilePath)
{
    QDir dir;
    if(dir.remove(FilePath) == false)
    {
        qDebug("Could not delete file %s",FilePath.toUtf8().data());
        return false;
    }
    qDebug("File deleted: %s",FilePath.toUtf8().data());

    return true;
}

bool CDatabaseMgrPage::RemoveDir(QDir Dir)
{
    if (!Dir.exists())
        return true;

    QFileInfoList DirList = Dir.entryInfoList(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot);
    for(int i = 0; i < DirList.size(); i++)
    {
       // QFileInfo info(DirList.at(i));
        if (DirList.at(i).isDir())
        {
            if (!RemoveDir(QDir(DirList.at(i).filePath())))
            {
                qDebug("Cannot delete %s",DirList.at(i).absoluteFilePath().toUtf8().data());
                return false;
            }
//            else
//            {
//                if(Dir.rmdir(DirList.at(i).absoluteFilePath()) == false)
//                {
//                    qDebug("Could not delete %s",DirList.at(i).filePath().toUtf8().data());
//                }
//            }
        }
        else
        {
            if (Dir.remove(DirList.at(i).absoluteFilePath()) == false)
            {
                qDebug("Cannot delete %s",DirList.at(i).absoluteFilePath().toUtf8().data());              //  return false;
            }
        }
    }

    if(QDir().rmdir(Dir.absolutePath()) == false)
    {
        qDebug("Could not delete %s",Dir.absolutePath().toUtf8().data());
        return false;
    }

    return true;
}

void CDatabaseMgrPage::UpdateDBStats()
{
    int NbTrains, NbZTLog;

    NbTrains = mLogMgrHandle->GetLogsCount();
    NbZTLog = mZTLogFilesManager->GetZTLogFilesCount();

    mDBFileCountText->setPlainText(QString().sprintf("Nombre de passages: %d\nNombre de fichiers ZTLog: %d",NbTrains,NbZTLog));
}

void CDatabaseMgrPage::EnableEngineeringMode()
{
    //mDeleteDBDuplicatesBtn->show();
    mDeleteNonErrorLogs->show();
    mDeleteZTLogFiles->show();
    mRebuildDatabaseFile->show();
    mDBMaintenanceProgressBar->show();
    mDBMaintenanceProgressStatusText->show();
    mFilterDuplicateChkBx->show();
}

void CDatabaseMgrPage::EnableLogImport()
{
    mImportDataButton->show();
}

//Grab the mouse if the user clicks outside buttons
void CDatabaseMgrPage::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
	Q_UNUSED(event)
}
void CDatabaseMgrPage::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
	Q_UNUSED(event)
}
void CDatabaseMgrPage::showEvent(QShowEvent *event)
{
    //qDebug("Show");
   UpdateDBStats();
}

CDatabaseImporterThread::CDatabaseImporterThread()
{
    mLogMgrHandle = 0;
    mKillThread = false;
}

void CDatabaseImporterThread::ExecuteThread()
{
    switch(mThreadTask)
    {
        case DATABASE_THREAD_NO_TASK:
        {
            return;
            break;
        }
        case DATABASE_THREAD_IMPORT_LOGS_TASK:
        {
            ImportLogs();
            break;
        }
        case DATABASE_THREAD_ARCHIVE_DB_TASK:
        {
            ArchiveDB();
            break;
        }
    }
}
int CDatabaseImporterThread::ArchiveDB()
{
    mKillThread = false;

    emit SetProgressBarRange(0,0);
    emit ResetProgressBar();
    emit SetProgressText("Copie des fichiers dans l'archive");

    //Create archive dir.
    QDir ArchiveDir = mLogMgrHandle->GetBaseLogDataDir();
    ArchiveDir.cdUp();
    QString Path = QString("Archives");//.arg(QDate::currentDate().toString("yyyy-MM-dd"));
    ArchiveDir.mkpath(Path);
    ArchiveDir.cd(Path);

    int ret = -1;
    emit SetProgressText("Compression de l'archive...");
    QString CmdLine = QString(".\\7zip\\7z a %1\\ArchiveTrains%2.7z %3 -r").arg(QDir::toNativeSeparators(ArchiveDir.absolutePath())).arg(QDate::currentDate().toString("yyyy-MM-dd")).arg(QDir::toNativeSeparators(mLogMgrHandle->GetBaseLogDataDir().absolutePath()));
  //ret = QProcess::execute(CmdLine.toAscii().data());
    QString Exec7zip = ".\\7zip\\7z.exe";
    QStringList Params;
    Params << "a"
           << QString("%1\\ArchiveTrains%2.7z").arg(QDir::toNativeSeparators(ArchiveDir.absolutePath())).arg(QDate::currentDate().toString("yyyy-MM-dd"))
           << QDir::toNativeSeparators(mLogMgrHandle->GetBaseLogDataDir().absolutePath())
           << "-r"
           << "-bsp1"
           << "-bso0";

    m7zipProcess = new QProcess();

    m7zipProcess->start(Exec7zip,Params);
    if(m7zipProcess->waitForStarted() == false)
    {
       ret = -1;
    }
    else
    {
        while(m7zipProcess->state() == QProcess::Running)
        {
            QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
            QString StdOut;
            StdOut = QString(m7zipProcess->readAllStandardOutput());
            if(StdOut.isEmpty() == false)
            {

                qDebug(qPrintable(StdOut));
                emit SetProgressText(StdOut);
            }
        }
        ret = 0;
    }

    emit SetProgressBarRange(0,1);
    emit ResetProgressBar();
    if(ret != 0 && ret != 1)
    {
        //Return values of 7z.exe
        mKillThread = true;
        switch(ret)
        {
            case 2:
            {
                emit SetProgressText("Échec de compression, erreur fatale.");
                break;
            }
            case 7:
            {
                emit SetProgressText("Échec de compression, erreur ligne de commande.");
                break;
            }
            case 8:
            {
                emit SetProgressText("Échec de compression, mémoire insuffisante");
                break;
            }
            case 255:
            {
                emit SetProgressText("Échec de compression, intervention de l'utilisateur.");
                break;
            }
            case -2:
            {
                emit SetProgressText("Échec de compression, 7z.exe introuvable.");
                break;
            }
            case -1:
            {
                emit SetProgressText("Erreur d'exécution de 7zip.");
                break;

            }
            default:
            {
                break;
            }
        }

        emit DatabaseArchiveFinished(false,0);
        mThreadTask = DATABASE_THREAD_NO_TASK;
        return RET_ERROR;

    }

    delete m7zipProcess;

    int IgnoredFiles = 0;


    QList<CLogElement*> *LogsList = mLogMgrHandle->GetLogsList();

    emit SetProgressBarRange(0,LogsList->size());
    emit ResetProgressBar();
    emit SetProgressText("Nettoyage de l'archive");

    QDir LastDir;
    if(LogsList->at(0)->mZTLogType == ZT1_LOG_TYPE)
    {
        CZT1LogElement *tmp = (CZT1LogElement*)LogsList->at(0);
        QFileInfo FilePath(tmp->mLogFileName);
        LastDir = FilePath.dir();
    }
    else
    {
        CZT2LogElement *tmp =(CZT2LogElement*)LogsList->at(0);
        QFileInfo FilePath(tmp->mLogFileName);
        LastDir = FilePath.dir();
    }





    for(int i = 0; i < LogsList->size(); i++)
    {
        bool DeleteFile = false;
        QFileInfo FileInfo;

        emit SetProgressBarVal(i);
//        if(IsThreadKilled())
//        {
//            emit DatabaseArchiveFinished(false,0);
//            return;
//        }

        if(LogsList->at(i)->mZTLogType == ZT1_LOG_TYPE)
        {
            CZT1LogElement *tmp = (CZT1LogElement*)LogsList->at(i);
            FileInfo = QFileInfo(tmp->mLogFileName);

            emit SetProgressText(QString("Analyse: %1").arg(FileInfo.fileName()));

            if((tmp->mZTDetections.size() == 0) && (tmp->mPassageDateTime.date() < mDatabaseArchiveFilterDate) && (tmp->mFileProtected == false))
            {
                //Remove file from database
                DeleteFile = true;
            }
            else
            {
                DeleteFile = false;
                IgnoredFiles++;
            }
        }
        else
        {
            CZT2LogElement *tmp = (CZT2LogElement*)LogsList->at(i);
            FileInfo = QFileInfo(tmp->mLogFileName);

            if(((tmp->mPassageDateTime.date() < mDatabaseArchiveFilterDate) && (tmp->mFileProtected == false)))
            {
                //Remove file from database
                DeleteFile = true;
            }
            else
            {
                DeleteFile = false;
                IgnoredFiles++;
            }
        }

        //Delete the current file if necessary...
        if(DeleteFile == true)
        {
            QFile::remove(FileInfo.filePath());
        }

        //Check if we are changing directory or analyzing the last one...
        if(LastDir.dirName() != FileInfo.dir().dirName() ||
           i == LogsList->size() - 1 )
        {
            //Check if we need to delete the directory (if there are any .bin in the dir, we have to keep it)
            //Make a list of the .bin files in the directory
            LastDir.setFilter(QDir::Files);
            QStringList filter;
            filter << "*.bin";
            LastDir.setNameFilters(filter);

            //If no binary file is left in the database dir, delete it.
            if(LastDir.count() == 0)
            {
                LastDir.setNameFilters(QStringList());
                ClearDir(LastDir);
                if(QDir().rmdir(LastDir.absolutePath()) == false)
                {
                    qDebug("Could not delete dir...");
                }
            }
        }


        LastDir = FileInfo.dir();
    }

    emit ResetProgressBar();
    emit SetProgressText(QString("Archivage terminé.  %1 fichiers conservés").arg(IgnoredFiles));

    emit DatabaseArchiveFinished(true,IgnoredFiles);
    mThreadTask = DATABASE_THREAD_NO_TASK;
    return RET_OK;
}

void CDatabaseImporterThread::ImportLogs()
{
    mKillThread = false;
    bool OnlyErrorLogs = mOnlyErrorLogs;
    bool FilterDuplicates = mFilterDuplicates;
    QStringList SelectedDirs = mSelectedDirs;

    int NbDeletedFiles = 0;
    int NbCopiedFiles = 0;
    int NbCopiedDirs = 0;


    ClearDir(QDir("./Temp"));



    emit SetProgressBarRange(0,SelectedDirs.size());
    emit ResetProgressBar();
    emit SetProgressText("Copie des répertoires temporaires");
    //Copy the files
    for(int i = 0; i < SelectedDirs.size(); i++)
    {

        QDir SrcDir(SelectedDirs.at(i));
        QString tmp = "./Temp/" + SrcDir.dirName();
        QDir DestDir(tmp);

        CopyDir(SrcDir,DestDir);
        emit SetProgressBarVal(i+1);

        if(IsThreadKilled())
        {
            emit DatabaseImportFinished(false,0);
            return;
        }
    }

    // Parse each directory to add.
    QFileInfoList DataFilePath;
    DataFilePath.clear();
    QDir TempDir("./Temp");
    DataFilePath = TempDir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot);

    if(DataFilePath.isEmpty())
    {
        emit DatabaseImportFinished(false,0);
        mThreadTask = DATABASE_THREAD_NO_TASK;
        return;
    }

    QString DatabasePath = mDatabasePath;
    QList<CLogElement*> *ExistingLogsList = mLogMgrHandle->GetLogsList();

    QStringList LogFilters;
    LogFilters << "*.bin";
    bool CopyDirectory = true;

    if(FilterDuplicates == true || OnlyErrorLogs == true)
    {
        for(int i = 0; i < DataFilePath.size(); i++)
        {
            QFileInfoList list;

            //Load files in base directory
            QDir LogDir(DataFilePath.at(i).absoluteFilePath());
            LogDir.setFilter(QDir::Files | QDir::NoDotAndDotDot);
            LogDir.setNameFilters(LogFilters);
            LogDir.setSorting(QDir::Name);
            list = LogDir.entryInfoList();
            if(list.size() != 0)
            {
                //If no filtering is required, just copy the directory...
                if(FilterDuplicates == false && OnlyErrorLogs == false)
                {
                    CopyDirectory = true;
                }
                else
                {
                    unsigned int ret;
                    emit SetProgressBarRange(0,list.size());
                    emit ResetProgressBar();
                    emit SetProgressText(QString().sprintf("Vérification du répertoire:\n%s",DataFilePath.at(i).fileName().toUtf8().data()));

                    for(int NewLogIndex = 0; NewLogIndex < list.size(); NewLogIndex++)
                    {
                        CLogElement *CurLogElement = CTrainLogFileMgr::instance()->OpenTrainLog(list.at(NewLogIndex).absoluteFilePath(),ret);

                        if(CurLogElement->mZTLogType == ZT1_LOG_TYPE)
                        {
                            CZT1LogElement * NewZT1Element = (CZT1LogElement*)CurLogElement;
                            bool FileDeleted = false;

                            if(OnlyErrorLogs && (FileDeleted == false))
                            {
                                if(NewZT1Element->mZTDetections.size() == 0)
                                {
                                    DeleteFile(list.at(NewLogIndex).absoluteFilePath());
                                    FileDeleted = true;
                                    NbDeletedFiles++;
                                }
                            }

                            if(FilterDuplicates && (FileDeleted == false))
                            {
                                for(int ExistingLogIndex = 0; ExistingLogIndex < ExistingLogsList->size(); ExistingLogIndex++)
                                {
                                    if(ExistingLogsList->at(ExistingLogIndex)->mZTLogType == ZT1_LOG_TYPE)
                                    {
                                        CZT1LogElement * ExistingZT1Element = (CZT1LogElement*)ExistingLogsList->at(ExistingLogIndex);

                                        if(ExistingZT1Element->mStationName == NewZT1Element->mStationName)
                                        {
                                            if(ExistingZT1Element->mPassageDateTime == NewZT1Element->mPassageDateTime)
                                            {
                                                //Delete the file from the temporary directory.
                                                DeleteFile(list.at(NewLogIndex).absoluteFilePath());
                                                FileDeleted = true;
                                                NbDeletedFiles++;
                                                break;
                                            }
                                        }
                                    }
                                }
                            }

                        }
                        else    //ZT2
                        {
                            CZT2LogElement * NewZT2Element = (CZT2LogElement*)CurLogElement;
                            bool FileDeleted = false;

                            if(OnlyErrorLogs && (FileDeleted == false))
                            {
                                if(NewZT2Element->mZTDetections.size() == 0)
                                {
                                    DeleteFile(list.at(NewLogIndex).absoluteFilePath());
                                    FileDeleted = true;
                                    NbDeletedFiles++;
                                }
                            }

                            if(FilterDuplicates && (FileDeleted == false))
                            {
                                for(int ExistingLogIndex = 0; ExistingLogIndex < ExistingLogsList->size(); ExistingLogIndex++)
                                {
                                    if(ExistingLogsList->at(ExistingLogIndex)->mZTLogType == ZT2_LOG_TYPE)
                                    {
                                        CZT2LogElement * ExistingZT2Element = (CZT2LogElement*)ExistingLogsList->at(ExistingLogIndex);

                                        if(ExistingZT2Element->mStationName == NewZT2Element->mStationName)
                                        {
                                            if(ExistingZT2Element->mPassageDateTime == NewZT2Element->mPassageDateTime)
                                            {
                                                //Delete the file from the temporary directory.
                                                DeleteFile(list.at(NewLogIndex).absoluteFilePath());
                                                FileDeleted = true;
                                                NbDeletedFiles++;
                                            }
                                        }
                                    }
                                }
                            }

                        }
                        emit SetProgressBarVal(NewLogIndex+1);
                        delete CurLogElement;
                        if(IsThreadKilled())
                        {
                            emit DatabaseImportFinished(false,0);
                            mThreadTask = DATABASE_THREAD_NO_TASK;
                            return;
                        }
                    }

                }

            }
            else
            {
                CopyDirectory = true;
            }
        }
    }

    QStringList *NewFilesList = new QStringList;
    if(CopyDirectory)
    {
        QDir TmpDir("./Temp");
        DataFilePath.clear();
        DataFilePath = TmpDir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot);

        //Find the number of files to copy for the progress bar...
        int NbFilesToCopy = 0;
        for(int i = 0; i < DataFilePath.size(); i++)
        {
            QDir SrcDir(DataFilePath.at(i).absoluteFilePath());
            NbFilesToCopy += SrcDir.entryList(QDir::Files).size();
        }

        emit SetProgressBarRange(0,NbFilesToCopy);
        emit ResetProgressBar();
        ProgressValue = 0;
        emit SetProgressText("Copie des fichiers dans la BD");

        for(int i = 0; i < DataFilePath.size(); i++)
        {
            QString StationDir;
            StationDir.clear();

            QStringList DirNameNibbles = DataFilePath.at(i).fileName().split('_');
            if(DirNameNibbles.size() == 3)
            {
                StationDir = DirNameNibbles.at(1);
                QDir SrcDir(DataFilePath.at(i).absoluteFilePath());
                QString tmp = DatabasePath + SrcDir.separator() + StationDir + SrcDir.separator() + SrcDir.dirName();
                QDir DestDir(QDir::cleanPath(tmp));

                NbCopiedFiles += CopyDir(SrcDir,DestDir,true);
                NbCopiedDirs++;

                QFileInfoList FilesList = DestDir.entryInfoList(QDir::Files);
                for(int i = 0; i < FilesList.size(); i++)
                {
                    NewFilesList->append(FilesList.at(i).absoluteFilePath());
                }
            }
            else
            {
                qDebug("Erreur, nom de répertoire illégal : %s",DataFilePath.at(i).absoluteFilePath().toUtf8().data());
            }
            if(IsThreadKilled())
            {
                emit DatabaseImportFinished(false,0);
                mThreadTask = DATABASE_THREAD_NO_TASK;
                return;
            }
     //       emit SetProgressBarVal(i+1);
        }
    }
    emit ResetProgressBar();
    emit SetProgressText(QString().sprintf("Importation terminée avec succès\n%d passages ignorés\n%d fichiers copiés dans %d répertoires",NbDeletedFiles,NbCopiedFiles,NbCopiedDirs));

    emit DatabaseImportFinished(true,NewFilesList);
    mThreadTask = DATABASE_THREAD_NO_TASK;
    return;

}




int CDatabaseImporterThread::CopyDir(QDir Dir, QDir DestDir, bool NotifyWhenCopied, bool Recursive)
{

    int CopiedFiles = 0;

    if (!Dir.exists())
    {
        return false;
    }


    Dir.mkpath(DestDir.absolutePath());

    foreach (QString f, Dir.entryList(QDir::Files))
    {
        QFile::copy(Dir.absolutePath() + QDir::separator() + f, DestDir.absolutePath() + QDir::separator() + f);
        CopiedFiles++;
        if(NotifyWhenCopied)
        {
            ProgressValue++;
            emit SetProgressBarVal(ProgressValue);
            emit SetProgressText(QString().sprintf("Copie des fichiers\n%s",f.toUtf8().data()));
        }
        if(IsThreadKilled())
        {
            return CopiedFiles;
        }
    }
    if(Recursive)
    {
       foreach (QString f, Dir.entryList(QDir::AllDirs | QDir::NoDotAndDotDot))
       {
           CopyDir(Dir.absolutePath()+QDir::separator()+f,DestDir.absolutePath()+QDir::separator()+f,true,true);

           if(IsThreadKilled())
           {
               return CopiedFiles;
           }
       }
    }


    return CopiedFiles;
}

bool CDatabaseImporterThread::ClearDir(QDir Dir)
{
    if (!Dir.exists())
        return true;

    QFileInfoList DirList = Dir.entryInfoList(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot);
    for(int i = 0; i < DirList.size(); i++)
    {
       // QFileInfo info(DirList.at(i));
        if (DirList.at(i).isDir())
        {
            if (!ClearDir(QDir(DirList.at(i).filePath())))
            {
                return false;
            }
            else
            {
                if(Dir.rmdir(DirList.at(i).absoluteFilePath()) == false)
                {
                    qDebug("Could not delete %s",DirList.at(i).filePath().toUtf8().data());
                }
            }
        }
        else
        {
            if (Dir.remove(DirList.at(i).absoluteFilePath()) == false)
            {
                qDebug("Cannot delete %s",DirList.at(i).absoluteFilePath().toUtf8().data());              //  return false;
            }
        }
    }

    return true;
}

bool CDatabaseImporterThread::DeleteFile(QString FilePath)
{
    QDir dir;
    if(dir.remove(FilePath) == false)
    {
        qDebug("Could not delete file %s",FilePath.toUtf8().data());
        return false;
    }
    qDebug("File deleted: %s",FilePath.toUtf8().data());

    return true;
}

int CDatabaseImporterThread::ParseDir(QDir dir)
{

    QStringList LogFilters;
    QFileInfoList list;
   // QString LogDataDir = mProgramHandle->GetLogDataPath();
    LogFilters << "*.bin";

    //Load files in base directory
    QDir LogDir(dir);
    LogDir.setFilter(QDir::Files | QDir::NoDotAndDotDot);
    LogDir.setNameFilters(LogFilters);
    LogDir.setSorting(QDir::Name);
    list = LogDir.entryInfoList();
    if(list.size() != 0)
    {

    }
    else
        return 0;


    return 1;
}

bool CDatabaseImporterThread::SetThreadTask(int task)
{
    mMutex.lockForWrite();
    mThreadTask = task;
    mMutex.unlock();
    return true;
}

void CDatabaseImporterThread::SetImporParams(QStringList SelectedDirs, bool FilterDuplicates, bool OnlyErrorLogs)
{
    mSelectedDirs = SelectedDirs;
    mFilterDuplicates = FilterDuplicates;
    mOnlyErrorLogs = OnlyErrorLogs;
}

void CDatabaseImporterThread::SetDatabaseFilters(QDate FilterDate)
{
    mDatabaseArchiveFilterDate  = FilterDate;
}

void CDatabaseImporterThread::KillThread()
{
    mMutex.lockForWrite();
    mKillThread = true;
    mMutex.unlock();

    qDebug("Thread killed");
}

bool CDatabaseImporterThread::IsThreadKilled()
{
    bool tmp;
    mMutex.lockForRead();
    tmp = mKillThread;
    mMutex.unlock();

    return tmp;
}

void CDatabaseImporterThread::New7zipStdOutput()
{

}
