#include "mainwindow.h"
#include "ui_mainwindow.h"

#include "formworklist.h"
#include "formhistory.h"
#include "formsetting.h"
#include "formcapture.h"
#include "formviewer.h"
#include "qrtspthread.h"
#include "qgstreamerplayer.h"

#include <QSharedMemory>

#include "charconvert.h"

#include "dialogpowerbutton.h"

#include <QKeyEvent>

#include "dialoglogin.h"
#include "dialogchecksumerror.h"

#include "dialogexportsamba.h"

#include "dialogsettingnetworkshare.h"

#include <QFileInfo>
#include <QDirIterator>



MainWindow* MainWindow::m_pMainWindow = NULL;
CommonData* MainWindow::m_pCommonData = NULL;

extern QRTSPThread t;
extern SThreadWatchVideoLink v;


MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    m_bMountDiskUSB = false;
    m_pProcessNode = NULL;
    m_pCommonData = NULL;
    QRTSPThread* pThreadRTSP = &t;
    SThreadWatchVideoLink* pThreadWatchVideoLink = &v;
    m_pMainWindow = this;
    m_pCommonData = new CommonData;
    m_pCommonData->SetUseWebDisplay(true);
    setWindowFlags(Qt::Window | Qt::FramelessWindowHint);

    m_pThreadWatch = NULL;

    //#ifndef _PC
        m_pThreadWatch = new SThreadWatchPort();
        connect(m_pThreadWatch, SIGNAL(CaptureHandSwitch()), this, SLOT(CaptureHandSwitch()));
        m_pThreadWatch->start();
    //#endif

    WRITE_FUNCTION_LOG();

    ui->setupUi(this);

    setGeometry(0, 0, 1920, 1080);

    FormWorklist* pWorklist = new FormWorklist(this);
    pWorklist->setGeometry(58, 166, 1808, 857);
    pWorklist->hide();

    FormHistory* pHistory = new FormHistory(this);
    pHistory->setGeometry(58, 166, 1808, 857);
    pHistory->hide();

    FormSetting* pSetting = new FormSetting(this);
    pSetting->setGeometry(58, 166, 1808, 857);
    pSetting->hide();

    FormCapture* pCapture = new FormCapture(this);
    pCapture->setGeometry(0, 0, 1920, 1080);
    pCapture->hide();

    FormViewer* pViewer = new FormViewer(this);
    pViewer->setGeometry(0, 0, 1920, 1080);
    pViewer->hide();

#ifndef _PC
    //connect(m_pThreadWatch, SIGNAL(HDMICalbeConnect(bool)), pCapture, SLOT(HDMICalbeConnect(bool)));
#endif

    pThreadWatchVideoLink->SetThreadRTSP(pThreadRTSP);
    //connect(pThreadWatchVideoLink, SIGNAL(HDMICalbeConnect(bool)), pCapture, SLOT(HDMICalbeConnect(bool)));
    pThreadWatchVideoLink->WatchVideoConnect();

    connect(this, SIGNAL(SendCaptureHandSwitch()), pCapture, SLOT(CaptureHandSwitch()));
    connect(this, SIGNAL(SendCaptureFootSwitch()), pCapture, SLOT(CaptureFootSwitch()));
    connect(pThreadRTSP, SIGNAL(VideoButtonChange(bool)), pCapture, SLOT(VideoButtonChange(bool)));

    //Test Code
    connect(pWorklist, SIGNAL(Exit()), this, SLOT(Exit()));

    connect(&m_TimerCheckDiskUSB, SIGNAL(timeout()), this, SLOT(CheckDiskUSB()));



    m_ListWidget.push_back(pWorklist);
    m_ListWidget.push_back(pHistory);
    m_ListWidget.push_back(pSetting);
    m_ListWidget.push_back(pCapture);
    m_ListWidget.push_back(pViewer);

    m_pDialogMissCapture = new DialogMissCapture(this);


    m_nCurrentMenuID = -1;
    m_nCurrentWidgetID = -1;

    connect(&m_Timer, SIGNAL(timeout()), this, SLOT(DeferredInit()));

    connect(&m_TimerWatchPowerButton, SIGNAL(timeout()), this, SLOT(WatchPowerButton()));

    connect(&m_TimerMissCapture, SIGNAL(timeout()), this, SLOT(MissCapture()));


    connect(pCapture, SIGNAL(BackupNetworkShareFolder(QString)), this, SLOT(BackupNetworkShareFolder(QString)));
    //m_pCommonData->SetUseNetworkBackupVideo(true);

    connect(&m_TimerScreenSaver, SIGNAL(timeout()), this, SLOT(CheckShowScreenSaver()));

    connect(&m_TimerLog, SIGNAL(timeout()), this, SLOT(WriteLogTimer()));

    m_TimerLog.start(1000*5); // 5 seconds



    m_Timer.start(500);

    m_TimerWatchPowerButton.start(1000);

    m_pScreenSaver = new FormScreenSaver;
    m_pScreenSaver->hide();

    pThreadWatchVideoLink->ChangeState(0);

}

MainWindow::~MainWindow()
{
    FormCapture* pCapture = (FormCapture*)m_ListWidget[3];

    disconnect(&m_Timer, SIGNAL(timeout()), this, SLOT(DeferredInit()));
    disconnect(&m_TimerWatchPowerButton, SIGNAL(timeout()), this, SLOT(WatchPowerButton()));
    disconnect(&m_TimerMissCapture, SIGNAL(timeout()), this, SLOT(MissCapture()));
    disconnect(&m_TimerScreenSaver, SIGNAL(timeout()), this, SLOT(CheckShowScreenSaver()));

    disconnect(this, SIGNAL(SendCaptureHandSwitch()), pCapture, SLOT(CaptureHandSwitch()));
    disconnect(this, SIGNAL(SendCaptureFootSwitch()), pCapture, SLOT(CaptureFootSwitch()));


    SThreadImageSave* pThreadImageSave = m_pCommonData->GetThreadCaptureImage();
    if(pThreadImageSave!=NULL)
    {
        disconnect(pThreadImageSave, SIGNAL(ViewDialogMissCapture()), this, SLOT(ViewDialogMissCapture()) );
    }

    WRITE_FUNCTION_LOG();
    SAFE_DELETE(m_pCommonData);

    SAFE_DELETE(m_pScreenSaver);

    if(m_pThreadWatch!=NULL)
    {
        m_pThreadWatch->ExitThread();
        SAFE_DELETE(m_pThreadWatch);
    }
    delete ui;
}



void MainWindow::CheckShowScreenSaver()
{
    qint64 nTime = m_TimeCheckScreenSaver.elapsed()/(1000);

    int nScreenSaverTime = m_pCommonData->GetScreenSaverTime();

    if(nScreenSaverTime==0)
    {
        return;
    }

    if(nTime>=60*nScreenSaverTime) //60 sec * 10 --> 10 minutes
    {
        if(m_pScreenSaver->isVisible()==false)
        {
            m_pScreenSaver->Init();
            StopScreenSaverTimer();
        }

    }
}

MainWindow* MainWindow::GetMainWindow()
{
    return m_pMainWindow;
}

CommonData* MainWindow::GetCommonData()
{
    return m_pCommonData;
}

void MainWindow::SetDisplayType(int nType)
{
    WRITE_FUNCTION_LOG_PARAM(QString::number(nType));
    m_nDisplayType = nType;
    m_pCommonData->SetDisplayType(nType);

    if(m_nDisplayType==SDISPLAY_1920X1080)
    {
        resize(1920, 1080);
    }
    else if(m_nDisplayType==SDISPLAY_1280X1024)
    {
        resize(1280, 1024);
    }
}

void MainWindow::ChangeMenu(int nID)
{
    WRITE_FUNCTION_LOG_PARAM(QString::number(nID));

    int nPrevCurrentMenuID = m_nCurrentMenuID;
    int nPrevCurrentWidgetID = m_nCurrentWidgetID;

    SThreadImageSave* pThreadImageSave = m_pCommonData->GetThreadCaptureImage();
    if(m_nCurrentWidgetID>=0)
    {
        m_ListWidget[m_nCurrentWidgetID]->hide();
    }

    switch(nID)
    {
        case SMENU_WORKLIST:
            m_nCurrentWidgetID = SWIDGET_WORKLIST;
            break;
        case SMENU_HISTORY:
            m_nCurrentWidgetID = SWIDGET_HISTORY;
            break;
        case SMENU_SETTING:
            m_nCurrentWidgetID = SWIDGET_SETTING;
            break;
        case SMENU_CAPTURE:
            m_nCurrentWidgetID = SWIDGET_CAPTURE;
            break;
        case SMENU_VIEWER:
            m_nCurrentWidgetID = SWIDGET_VIEWER;
            break;
    }


    if(nID!=SMENU_CAPTURE)
    {
        if(m_pCommonData->GetScreenSaverTime()>0)
        {
            if(m_TimerScreenSaver.isActive()==false)
            {
                ResetScreenSaverTimer();
                StartScreenSaverTimer();
            }
        }

    }
    else
    {
        if(m_pCommonData->GetScreenSaverTime()>0)
        {
            if(m_TimerScreenSaver.isActive()==true)
            {
                StopScreenSaverTimer();
            }
        }

    }


    if(nID<=SMENU_SETTING)
    {
        m_nCurrentMenuID = nID;
        if(m_nCurrentMenuID==SMENU_WORKLIST)
        {
            ((FormWorklist*)m_ListWidget[m_nCurrentWidgetID])->Init();
        }
        else if(m_nCurrentMenuID==SMENU_HISTORY)
        {
            ((FormHistory*)m_ListWidget[m_nCurrentWidgetID])->Init();
        }
        else if(m_nCurrentMenuID==SMENU_SETTING)
        {
            ((FormSetting*)m_ListWidget[m_nCurrentWidgetID])->Init();
        }
        m_ListWidget[m_nCurrentWidgetID]->show();
        return;
    }
    else
    {
        if(nID==SMENU_CAPTURE)
        {

            {



                ACQUISITION_INFO* pAcquisitionInfo = m_pCommonData->GetAcquisitionInfo();

                QDateTime dt = QDateTime::currentDateTime();
                int nYear = dt.date().year();
                int nMonth = dt.date().month();
                int nDay = dt.date().day();
                int nHour = dt.time().hour();
                int nMinute = dt.time().minute();
                int nSecond = dt.time().second();

                SDATA_STUDY* pStudy = pAcquisitionInfo->GetStudyInfo();

                //if(pStudy->strStudyDate.length()==0)
                {
                    //pStudy->strStudyDate = (QString("%1%2%3").arg(QString::number(nYear).rightJustified(4, '0')).arg(QString::number(nMonth).rightJustified(2, '0')).arg(QString::number(nDay).rightJustified(2, '0'))).toStdString();
                    //pStudy->strStudyTime = (QString("%1%2%3").arg(QString::number(nHour).rightJustified(2, '0')).arg(QString::number(nMinute).rightJustified(2, '0')).arg(QString::number(nSecond).rightJustified(2, '0'))).toStdString();
                }

                if(pAcquisitionInfo->GetPatientInfo()->strPatientID.size()==0)
                {
                    pAcquisitionInfo->Clear();
                    pAcquisitionInfo->GetPatientInfo()->strPatientID = (QString("%1%2%3%4%5%6").arg(QString::number(nYear)).arg(QString::number(nMonth)).arg(QString::number(nDay)).arg(QString::number(nHour)).arg(QString::number(nMinute)).arg(QString::number(nSecond))).toStdString().c_str();
                    pAcquisitionInfo->GetPatientInfo()->strPatientName = (QString("테스트%1").arg(pAcquisitionInfo->GetPatientInfo()->strPatientID)).toStdString().c_str();
                    pAcquisitionInfo->GetStudyInfo()->strStudyInstanceUID = (QString("1.1.22.33.%1.1%2%3.1%4").arg(pAcquisitionInfo->GetPatientInfo()->strPatientID.toStdString().c_str()).arg(QString::number(nHour)).arg(QString::number(nMinute)).arg(QString::number(nSecond))).toStdString().c_str();
                    pAcquisitionInfo->GetStudyInfo()->strStudyDescription = "Emergency Study Desc.";
                    pAcquisitionInfo->GetSeriesInfo()->strSeriesDescription = "Emergency Series Desc.";
                    pAcquisitionInfo->GetSeriesInfo()->strOperatorsName = "";

                    pAcquisitionInfo->GetPatientInfo()->strPatientSex = "F";
                    pAcquisitionInfo->GetPatientInfo()->strPatientWeight = "70";
                    pAcquisitionInfo->GetPatientInfo()->strPatientBirthDate = "19990909";
                }


                SDatabase* pDatabase = NULL;
                int nStudyIndex = 0;
                int nPatientIndex = 0;
                int nSeriesImageIndex = 0;
                int nSeriesMovieIndex = 0;
                bool bCreateStudy = false;


                int nMaxTestCount = 10;
                int nTestCount = 0;

                for(nTestCount=0 ; nTestCount<nMaxTestCount ; nTestCount++)
                {
                    SUTIL::SDatabase db(QString("CreateStudyThread_%1").arg(reinterpret_cast<quintptr>(this)));
                    if (db.OpenDatabase("/home/birdhead/test.db") != 0) {
                        qWarning() << "DB open failed, retrying...";
                        usleep(100 * 1000); // DB 연결 실패 시 잠시 대기 후 재시도
                        continue;
                    }

                    // 2. 트랜잭션을 시작합니다. 이제부터 모든 작업은 "All or Nothing" 입니다.
                    if (!db.BeginTransaction()) {
                        qWarning() << "Failed to begin transaction, retrying...";
                        usleep(10 * 1000);
                        continue;
                    }

                    // 3. 트랜잭션 내에서 모든 INSERT 작업을 수행합니다.
                    nPatientIndex = db.InsertPatient(pAcquisitionInfo);
                    nStudyIndex = db.InsertStudy(pAcquisitionInfo);
                    nSeriesImageIndex = db.InsertSeriesImage(pAcquisitionInfo);
                    nSeriesMovieIndex = db.InsertSeriesMovie(pAcquisitionInfo);

                    // 4. 모든 작업의 성공 여부를 확인합니다.
                    if (nPatientIndex > 0 && nStudyIndex > 0 && nSeriesImageIndex > 0 && nSeriesMovieIndex > 0) {
                        // 5. 모두 성공했다면, 트랜잭션을 최종적으로 데이터베이스에 반영 (Commit)
                        if (db.Commit()) {
                            bCreateStudy = true; // 최종 성공!
                        } else {
                            qWarning() << "Transaction commit failed! Rolling back...";
                            db.Rollback(); // Commit 실패 시 롤백
                        }
                    } else {
                        // 하나라도 실패했다면, 지금까지의 모든 작업을 취소 (Rollback)
                        qWarning() << "One or more insert failed. Rolling back...";
                        db.Rollback();
                    }

                    // 무언가 실패하여 재시도해야 하는 경우, 잠시 대기
                    if (!bCreateStudy) {
                        usleep(10 * 1000);
                    }
                }


                nStudyIndex = pAcquisitionInfo->m_nIndexStudy;
                m_pCommonData->ReleaseAcquisitionInfo();

                //bCreateStudy = false;
                if(bCreateStudy==false)
                {
                    m_nCurrentMenuID = nPrevCurrentMenuID;
                    m_nCurrentWidgetID = nPrevCurrentWidgetID;
                    m_ListWidget[m_nCurrentWidgetID]->show();

                    if(m_nCurrentMenuID==SMENU_WORKLIST)
                    {
                        FormWorklist* pWorklist = (FormWorklist*)m_ListWidget[m_nCurrentWidgetID];
                        pWorklist->ErrorPatientInfo();
                    }
                    else if(m_nCurrentMenuID==SMENU_HISTORY)
                    {
                        FormHistory* pHistory = (FormHistory*)m_ListWidget[m_nCurrentWidgetID];
                    }

                    SetDisplayError(0x08);


                    return;
                }

                if (nStudyIndex > 0)
                {
                    // 1. 이 로직 블록 전체에서 사용할 단 하나의 지역 DB 인스턴스를 생성합니다.
                    SUTIL::SDatabase db(QString("ProcessStudy_%1").arg(reinterpret_cast<quintptr>(this)));
                    if (db.OpenDatabase("/home/birdhead/test.db") != 0) {
                        qWarning() << "DB open failed for study processing, StudyIndex:" << nStudyIndex;
                        return; // 또는 다른 오류 처리
                    }

                    // 2. 새로운 API를 사용합니다. 함수가 직접 결과 "값"을 반환합니다.
                    QList<QStringList> listResponse = db.GetImageWithStudyIndexASC(nStudyIndex);

                    int nTotalCount = listResponse.size();

                    if (nTotalCount > 0)
                    {
                        // 3. 동일한 지역 DB 인스턴스를 사용하여 다음 DB 작업을 수행합니다.
                        db.AddImageToAcquisitionTemp(nStudyIndex);

                        usleep(10 * 1000);

                        // 4. 다른 스레드로 데이터를 넘겨줄 때도 값으로 넘겨줍니다.
                        //    (참고: pThreadImageSave의 SetListImageWithStudyASC 함수 시그니처도
                        //     const QList<QStringList>& 타입으로 변경하는 것이 가장 이상적입니다.)
                        pThreadImageSave->SetListImageWithStudyASC(listResponse);
                        pThreadImageSave->ChangeState(0x200);

                        while (pThreadImageSave->GetCurrentState() != 0x2000)
                        {
                            QThread::usleep(1000 * 100);
                        }
                        pThreadImageSave->ChangeState(0);
                    }

                    // 5. 더 이상 수동으로 메모리를 해제할 필요가 없습니다.
                    // SDatabase::DeleteListReponse(listResponse); // 이 줄은 완전히 제거됩니다.
                }

            }

            m_nCurrentMenuID = (m_nCurrentMenuID | SMENU_CAPTURE);
            FormCapture* pCapture = (FormCapture*)m_ListWidget[m_nCurrentWidgetID];
            pCapture->Init();
            pCapture->show();
            pCapture->setFocus();

            /*
            if(m_pCommonData->IsAutoVideoCapture()==true)
            {
                //m_pCommonData->GetThreadRTSP()->ChangeState(0);
                QString strVideoFilename = m_pCommonData->GetNewFilename(DISPLAY_VIDEO);
                m_pCommonData->GetThreadRTSP()->SaveFile(strVideoFilename);
                m_pCommonData->GetThreadRTSP()->ChangeState(6);
            }
            else
            {
                m_pCommonData->GetThreadRTSP()->ChangeState(0);
            }
            */

            m_pCommonData->GetThreadRTSP()->ChangeState(0);

            usleep(1*1000);
        }
        else if(nID==SMENU_VIEWER)
        {
            HISTORY_STUDY* pHistoryStudy = m_pCommonData->GetCurrentHistoryStudy();

            if(pHistoryStudy==NULL)
            {
                return;
            }



            //QString strStudyInstanceUID = *pHistoryStudy->pStrStudyInstanceUID;
            //int nStudyIndex = pDatabase->GetStudyIndexWithStudyInstanceUID(strStudyInstanceUID);


            QString strStudyIndex = *pHistoryStudy->pStrStudyIndex;

            m_pCommonData->ReleaseCurrentHistoryStudy();

            int nStudyIndex = strStudyIndex.toInt();

            FormViewer* pViewer = (FormViewer*)m_ListWidget[m_nCurrentWidgetID];            
            m_nCurrentMenuID = (m_nCurrentMenuID | SMENU_VIEWER);

            QDate dateToday = QDate::currentDate();

            int nYear = dateToday.year();
            int nMonth = dateToday.month();
            int nDay = dateToday.day();
            QString strSearchDate = QString("%1/%2/%3-%1/%2/%3").arg(QString::number(nYear).rightJustified(4, '0')).arg(QString::number(nMonth).rightJustified(2, '0')).arg(QString::number(nDay).rightJustified(2, '0'));


            CommonData* pCommonData = MainWindow::GetCommonData();
            pCommonData->ClearHistoryImage();

            pCommonData->ClearHistorySearchItem();
            pCommonData->ClearHistorySearchStudyIndex();



            SEARCH_ITEM si;
            //QList<QStringList*> listResponse;

            si.m_strStudyDate = strSearchDate;
            //si.m_strStudyDate = "2021/08/06-2021/08/12";
            //si.m_strPatientName = "202188";
            int historyCount = 0;
            QList<QStringList> listResponse; // 포인터가 아닌 값 타입의 리스트

            // 1. 이 작업을 위한 지역 DB 인스턴스를 생성하고 연결합니다.
            SUTIL::SDatabase db(QString("HistoryAndImageFetch_%1").arg(reinterpret_cast<quintptr>(this)));
            if (db.OpenDatabase("/home/birdhead/test.db") == 0) // 0이 성공
            {
                // 2. 새로운 GetHistory API를 호출하고, 반환 값을 변수에 저장합니다.
                //    (기존 코드에서는 이 값을 사용하지 않았지만, 필요할 수 있으므로 받아둡니다.)
                historyCount = db.GetHistory(&si);

                // 3. 새로운 GetImageWithStudyIndex API를 호출하여 결과를 직접 받습니다.
                //    더 이상 출력 파라미터나 포인터를 사용하지 않습니다.
                listResponse = db.GetImageWithStudyIndex(nStudyIndex);
            }
            else
            {
                qWarning() << "DB open failed for history/image fetching.";
                // 필요에 따라 오류 처리
            }

            // 이제 'historyCount'와 'listResponse'를 안전하게 사용할 수 있습니다.
            // 예를 들어:
            qDebug() << "Found history items:" << historyCount;
            qDebug() << "Found images in study:" << listResponse.size();

            // 수동 메모리 해제는 더 이상 필요 없습니다.
            // SDatabase::DeleteListReponse(listResponse); // 이 줄은 완전히 제거됩니다.

            pCommonData->SetSearchItemHistory(si);
            pCommonData->SetHistorySearchStudyIndex(nStudyIndex);

            int nImageCount = listResponse.size();



            pViewer->Init();

            pViewer->SetTotalImageCount(nImageCount);
            //pViewer->UpdateViewer();
            pViewer->ChangeViewMode(2);


            SThreadImageSave* pThreadImageSave = m_pCommonData->GetThreadCaptureImage();
            pThreadImageSave->SetListImageWithStudy(listResponse);
            pThreadImageSave->ChangeState(0x08);

            pViewer->show();
            //SDatabase::DeleteListReponse(listResponse);

        }
        return;
    }





}


void MainWindow::ExitCapture()
{
    WRITE_FUNCTION_LOG();

    m_nCurrentMenuID = (m_nCurrentMenuID & ~SMENU_CAPTURE);

    SThreadImageSave* pThreadCaptureImage = m_pCommonData->GetThreadCaptureImage();
    pThreadCaptureImage->ExitCapture();
    pThreadCaptureImage->ClearCaptureSaveToFile();

    FormCapture* pCapture = (FormCapture*)m_ListWidget[m_nCurrentWidgetID];
    if(pCapture->isVisible()==true)
    {
        pCapture->ExitCapture();
        pCapture->hide();
    }

    m_pCommonData->ClearCaptureImage();

    ACQUISITION_INFO* pAcquisitionInfo = m_pCommonData->GetAcquisitionInfo();
    pAcquisitionInfo->Clear();
    m_pCommonData->ReleaseAcquisitionInfo();

    switch(m_nCurrentMenuID)
    {
        case SMENU_WORKLIST:
            m_nCurrentWidgetID = SWIDGET_WORKLIST;
            break;
        case SMENU_HISTORY:
            m_nCurrentWidgetID = SWIDGET_HISTORY;
            break;
        case SMENU_SETTING:
            m_nCurrentWidgetID = SWIDGET_SETTING;
            break;
        case SMENU_CAPTURE:
            m_nCurrentWidgetID = SWIDGET_CAPTURE;
            break;
        case SMENU_VIEWER:
            m_nCurrentWidgetID = SWIDGET_VIEWER;
            break;
    }

    if(m_nCurrentMenuID==0x22)
    {
        ui->widgetMainMenu->SelectWorklist();
        //m_nCurrentMenuID = SMENU_WORKLIST;
        //m_nCurrentWidgetID = SWIDGET_WORKLIST;
        //ChangeMenu(m_nCurrentMenuID);
    }

    m_ListWidget[m_nCurrentWidgetID]->show();

    if(m_nCurrentWidgetID!=SMENU_CAPTURE)
    {
        if(m_pCommonData->GetScreenSaverTime()>0)
        {
            if(m_TimerScreenSaver.isActive()==false)
            {
                ResetScreenSaverTimer();
                StartScreenSaverTimer();
            }
        }

    }

    QWidget* pFocusWidget = focusWidget();

    if(m_nCurrentWidgetID==SWIDGET_WORKLIST)
    {
        FormWorklist* pFormWorklist = (FormWorklist*)m_ListWidget[m_nCurrentWidgetID];

        pFormWorklist->Init();

        repaint();
    }

    if(pFocusWidget!=m_ListWidget[m_nCurrentWidgetID])
    {
        m_ListWidget[m_nCurrentWidgetID]->setFocus(Qt::ActiveWindowFocusReason);
        connect(&m_Timer, SIGNAL(timeout()), this, SLOT(ViewerChangeFocusCheck()));
        m_Timer.start();
    }


    if(m_pCommonData->IsUseWebDisplay()==true)
    {
        if(m_pProcessNode!=NULL)
        {
            if(m_pProcessNode->state()==QProcess::Running)
            {
                m_pProcessNode->close();

                int nCount = 0;

                while(m_pProcessNode->state()==QProcess::Running && nCount<100)
                {
                    usleep(100);
                    nCount++;
                }

                if(m_pProcessNode->state()!=QProcess::Running)
                {
                    m_pProcessNode->start("/usr/bin/node", QStringList("index.js"));
                }
            }
        }
    }

}

void MainWindow::ErrorCapture()
{
    WRITE_FUNCTION_LOG();
    ExitCapture();
}

void MainWindow::ExitViewer()
{
    WRITE_FUNCTION_LOG();
    SThreadImageSave* pThreadImageSave = m_pCommonData->GetThreadCaptureImage();
    if(pThreadImageSave->GetCurrentState()==4)
    {
        pThreadImageSave->StopLoadImage();
        while(pThreadImageSave->GetCurrentState()==4)
        {
            usleep(100*1000);
        }
    }
    m_nCurrentMenuID = (m_nCurrentMenuID & ~SMENU_VIEWER);

    m_ListWidget[m_nCurrentWidgetID]->hide();

    switch(m_nCurrentMenuID)
    {
        case SMENU_WORKLIST:
            m_nCurrentWidgetID = SWIDGET_WORKLIST;
            break;
        case SMENU_HISTORY:
            m_nCurrentWidgetID = SWIDGET_HISTORY;
            ((FormHistory*)m_ListWidget[m_nCurrentWidgetID])->Init();
            break;
        case SMENU_SETTING:
            m_nCurrentWidgetID = SWIDGET_SETTING;
            break;
        case SMENU_CAPTURE:
            m_nCurrentWidgetID = SWIDGET_CAPTURE;
            break;
        case SMENU_VIEWER:
            m_nCurrentWidgetID = SWIDGET_VIEWER;
            break;
    }

    m_ListWidget[m_nCurrentWidgetID]->show();

    m_pCommonData->ClearHistoryImage();
}

void MainWindow::BackupNetworkShareFolder(QString strFilename)
{
    //test samba backup
    DialogExportSamba dlgExport(this);

    QThread::usleep(1000*1000);
    dlgExport.exec();
}


void MainWindow::SetRTSPThread(QRTSPThread* pThread)
{
    m_pCommonData->SetRTSPThread(pThread);

    FormCapture* pCapture = (FormCapture*)m_ListWidget[3];
    pThread->SetVideoWidget(pCapture->GetVideoWidget());
}

void MainWindow::SetThreadCaptureImage(SThreadImageSave* pThread)
{
    m_pCommonData->SetThreadCaptureImage(pThread);

    pThread->OpenDatabase();

    FormCapture* pCapture = (FormCapture*)m_ListWidget[3];
    connect(pThread, SIGNAL(captureImage(CAPTURE_IMAGE*)), pCapture, SLOT(captureImage(CAPTURE_IMAGE*)));
    connect(pThread, SIGNAL(captureVideo(CAPTURE_IMAGE*)), pCapture, SLOT(captureVideo(CAPTURE_IMAGE*)));


    FormViewer* pViewer = (FormViewer*)m_ListWidget[4];
    connect(pThread, SIGNAL(SetImageLoadInfo(int, int, ImageSelect*)), pViewer, SLOT(SetImageLoadInfo(int, int, ImageSelect*)));
    connect(pThread, SIGNAL(ImageLoadComplete()), pViewer, SLOT(ImageLoadComplete()));

    //FormWorklist* pWorklist = (FormWorklist*)m_ListWidget[0];
    //connect(pThread, SIGNAL(worklistUpdateComplete()), pWorklist, SLOT(worklistUpdateComplete()));
    //connect(pThread, SIGNAL(worklistError()), pWorklist, SLOT(worklistError()));
    //connect(pThread, SIGNAL(SetWorklistProgress(int)), pWorklist, SLOT(SetWorklistProgress(int)));


    connect(pThread, SIGNAL(CompleteCleanStorage()), this, SLOT(CompleteCleanStorage()));



    connect(pThread, SIGNAL(CompleteAcquisitionFromHistory()), this, SLOT(CompleteAcquisitionFromHistory()));
    connect(pThread, SIGNAL(LoadInfoAcquisitionFromHistory(int, int)), this, SLOT(LoadInfoAcquisitionFromHistory(int, int)));

    connect(pThread, SIGNAL(ViewDialogMissCapture()), this, SLOT(ViewDialogMissCapture()));
}

void MainWindow::SetThreadSendDICOM(SThreadSendDICOM* pThread)
{
    m_pCommonData->SetThreadSendDICOM(pThread);

    //FormWorklist* pWorklist = (FormWorklist*)m_ListWidget[0];

    //connect(pThread, SIGNAL(worklistUpdateComplete()), pWorklist, SLOT(worklistUpdateComplete()));
    //connect(pThread, SIGNAL(worklistError()), pWorklist, SLOT(worklistError()));
    //connect(pThread, SIGNAL(SetWorklistProgress(int)), pWorklist, SLOT(SetWorklistProgress(int)));
    connect(pThread, SIGNAL(UpdateSendFailed()), this, SLOT(UpdateSendFailed()));
}

void MainWindow::CompleteCleanStorage()
{
    WRITE_FUNCTION_LOG();
    if (m_pDialogStorageClean != NULL) {
        m_pDialogStorageClean->accept();
    }

    // --- 첫 번째 블록: 스케줄에 따른 자동 삭제 ---
    {
        // 1. 이 블록만을 위한 지역 DB 인스턴스 생성
        SUTIL::SDatabase db("AutoRemoveTask");
        if (db.OpenDatabase("/home/birdhead/test.db") == 0)
        {
            // 2. 두 개의 수정 작업을 하나의 트랜잭션으로 묶어 원자성 보장
            db.BeginTransaction();
            bool success1 = db.AutoremoveImageTable();
            // UpdateScheduled... 함수도 이전에 bool을 반환하도록 수정했어야 하나,
            // void라면 일단 호출만 합니다.
            db.UpdateScheduledDeleteCompleteStudyDate();

            // AutoremoveImageTable의 성공 여부에 따라 Commit 결정
            if (success1) {
                db.Commit();
            } else {
                db.Rollback();
            }
        }
    }

    // --- 두 번째 블록: 필요 시 추가 공간 확보 ---
    m_pCommonData->ComputeStorageSize();
    int nStorageFreeSize = m_pCommonData->GetStorageFreeSize();
    const int nRemainSize = 100000; // 100MB

    if (nStorageFreeSize < nRemainSize)
    {
        // 1. 이 블록만을 위한 별도의 지역 DB 인스턴스 생성
        SUTIL::SDatabase db("FreeUpSpaceTask");
        if (db.OpenDatabase("/home/birdhead/test.db") == 0)
        {
            // 2. 새로운 API를 사용하여 파일 목록을 값(QStringList)으로 직접 받음
            QStringList videoFiles = db.GetVideoFileList();

            // 3. 파일 삭제 및 DB 업데이트를 하나의 트랜잭션으로 처리
            db.BeginTransaction();
            bool bSuccess = true;
            for (const QString& strFileLocation : videoFiles)
            {
                bool bFileActuallyDeleted = false;

                if(strFileLocation.contains(MOVIE_FILE_EXTENSION)==true)
                {
                    QString strTest = strFileLocation;
                    QFileInfo fi(strTest);
                    QString strPath = fi.path();
                    QString strFilename = fi.fileName();
                    strFilename = strFilename.replace(MOVIE_FILE_EXTENSION, "");
                    strFilename += "*";

                    QDirIterator itDir(strPath, {strFilename}, QDir::Files);

                    while(itDir.hasNext()==true)
                    {
                        QString strFileDelete = itDir.next();
                        QFile fileRemove(strFileDelete);
                        if(fileRemove.exists()==true)
                        {
                            fileRemove.remove();
                            bFileActuallyDeleted = true;
                        }
                    }
                }
                // ... (기존과 동일한 파일 시스템에서 파일 삭제 로직) ...
                // 이 로직이 성공적으로 파일을 삭제했다면, DB에 업데이트


                if (bFileActuallyDeleted) {
                    // SetDeleteStorageFile 함수도 bool을 반환하도록 수정하는 것이 좋음
                    if (!db.SetDeleteStorageFile(strFileLocation)) {
                        bSuccess = false;
                        break; // DB 업데이트 실패 시 중단
                    }
                }

                // 성능 참고: 이 부분은 여전히 비효율적입니다.
                // 루프 밖에서 한 번만 계산하거나, 10개 파일 처리 후 한 번씩만 계산하는 것이 좋습니다.
                m_pCommonData->ComputeStorageSize();
                if (m_pCommonData->GetStorageFreeSize() >= nRemainSize) {
                    break; // 목표 공간 확보 시 루프 탈출
                }
            }

            if (bSuccess) {
                db.Commit();
            } else {
                db.Rollback();
            }
        }
    }
}

#include "sexception.h"

void MainWindow::DeferredInit()
{
    WRITE_FUNCTION_LOG();
    m_Timer.stop();
    disconnect(&m_Timer, SIGNAL(timeout()), this, SLOT(DeferredInit()));

    ChangeMenu(SMENU_WORKLIST);

    if (m_pCommonData->IsAutoLogin() == false)
    {
        DialogLogin dlgLogin(this);
        dlgLogin.exec();
    }

    SThreadImageSave* pThreadImageSave = m_pCommonData->GetThreadCaptureImage();

    // --- 첫 번째 블록 리팩토링 ---
    {
        // 1. 이 작업을 위한 지역 DB 인스턴스를 생성합니다.
        SUTIL::SDatabase db("DeferredInit_DeleteList_Connection");
        if (db.OpenDatabase("/home/birdhead/test.db") == 0) // 0이 성공
        {
            // 2. 새로운 API를 호출하여 QStringList 값을 직접 받습니다.
            QStringList dateList = db.GetScheduledDeleteStudyDateList();

            // 3. 다른 스레드로 값을 전달합니다.
            // 참고: SetSchduledDeleteStudyDateList의 파라미터도 const QStringList&로 변경해야 합니다.
            pThreadImageSave->SetSchduledDeleteStudyDateList(dateList);
        }
        else
        {
            qWarning() << "DB open failed for GetScheduledDeleteStudyDateList in DeferredInit.";
        }
        // 'db'와 'dateList'는 스코프가 끝나면 자동으로 메모리가 정리됩니다.
        // DeleteListReponse 호출이 필요 없습니다.
    }

    usleep(10 * 1000);

    pThreadImageSave->ChangeState(0x100);

    m_pDialogStorageClean = new DialogProgress(this);
    m_pDialogStorageClean->Init(2);
    m_pDialogStorageClean->exec();

    delete m_pDialogStorageClean;
    m_pDialogStorageClean = NULL;

    if (m_pCommonData->IsUseNetworkBackupVideo() == true)
    {
        // Samba 관련 로직
    }

    // --- 두 번째 블록 리팩토링 ---
    {
        // 1. 별도의 작업을 위한 또 다른 지역 DB 인스턴스를 생성합니다.
        SUTIL::SDatabase db("DeferredInit_MergeTemp_Connection");
        if (db.OpenDatabase("/home/birdhead/test.db") == 0)
        {
            // 2. 이 함수 하나가 데이터 병합과 임시 테이블 정리를 모두 수행합니다.
            db.AddAcquisitionTempToImage();
        }
        else
        {
            qWarning() << "DB open failed for AddAcquisitionTempToImage in DeferredInit.";
        }
        // 'db'는 스코프가 끝나면 자동으로 소멸됩니다.
    }

    m_TimeCheckScreenSaver.start();
    m_TimerScreenSaver.setInterval(1000 * 10);

    if (m_pCommonData->IsUseWebDisplay() == true)
    {
        m_pProcessNode = new QProcess();
        m_pProcessNode->setWorkingDirectory("/home/birdhead/web_display");
        m_pProcessNode->start("/usr/bin/node", QStringList("index.js"));
    }

    UmountDiskUSB("/home/birdhead/backup");
    m_TimerCheckDiskUSB.start(2000);
}

void MainWindow::Exit()
{
    WRITE_FUNCTION_LOG();
    FormWorklist* pWorklist = (FormWorklist*)m_ListWidget[0];
    FormHistory* pHistory = (FormHistory*)m_ListWidget[1];
    FormCapture* pCapture = (FormCapture*)m_ListWidget[3];

    m_pCommonData->GetThreadRTSP()->exitRTSP();

    usleep(1000*1000);

    //pWorklist->Exit();
    //pHistory->Exit();

    m_pCommonData->Exit();
    QApplication::quit();
}


void MainWindow::ViewerChangeFocusCheck()
{
    WRITE_FUNCTION_LOG();
    QWidget* pFocusWidget = focusWidget();

    if(pFocusWidget!=m_ListWidget[m_nCurrentWidgetID])
    {
        usleep(10*1000);
        m_ListWidget[m_nCurrentWidgetID]->setFocus(Qt::ActiveWindowFocusReason);

    }
    else
    {

        m_ListWidget[m_nCurrentWidgetID]->update();
        update();
        disconnect(&m_Timer, SIGNAL(timeout()), this, SLOT(ViewerChangeFocusCheck()));
        m_Timer.stop();
    }
}

void MainWindow::resizeEvent(QResizeEvent *event)
{
    QSize nSize = size();
    if(m_nDisplayType==SDISPLAY_1280X1024)
    {
        //ui->widgetMainMenu->setGeometry(45, 40, 462, 58);
        ui->widgetMainMenu->setGeometry(45, 40, 1190, 58);
        FormWorklist* pWorklist = (FormWorklist*)m_ListWidget[0];
        pWorklist->setGeometry(45, 120, 1190, 864);

        FormHistory* pHistory = (FormHistory*)m_ListWidget[1];
        pHistory->setGeometry(45, 120, 1190, 864);

        FormSetting* pSetting = (FormSetting*)m_ListWidget[2];
        pSetting->setGeometry(45, 120, 1190, 864);

        FormCapture* pCapture = (FormCapture*)m_ListWidget[3];
        pCapture->setGeometry(0, 0, 1280, 1024);

        FormViewer* pViewer = (FormViewer*)m_ListWidget[4];
        pViewer->setGeometry(0, 0, 1280, 1024);

        m_pDialogMissCapture->setGeometry(0, 0, 1280, 1024);
    }
    else if(m_nDisplayType==SDISPLAY_1920X1080)
    {
        ui->widgetMainMenu->setGeometry(58, 58, 573, 70);
        FormWorklist* pWorklist = (FormWorklist*)m_ListWidget[0];
        pWorklist->setGeometry(58, 166, 1808, 857);

        FormCapture* pCapture = (FormCapture*)m_ListWidget[3];
        pCapture->setGeometry(0, 0, 1920, 1080);
    }
}


QWidget* MainWindow::GetFormCapture()
{
    FormCapture* pCapture = (FormCapture*)m_ListWidget[3];

    return pCapture;
}

void MainWindow::UpdateMakeDICOMInfo(int nCurrent, int nTotal)
{
    WRITE_FUNCTION_LOG_PARAM(QString::number(nCurrent) + ", " +QString::number(nTotal));
    if(m_nCurrentWidgetID==SWIDGET_VIEWER)
    {
        FormViewer* pFormViewer = (FormViewer*)m_ListWidget[m_nCurrentWidgetID];
        pFormViewer->UpdateMakeDICOMInfo(nCurrent, nTotal);
    }
    else if(m_nCurrentWidgetID==SWIDGET_CAPTURE)
    {
        FormCapture* pFormCapture = (FormCapture*)m_ListWidget[m_nCurrentWidgetID];
        pFormCapture->UpdateMakeDICOMInfo(nCurrent, nTotal);
    }
}

void MainWindow::UpdateSendInfo(int nCount, int nTotalCount)
{
    WRITE_FUNCTION_LOG_PARAM(QString::number(nCount) + ", " + QString::number(nTotalCount));
    if(m_nCurrentWidgetID==SWIDGET_VIEWER)
    {
        FormViewer* pFormViewer = (FormViewer*)m_ListWidget[m_nCurrentWidgetID];
        pFormViewer->UpdateSendInfo(nCount, nTotalCount);
    }
    else if(m_nCurrentWidgetID==SWIDGET_CAPTURE)
    {
        FormCapture* pFormCapture = (FormCapture*)m_ListWidget[m_nCurrentWidgetID];
        pFormCapture->UpdateSendInfo(nCount, nTotalCount);
    }
    /*
    switch(nID)
    {
        case SMENU_WORKLIST:
            m_nCurrentWidgetID = SWIDGET_WORKLIST;
            break;
        case SMENU_HISTORY:
            m_nCurrentWidgetID = SWIDGET_HISTORY;
            break;
        case SMENU_SETTING:
            m_nCurrentWidgetID = SWIDGET_SETTING;
            break;
        case SMENU_CAPTURE:
            m_nCurrentWidgetID = SWIDGET_CAPTURE;
            break;
        case SMENU_VIEWER:
            m_nCurrentWidgetID = SWIDGET_VIEWER;
            break;
    }
    */
}

void MainWindow::UpdateSendComplete()
{
    WRITE_FUNCTION_LOG();
    if(m_nCurrentWidgetID==SWIDGET_VIEWER)
    {
        FormViewer* pFormViewer = (FormViewer*)m_ListWidget[m_nCurrentWidgetID];
        pFormViewer->UpdateSendComplete();
    }
    else if(m_nCurrentWidgetID==SWIDGET_CAPTURE)
    {
        FormCapture* pFormCapture = (FormCapture*)m_ListWidget[m_nCurrentWidgetID];
        pFormCapture->UpdateSendComplete();
    }
}

void MainWindow::UpdateSendFailed()
{
    WRITE_FUNCTION_LOG();
    if(m_nCurrentWidgetID==SWIDGET_VIEWER)
    {
        FormViewer* pFormViewer = (FormViewer*)m_ListWidget[m_nCurrentWidgetID];
        pFormViewer->UpdateSendFailed();
    }
    else if(m_nCurrentWidgetID==SWIDGET_CAPTURE)
    {
        FormCapture* pFormCapture = (FormCapture*)m_ListWidget[m_nCurrentWidgetID];
        pFormCapture->UpdateSendFailed();
    }
}

void MainWindow::UpdateAutoSendDICOMFailed()
{

}

void MainWindow::ClearHistoryView()
{
    WRITE_FUNCTION_LOG();
    FormHistory* pForm = (FormHistory*)m_ListWidget[SWIDGET_HISTORY];
    pForm->Init();
}

int MainWindow::GetCurrentWidgetID()
{
    return m_nCurrentWidgetID;
}

void MainWindow::DeleteUI()
{
    WRITE_FUNCTION_LOG();
    int i=0;
    for(i=0 ; i<m_ListWidget.size() ; i++)
    {
        QWidget* pWidget = m_ListWidget[i];
        delete pWidget;
    }

    m_ListWidget.clear();

    m_pCommonData->GetThreadRTSP()->ExitThread();
}


void MainWindow::WatchPowerButton()
{

    QSharedMemory shared("SmartQuadra");

    if(shared.create(512, QSharedMemory::ReadWrite)==false)
    {
        //exit(0);

        bool bAttach = shared.attach();

        if(bAttach==true)
        {
            int nSize = shared.size();

            shared.lock();
            {
                const char* pData1 = (const char*)shared.constData();
                int nLength = strlen(pData1);
                if(nLength>0)
                {
                    //Dialog Power Button
                    DialogPowerButton dlg(this);
                    //dlg.setGeometry(0, 0, 1280, 1280);

                    dlg.exec();

                    char* pPipe = (char*)shared.data();
                    memset(pPipe, 0, 512);
                }

            }
            shared.unlock();

            shared.detach();
        }
    }
}


void MainWindow::keyReleaseEvent(QKeyEvent *event)
{
    WRITE_FUNCTION_LOG();
    int nKey = event->key();

    SThreadImageSave* pThread = MainWindow::GetCommonData()->GetThreadCaptureImage();

    if(nKey==Qt::Key_F10)
    {
        pThread->MissCapture();
    }
    else if(nKey==Qt::Key_F11)
    {
        pThread->MissCapture();
    }
}


void MainWindow::ViewDialogMissCapture()
{

    m_TimerMissCapture.start();

    if(m_pDialogMissCapture!=NULL)
    {
        m_pDialogMissCapture->show();
        m_pDialogMissCapture->SetErrorType(0);
    }

}

void MainWindow::MissCapture()
{
    //m_pDialogMissCapture->show();
    m_pDialogMissCapture->exec();

    m_TimerMissCapture.stop();
}

void MainWindow::CompleteAcquisitionFromHistory()
{

}

void MainWindow::LoadInfoAcquisitionFromHistory(int nCurrent, int nTotal)
{
}


void MainWindow::ResetScreenSaverTimer()
{
    m_TimeCheckScreenSaver.restart();
}

void MainWindow::StartScreenSaverTimer()
{
    m_TimerScreenSaver.start();
}

void MainWindow::StopScreenSaverTimer()
{
    m_TimerScreenSaver.stop();
}


void MainWindow::CaptureHandSwitch()
{
    WRITE_FUNCTION_LOG();

    if(m_nCurrentWidgetID==SWIDGET_CAPTURE)
    {
        SendCaptureHandSwitch();
    }
    else
    {
        SThreadImageSave* pThread = MainWindow::GetCommonData()->GetThreadCaptureImage();
        pThread->MissCapture();
    }

}

void MainWindow::CaptureFootSwitch()
{
    WRITE_FUNCTION_LOG();

    if(m_nCurrentWidgetID==SWIDGET_CAPTURE)
    {
        SendCaptureFootSwitch();
    }
    else
    {
        SThreadImageSave* pThread = MainWindow::GetCommonData()->GetThreadCaptureImage();
        pThread->MissCapture();
    }

}

void MainWindow::WriteLogTimer()
{
    if(m_pCommonData->GetLogLevel()==0)
    {
        return;
    }

    QStringList* pListLog = m_pCommonData->GetListLog();

    QString strLog = QString::fromStdString(pListLog->join("").toStdString());
    pListLog->clear();

    m_pCommonData->ReleaseListLog();

    if(strLog.size()>0)
    {
        m_pCommonData->WriteLogFile(strLog);
    }



}


void MainWindow::SetDisplayError(int nTypeError)
{
    m_TimerMissCapture.start();
    if(m_pDialogMissCapture!=NULL)
    {
        m_pDialogMissCapture->show();
        m_pDialogMissCapture->SetErrorType(nTypeError);
    }
}

void MainWindow::SetDisplayError(QString strError)
{
    CommonData::RestartNetworkManager();

    m_TimerMissCapture.start();
    if(m_pDialogMissCapture!=NULL)
    {
        m_pDialogMissCapture->show();
        m_pDialogMissCapture->SetErrorString(strError);
    }


}


void MainWindow::CheckDiskUSB()
{
    bool bExists = false;
    QString strDevice;
#ifdef _PC
    strDevice = "/dev/sdb1";
#else
    strDevice = "/dev/sda1";
#endif

    QFileInfo fi(strDevice);
    bExists = fi.exists();

    if(ui->widgetMainMenu->isVisible()==false)
    {
        return;
    }

    if(bExists==true)
    {
        if(m_bMountDiskUSB==false)
        {
            bool bMount = false;
            QProcess processCheckMount;
            processCheckMount.start("mount");
            while(processCheckMount.waitForStarted(100)==false)
            {
                usleep(1000);
            }
            bool retval = false;
            QByteArray buffer;

            while ((retval = processCheckMount.waitForFinished(100)))
            {
                usleep(1000);
            }
            buffer.append(processCheckMount.readAll());

            processCheckMount.terminate();
            processCheckMount.waitForFinished(100);
            processCheckMount.deleteLater();

            QString strDeviceMount;
            QString strLocationMount;
            QString strBufferMount = buffer.toStdString().c_str();
            QStringList listMount = strBufferMount.split("\n");

            if(strBufferMount.contains(strDevice)==true)
            {
                int i=0;

                for(i=0 ; i<listMount.size() ; i++)
                {
                    QString strTmpMount = listMount[i];
                    if(strTmpMount.contains(strDevice)==true)
                    {
                        QStringList listDeviceMount = strTmpMount.split(" ");
                        int j=0;
                        strDeviceMount = listDeviceMount[0];

                        if(listDeviceMount.size()>=6)
                        {
                            for(j=2 ; j<listDeviceMount.size()-3 ; j++)
                            {
                                strLocationMount += listDeviceMount[j];
                                if(j<listDeviceMount.size()-4)
                                {
                                    strLocationMount += " ";
                                }
                            }
                        }
                        break;

                    }
                }
                //Already mounted
                bMount = true;
            }
            buffer.clear();

            if(bMount==true)
            {
                if(strLocationMount!="/home/birdhead/backup")
                {
                    //umount
                    UmountDiskUSB(strLocationMount);
                    MountDiskUSB(strDevice, "/home/birdhead/backup");
                }
            }
            else
            {
                MountDiskUSB(strDevice, "/home/birdhead/backup");
            }

            m_bMountDiskUSB = true;


            ui->widgetMainMenu->SetEnableDiskUSB(true);
        }

    }
    else
    {
        if(m_bMountDiskUSB==true)
        {
            UmountDiskUSB("/home/birdhead/backup");
        }
        ui->widgetMainMenu->SetEnableDiskUSB(false);
        m_bMountDiskUSB = false;
    }
}

void MainWindow::MountDiskUSB(QString strDeviceMount, QString strLocationMount)
{
    QString strCommand;
    strCommand = QString("sudo -S mount %1 %2").arg(strDeviceMount).arg(strLocationMount);

    CommandSudo(strCommand);
}

void MainWindow::UmountDiskUSB(QString strLocationMount)
{
    QString strCommand;
    strCommand = QString("sudo -S umount %1").arg(strLocationMount);

    CommandSudo(strCommand);
}


void MainWindow::CommandSudo(QString strCommand)
{
    bool retval = false;
    QByteArray buffer;

    QProcess process1;
    QProcess process2;

    process1.setStandardOutputProcess(&process2);

    process1.start("echo 1");


    process2.start(strCommand);
    process2.setProcessChannelMode(QProcess::ForwardedChannels);



    // Wait for it to start
    if(!process1.waitForStarted())
        return;


    // To be fair: you only need to wait here for a bit with shutdown,
    // but I will still leave the rest here for a generic solution
    while ((retval = process2.waitForFinished()))
    {
        buffer.append(process2.readAll());
    }


    process1.terminate();
    process2.terminate();

    process1.waitForFinished(100);
    process2.waitForFinished(100);

    process1.deleteLater();
    process2.deleteLater();

    buffer.clear();
}
