#include "commondata.h"

#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#include <QDir>
#include <QDirIterator>
#include <QStorageInfo>
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QSqlRecord>

#include "mainwindow.h"

#include <jpeglib.h> //-ljpeg


CommonData::CommonData()
{
    m_bUseWebDisplay = true;

    //m_pDatabase = new SDatabase("CommonData");
    //m_pDatabase->OpenDatabase("/home/birdhead/test.db");

    m_pLogFile = NULL;
    if(m_pLogFile==NULL)
    {
        QDir dirLog("/home/birdhead/Log");
        if(dirLog.exists()==false)
        {
            QDir().mkdir("/home/birdhead/Log");
        }

        QString strLogFile = QString("/home/birdhead/Log/%1.log").arg(QDateTime::currentDateTime().toString("yyyyMMdd_HHmmss"));

        m_pLogFile = new QFile(strLogFile);
        m_pLogFile->open(QFile::ReadWrite | QFile::Unbuffered);
    }

    /*
#ifdef _SAVE_LOG
    QDir().mkdir("Log");
    QString strLogFile = QString("Log/%1.log").arg(QDateTime::currentDateTime().toString("yyyyMMdd_HHmmss"));

    m_pLogFile = new QFile(strLogFile);
    m_pLogFile->open(QFile::ReadWrite | QFile::Unbuffered);
#endif
*/

    m_bConnectHDMI = false;

#ifdef _4K
    m_nVideoWidth = 3840;
    m_nVideoHeight = 2160;
#else
    m_nVideoWidth = 1920;
    m_nVideoHeight = 1080;
#endif


    m_pBitmapData = new uint8_t[m_nVideoWidth*m_nVideoHeight*3+1000];

    m_nGPIO_Buzzer = 0;
    m_nVideoMode = 0;
    m_nCropMode = 0;
    m_nUseFixWidthLevel = 0;
    m_nUseLogLevel = 0;

    m_nUseUSBBackup = 0;


    m_nScreenSaverTime = 0;


    m_pSambaClient = NULL;
    m_bAutoExitCaptureSendDICOM = false;
    m_bAutoCaptureSendDICOM = false;
    m_bAutoVideoCapture = false;
    m_bAutoLogin = false;

    m_bActiveDetect = false;

    m_bAutoCloseSendFinish = false;

    m_nGPIO_HandSwitch = 0;


    m_nSearchItemHistoryStudyIndex = -1;

    m_bIsCapturing = false;

    m_strImageExtension = "jpg";
    //m_strImageExtension = "bmp";




    m_pDCMWorklist = new SDCMWorklist;

    m_pListHistorySearch = new vector<HISTORY_STUDY*>;

    m_pListHistoryImage = new vector<ImageSelect*>;


    m_pWorklistData = new vector<WorklistResponseData>;
    m_pDCMDumpList = new vector<CSDCM*>;
    m_pFindSCUDataCallback = new SDCMFindSCUDataCallback(m_pDCMWorklist->GetExtractMode(), m_pDCMWorklist->GetCancelAfterNResponses());

    m_pFindSCUDataCallback->SetWorklistData(m_pWorklistData);
    m_pFindSCUDataCallback->SetWorklistDump(m_pDCMDumpList);

    m_pCurrentWorklist = NULL;

    m_pRTSPThread = NULL;

    m_pListCaptureImage = new vector<CAPTURE_IMAGE*>;

    m_pImageCapture = new RGB_Data[m_nVideoWidth*m_nVideoHeight];
    memset(m_pImageCapture, 0, sizeof(RGB_Data)*m_nVideoWidth*m_nVideoHeight);

    m_strStorageDirectory = "/home/birdhead/test_save";

    m_pCurrentHistoryStudy = NULL;

    m_bVideoEncoding = false;

    m_pWorklistTableHeader = new STableHeader;
    m_pHistoryTableHeader = new STableHeader;



    QDate dt = QDate::currentDate();
    SetDateSearchWorklistStart(dt);
    SetDateSearchWorklistEnd(dt);
    SetDateSearchHistoryStart(dt);
    SetDateSearchHistoryEnd(dt);

    InitWorklistIndex();
    InitHistoryIndex();
    InitSetting();
    //m_pWorklistTableHeader->UpdateTableHeaderInfo(m_MapWorklistIndex);

#ifdef _XAVIER_NX
    //m_nGPIO_Buzzer = open("/sys/class/gpio/gpio393/value", O_WRONLY);
    m_strGPIOBeep = "/sys/class/gpio/gpio393/value";
    m_strGPIOHandSwitch = "/sys/class/gpio/gpio271/value";
#endif
#ifdef _JETSON_TX2_NX
    m_strGPIOBeep = "/sys/class/gpio/gpio269/value";
    m_strGPIOHandSwitch = "/sys/class/gpio/gpio341/value";
#endif

    if(m_strGPIOBeep.size()>0)
    {
        m_nGPIO_Buzzer = open(m_strGPIOBeep.toUtf8(), O_WRONLY);

        if(m_nGPIO_Buzzer==-1)
        {

        }
    }





    ComputeStorageSize();
}



CommonData::~CommonData()
{
    SAFE_ARRAY_DELETE(m_pBitmapData);

    SAFE_ARRAY_DELETE(m_pImageCapture);

    //SAFE_DELETE(m_pDatabase);

    SAFE_DELETE(m_pWorklistTableHeader);
    SAFE_DELETE(m_pHistoryTableHeader);

    ClearHistorySearchResult();
    SAFE_DELETE(m_pListHistorySearch);

    ClearHistoryImage();
    SAFE_DELETE(m_pListHistoryImage);

    ClearCaptureImage();
    SAFE_DELETE(m_pListCaptureImage);

    SAFE_DELETE(m_pFindSCUDataCallback);
    SAFE_DELETE(m_pDCMWorklist);

    SAFE_DELETE(m_pWorklistData);
    SAFE_DELETE(m_pDCMDumpList);

    if(m_nGPIO_Buzzer>0)
    {
        close(m_nGPIO_Buzzer);
    }


    if(m_pLogFile!=NULL)
    {
        m_pLogFile->flush();
        m_pLogFile->close();

        SAFE_DELETE(m_pLogFile);
    }

    STableHeader::ClearMapData();

}

QDate CommonData::GetDateSearchWorklistStart()
{
    return m_SearchDateWorklist.m_DateStart;
}

QDate CommonData::GetDateSearchWorklistEnd()
{
    return m_SearchDateWorklist.m_DateEnd;
}

void CommonData::SetDateSearchWorklistStart(QDate date)
{
    m_SearchDateWorklist.m_DateStart = date;
}

void CommonData::SetDateSearchWorklistEnd(QDate date)
{
    m_SearchDateWorklist.m_DateEnd = date;
}

QString CommonData::GetStorageDirectory()
{
    return m_strStorageDirectory;
}

QDate CommonData::GetDateSearchHistoryStart()
{
    return m_SearchDateHistory.m_DateStart;
}

QDate CommonData::GetDateSearchHistoryEnd()
{
    return m_SearchDateHistory.m_DateEnd;
}

void CommonData::SetDateSearchHistoryStart(QDate date)
{
    m_SearchDateHistory.m_DateStart = date;
}

void CommonData::SetDateSearchHistoryEnd(QDate date)
{
    m_SearchDateHistory.m_DateEnd = date;
}

SEARCH_ITEM* CommonData::GetSearchItemWorklist()
{
    return &m_SearchItemWorklist;
}

SDCMFindSCUDataCallback* CommonData::GetFindSCUDataCallback()
{
    return m_pFindSCUDataCallback;
}

vector<WorklistResponseData>* CommonData::GetWorklistData()
{
    m_LockWorklistData.lock();
    return m_pWorklistData;
}

void CommonData::ReleaseWorklistData()
{
    m_LockWorklistData.unlock();
}

vector<CSDCM*>* CommonData::GetWorklistDump()
{
    return m_pDCMDumpList;
}

void CommonData::SetRTSPThread(QRTSPThread* pThread)
{
    m_pRTSPThread = pThread;
}

QRTSPThread* CommonData::GetThreadRTSP()
{
    return m_pRTSPThread;
}

void CommonData::SetThreadCaptureImage(SThreadImageSave* pThread)
{
    m_pThreadCaptureImage = pThread;
}

void CommonData::SetThreadSendDICOM(SThreadSendDICOM* pThread)
{
    m_pThreadSendDICOM = pThread;
}

void CommonData::SetThreadWorklistSearch(SThreadWorklistSearch* pThread)
{
    m_pThreadWorklistSearch = pThread;
}

SThreadImageSave* CommonData::GetThreadCaptureImage()
{
    return m_pThreadCaptureImage;
}

SThreadSendDICOM* CommonData::GetThreadSendDICOM()
{
    return m_pThreadSendDICOM;
}

SThreadWorklistSearch* CommonData::GetThreadWorklistSearch()
{
    return m_pThreadWorklistSearch;
}

void CommonData::AddCaptureImageWithHistory()
{
    int i=0;
    ClearCaptureImage();

    int nImages = m_pListHistoryImage->size();

    QImage* pImageTmp = NULL;

    m_LockAddHistory.lock();

    for(i=0 ; i<nImages ; i++)
    {
        ImageSelect* pImageHistory = (*m_pListHistoryImage)[nImages-1-i];
        QString strDate = pImageHistory->m_strDate;
        QString strTime = pImageHistory->m_strTime;
        int nWidth = pImageHistory->GetWidth();
        int nHeight = pImageHistory->GetHeight();
        QImage::Format fmt = (QImage::Format)pImageHistory->GetFormat();
        int nType = pImageHistory->m_nType;
        QString strFilename = pImageHistory->m_strFile;
        bool bDelete = pImageHistory->m_bDelete;

        QString strTimeFormat = "yyyyMMdd HHmmss";
        QString strDateTime = QString("%1 %2").arg(strDate).arg(strTime);
        QDateTime dtCapture = QDateTime::fromString(strDateTime, strTimeFormat);

        CAPTURE_IMAGE* pImageNew = new CAPTURE_IMAGE;
        pImageNew->m_nAcquisitionNumber = pImageHistory->m_nImageNumber;
        pImageNew->m_bDelete = pImageHistory->m_bDelete;
        pImageNew->m_bSend = pImageHistory->m_bSend;
        pImageNew->m_bBackup = true;
        pImageNew->m_pImageSmall = new QImage(nWidth/4, nHeight/4, fmt);

        if(pImageTmp==NULL)
        {
            pImageTmp = new QImage(nWidth, nHeight, fmt);
        }
        else
        {
            if(pImageTmp->width()!=nWidth || pImageTmp->height()!=nHeight || pImageTmp->format()!=fmt)
            {
                SAFE_DELETE(pImageTmp);
                pImageTmp = new QImage(nWidth, nHeight, fmt);
            }
        }

        {
            uint8_t* pImageData = pImageTmp->bits();

            memcpy(pImageData, pImageHistory->m_pImageData, nWidth*nHeight*3);

            //
            QImage imgSmall = pImageTmp->scaled(nWidth/4, nHeight/4);
            *pImageNew->m_pImageSmall = imgSmall.copy();
            SAFE_ARRAY_DELETE(pImageNew->m_pImageCaptureRaw);
            SAFE_ARRAY_DELETE(pImageNew->m_pImageCaptureColor);

            imgSmall.detach();

        }



        bool bTest = true;

        if(bTest==true)
        {

            //CAPTURE_IMAGE* pImageNew = AddCaptureImage(pImageOri->bits(), nWidth, nHeight, pImageHistory->m_nType);





            pImageNew->m_DateTime = dtCapture;//QDateTime::currentDateTime();
            pImageNew->m_nType = (DISPLAY_TYPE)nType;


            pImageNew->m_strImageFilename = strFilename;
            if(pImageNew->m_nType==DISPLAY_VIDEO)
            {
                pImageNew->m_strVideoFilename = strFilename;
                pImageNew->m_strVideoFilename.replace(".bmp", MOVIE_FILE_EXTENSION);
                pImageNew->m_strVideoFilename.replace(".jpg", MOVIE_FILE_EXTENSION);
                pImageNew->m_strVideoFilename.replace(".png", MOVIE_FILE_EXTENSION);
            }
            pImageNew->m_bCheck = true;
            pImageNew->m_nType = (DISPLAY_TYPE)nType;
            pImageNew->m_bDelete = bDelete;
            pImageNew->m_bSaveFile = true;
            pImageNew->m_nIndex = i;

            m_LockAddCapture.lock();
            m_pListCaptureImage->push_back(pImageNew);
            m_LockAddCapture.unlock();


        }
    }
    SAFE_DELETE(pImageTmp);
    m_LockAddHistory.unlock();

    ClearHistoryImage();
}

vector<CAPTURE_IMAGE*>* CommonData::GetListCaptureImage()
{
    m_LockAddCapture.lock();
    return m_pListCaptureImage;
}

void CommonData::ReleaseListCaptureImage()
{
    m_LockAddCapture.unlock();
}

void CommonData::ClearCaptureImage()
{
    m_LockAddCapture.lock();
    {
        int i=0;
        for(i=0 ; i<m_pListCaptureImage->size() ; i++)
        {
            CAPTURE_IMAGE* pCaptureImage = (*m_pListCaptureImage)[i];
            if(pCaptureImage!=NULL)
            {
                if(pCaptureImage->m_pImage!=NULL)
                {
                    //pCaptureImage->m_pImage->detach();
                }
                if(pCaptureImage->m_pImageSmall!=NULL)
                {
                    //pCaptureImage->m_pImageSmall->detach();
                }
                SAFE_DELETE(pCaptureImage->m_pImage);
                SAFE_DELETE(pCaptureImage->m_pImageSmall);
                SAFE_ARRAY_DELETE(pCaptureImage->m_pImageCaptureRaw);
                SAFE_ARRAY_DELETE(pCaptureImage->m_pImageCaptureColor);
                SAFE_ARRAY_DELETE(pCaptureImage->m_pImageData);

                SAFE_DELETE(pCaptureImage);
            }

        }
        m_pListCaptureImage->clear();

        //SAFE_DELETE(m_pListCaptureImage);
        //m_pListCaptureImage = new vector<CAPTURE_IMAGE*>;
    }
    m_LockAddCapture.unlock();
}

CAPTURE_IMAGE* CommonData::AddCaptureImage(uint8_t* pData, int nWidth, int nHeight, int nCaptureType)
{
    CAPTURE_IMAGE* pCaptureImage = NULL;
    m_LockAddCapture.lock();
    {
        pCaptureImage = new CAPTURE_IMAGE;
        pCaptureImage->m_DateTime = QDateTime::currentDateTime();
        pCaptureImage->m_nType = (DISPLAY_TYPE)nCaptureType;
        if(nWidth>0 && nHeight>0 && pData!=NULL)
        {
            pCaptureImage->m_pImageCaptureRaw = NULL;
            pCaptureImage->m_pImageCaptureRaw = new uint8_t[nWidth*nHeight*2];
            memset(pCaptureImage->m_pImageCaptureRaw, 0, sizeof(uint8_t)*nWidth*nHeight*2);
            memcpy(pCaptureImage->m_pImageCaptureRaw, pData, sizeof(uint8_t)*nWidth*nHeight*2);
        }
        else
        {
            pCaptureImage->m_pImageCaptureRaw = NULL;
            if(nWidth>0 && nHeight>0)
            {
                pCaptureImage->m_pImageCaptureRaw = new uint8_t[nWidth*nHeight*2];
                memset(pCaptureImage->m_pImageCaptureRaw, 0, sizeof(uint8_t)*nWidth*nHeight*2);
            }
        }



        {
            m_pListCaptureImage->push_back(pCaptureImage);
        }
    }
    m_LockAddCapture.unlock();


    return pCaptureImage;
}

uint8_t* CommonData::ConvertColor(uint8_t* pData, int nWidth, int nHeight)
{
    int i=0;
    int j=0;

    for(i=0 ; i<nHeight ; i++)
    {
        int nIndex = 0;
        for(j=0 ; j<nWidth/2 ; j++)
        {

            //UYVY
            float fU = (float)pData[i*m_nVideoWidth*2+j*4+0] / 255.0f;
            float fY1 = (float)pData[i*m_nVideoWidth*2+j*4+1] / 255.0f;
            float fV = (float)pData[i*m_nVideoWidth*2+j*4+2] / 255.0f;
            float fY2 = (float)pData[i*m_nVideoWidth*2+j*4+3] / 255.0f;

            float fR = 0;
            float fG = 0;
            float fB = 0;

            fY1=1.1643*(fY1-0.0625);
            fY2=1.1643*(fY2-0.0625);
            fU=fU-0.5;
            fV=fV-0.5;

            fR = CLAMP(fY1+1.5958*fV, 0.0, 1.0);
            fG = CLAMP(fY1-0.39173*fU-0.81290*fV, 0.0, 1.0);
            fB = CLAMP(fY1+2.017*fU, 0.0, 1.0);

            m_pImageCapture[i*nWidth+nIndex].r = fR*255;
            m_pImageCapture[i*nWidth+nIndex].g = fG*255;
            m_pImageCapture[i*nWidth+nIndex].b = fB*255;
            nIndex++;

            fR = CLAMP(fY2+1.5958*fV, 0.0, 1.0);
            fG = CLAMP(fY2-0.39173*fU-0.81290*fV, 0.0, 1.0);
            fB = CLAMP(fY2+2.017*fU, 0.0, 1.0);

            m_pImageCapture[i*nWidth+nIndex].r = fR*255;
            m_pImageCapture[i*nWidth+nIndex].g = fG*255;
            m_pImageCapture[i*nWidth+nIndex].b = fB*255;
            nIndex++;

        }
    }

    return (uint8_t*)m_pImageCapture;
}

void CommonData::ConvertColor2(uint8_t* pSrcData, uint8_t* pDestData, int nOffsetX, int nOffsetY, int nWidth, int nHeight)
{
    int i=0;
    int j=0;

    RGB_Data* pColorData = (RGB_Data*)pDestData;

    for(i=0 ; i<nHeight ; i++)
    {
        int nIndex = 0;
        for(j=0 ; j<nWidth/2 ; j++)
        {

            //UYVY
            float fU = (float)pSrcData[(i+nOffsetY)*m_nVideoWidth*2+(nOffsetX*2+j*4+0)] / 255.0f;
            float fY1 = (float)pSrcData[(i+nOffsetY)*m_nVideoWidth*2+(nOffsetX*2+j*4+1)] / 255.0f;
            float fV = (float)pSrcData[(i+nOffsetY)*m_nVideoWidth*2+(nOffsetX*2+j*4+2)] / 255.0f;
            float fY2 = (float)pSrcData[(i+nOffsetY)*m_nVideoWidth*2+(nOffsetX*2+j*4+3)] / 255.0f;

            float fR = 0;
            float fG = 0;
            float fB = 0;

            fY1=1.1643*(fY1-0.0625);
            fY2=1.1643*(fY2-0.0625);
            fU=fU-0.5;
            fV=fV-0.5;

            fR = CLAMP(fY1+1.5958*fV, 0.0, 1.0);
            fG = CLAMP(fY1-0.39173*fU-0.81290*fV, 0.0, 1.0);
            fB = CLAMP(fY1+2.017*fU, 0.0, 1.0);

            pColorData[i*nWidth+nIndex].r = fR*255;
            pColorData[i*nWidth+nIndex].g = fG*255;
            pColorData[i*nWidth+nIndex].b = fB*255;
            nIndex++;

            fR = CLAMP(fY2+1.5958*fV, 0.0, 1.0);
            fG = CLAMP(fY2-0.39173*fU-0.81290*fV, 0.0, 1.0);
            fB = CLAMP(fY2+2.017*fU, 0.0, 1.0);

            pColorData[i*nWidth+nIndex].r = fR*255;
            pColorData[i*nWidth+nIndex].g = fG*255;
            pColorData[i*nWidth+nIndex].b = fB*255;
            nIndex++;

        }
    }
}

QString CommonData::GetNewFilename(int nType)
{
    QString strFile;
    QDateTime dt = QDateTime::currentDateTime();

    int nYear = dt.date().year();
    int nMonth = dt.date().month();
    int nDay = dt.date().day();

    int nMaxIndex = 0;
    QString strStorageDirectory = "/data";
    QString strDirectoryImage;
    QString strImageExtention;


    ACQUISITION_INFO* pAcquisitionInfo = GetAcquisitionInfo();

    if(nType==DISPLAY_IMAGE)
    {
        strDirectoryImage = QString("%1/image").arg(strStorageDirectory);
        strImageExtention = m_strImageExtension;
        nMaxIndex = (++pAcquisitionInfo->m_nAcquisitionImageMax);
    }
    else if(nType==DISPLAY_VIDEO)
    {
        strDirectoryImage = QString("%1/video").arg(strStorageDirectory);
        strImageExtention = "mp4";
        nMaxIndex = (++pAcquisitionInfo->m_nAcquisitionVideoMax);
    }

    SDATA_PATIENT* pPatientInfo = pAcquisitionInfo->GetPatientInfo();
    QString strPatientID = pPatientInfo->strPatientID;

    ReleaseAcquisitionInfo();


    //QString strStorageDirectory = pMainWindow->GetStorageDirectory();


    QString strDirectoryDate = QString("%1/%2%3%4").arg(strDirectoryImage).arg(QString::number(nYear).rightJustified(4, '0')).arg(QString::number(nMonth).rightJustified(2, '0'))
            .arg(QString::number(nDay).rightJustified(2, '0'));

    if(strPatientID.size()<1)
    {
        strPatientID = "unknown";
    }

    QString strDirectoryPatient = QString("%1/%2").arg(strDirectoryDate).arg(strPatientID);


    uint captureTime = dt.toMSecsSinceEpoch();

    QDir().mkdir(strDirectoryImage);
    QDir().mkdir(strDirectoryDate);
    QDir().mkdir(strDirectoryPatient);

    vector<CAPTURE_IMAGE*>::iterator it;

    strFile = QString("%1/%2_%3.%4").arg(strDirectoryPatient).arg(QString::number(nMaxIndex)).arg(QString::number(captureTime)).arg(strImageExtention);

    m_LockAddCapture.lock();

    int nCheckCount = -1;
    for(it=m_pListCaptureImage->begin() ; it!=m_pListCaptureImage->end() ; ++it)
    {
        CAPTURE_IMAGE* pCheckImage = *it;
        if(pCheckImage->m_strImageFilename==strFile)
        {
            nCheckCount++;

            strFile = QString("%1/%2_%3_%4.%5").arg(strDirectoryPatient).arg(QString::number(nMaxIndex)).arg(QString::number(captureTime)).arg(QString::number(nCheckCount)).arg(strImageExtention);

        }
    }

    m_LockAddCapture.unlock();


    return strFile;
}

bool CommonData::ConvertCaptureImage(CAPTURE_IMAGE* pCaptureImage, int nWidth, int nHeight)
{
    int i=0;
    int j=0;

    pCaptureImage->m_bSaveFile = false;

    if(pCaptureImage->m_pImageCaptureRaw==NULL)
    {
        pCaptureImage->m_pImageCaptureRaw = new uint8_t[m_nVideoWidth*m_nVideoHeight*2];
    }

    uint8_t* pData = pCaptureImage->m_pImageCaptureRaw;

    memset(m_pImageCapture, 0, sizeof(RGB_Data)*m_nVideoWidth*m_nVideoHeight);

    for(i=0 ; i<nHeight ; i++)
    {
        int nIndex = 0;
        for(j=0 ; j<nWidth/2 ; j++)
        {

            //UYVY
            float fU = (float)pData[i*nWidth*2+j*4+0] / 255.0f;
            float fY1 = (float)pData[i*nWidth*2+j*4+1] / 255.0f;
            float fV = (float)pData[i*nWidth*2+j*4+2] / 255.0f;
            float fY2 = (float)pData[i*nWidth*2+j*4+3] / 255.0f;


            /*
            //YUY2
            float fY1 = (float)pData[i*nWidth*2+j*4+0] / 255.0f;
            float fU = (float)pData[i*nWidth*2+j*4+1] / 255.0f;
            float fY2 = (float)pData[i*nWidth*2+j*4+2] / 255.0f;
            float fV = (float)pData[i*nWidth*2+j*4+3] / 255.0f;
            */

            float fR = 0;
            float fG = 0;
            float fB = 0;

            fY1=1.1643*(fY1-0.0625);
            fY2=1.1643*(fY2-0.0625);
            fU=fU-0.5;
            fV=fV-0.5;

            fR = CLAMP(fY1+1.5958*fV, 0.0, 1.0);
            fG = CLAMP(fY1-0.39173*fU-0.81290*fV, 0.0, 1.0);
            fB = CLAMP(fY1+2.017*fU, 0.0, 1.0);

            m_pImageCapture[i*nWidth+nIndex].b = fR*255;
            m_pImageCapture[i*nWidth+nIndex].g = fG*255;
            m_pImageCapture[i*nWidth+nIndex].r = fB*255;
            nIndex++;

            fR = CLAMP(fY2+1.5958*fV, 0.0, 1.0);
            fG = CLAMP(fY2-0.39173*fU-0.81290*fV, 0.0, 1.0);
            fB = CLAMP(fY2+2.017*fU, 0.0, 1.0);

            m_pImageCapture[i*nWidth+nIndex].b = fR*255;
            m_pImageCapture[i*nWidth+nIndex].g = fG*255;
            m_pImageCapture[i*nWidth+nIndex].r = fB*255;
            nIndex++;

        }
    }

    SAFE_ARRAY_DELETE(pCaptureImage->m_pImageCaptureRaw);
    SAFE_ARRAY_DELETE(pCaptureImage->m_pImageCaptureColor);

    QString strFile = GetNewFilename(DISPLAY_IMAGE);

    pCaptureImage->m_bCheck = true;
    pCaptureImage->m_strImageFilename = strFile;

    ACQUISITION_INFO* pAcquisitionInfo = GetAcquisitionInfo();
    {
        if(pCaptureImage->m_nType==DISPLAY_VIDEO)
        {
            QString strVideo = pCaptureImage->m_strVideoFilename;
            QString strImageExtention = m_strImageExtension;

            if(strVideo.size()==0)
            {
                strVideo = GetNewFilename(DISPLAY_VIDEO);
                pCaptureImage->m_strVideoFilename = strVideo;
            }

            strFile = strVideo.replace("mp4", strImageExtention);

            pCaptureImage->m_strImageFilename = strFile;
            pCaptureImage->m_nAcquisitionNumber = pAcquisitionInfo->m_nAcquisitionVideoMax;
        }
        else
        {
            pCaptureImage->m_nAcquisitionNumber = pAcquisitionInfo->m_nAcquisitionImageMax;
        }
    }
    ReleaseAcquisitionInfo();

    bool bCreateBitmapFile = false;

    for(i=0 ; i<10 && bCreateBitmapFile==false ; i++)
    {
        if(m_strImageExtension=="bmp")
        {
            bCreateBitmapFile = WriteBitmapFile(pCaptureImage->m_strImageFilename, (uint8_t*)m_pImageCapture, nWidth, nHeight);
        }
        else if(m_strImageExtension=="jpg")
        {
            bCreateBitmapFile = WriteJPEG(pCaptureImage->m_strImageFilename, (uint8_t*)m_pImageCapture, nWidth, nHeight, 100);
        }

        if(bCreateBitmapFile==false)
        {
            usleep(1000*10);
        }
    }

    //bCreateBitmapFile = false;
    if(bCreateBitmapFile==false)
    {
        MainWindow* pMainWindow = MainWindow::GetMainWindow();
        pMainWindow->SetDisplayError(0x04);

        return false;
    }

    pCaptureImage->m_bSaveFile = true;

    pCaptureImage->m_pImage = new QImage(pCaptureImage->m_strImageFilename);

    if(m_nCropMode==true)
    {
        int nSaveWidth = 1376;
        int nSaveHeight = 992;
        *pCaptureImage->m_pImage = pCaptureImage->m_pImage->copy(QRect(242, 5, nSaveWidth, nSaveHeight));
        pCaptureImage->m_pImageSmall = new QImage(nSaveWidth/4, nSaveHeight/4, pCaptureImage->m_pImage->format());
        *pCaptureImage->m_pImageSmall = pCaptureImage->m_pImage->scaled(pCaptureImage->m_pImage->width()/4, pCaptureImage->m_pImage->height()/4, Qt::IgnoreAspectRatio, Qt::SmoothTransformation).copy();
    }
    else
    {
        QImage image = pCaptureImage->m_pImage->scaled(nWidth/4, nHeight/4, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
        pCaptureImage->m_pImageSmall = new QImage(nWidth/4, nHeight/4, image.format());
        *pCaptureImage->m_pImageSmall = image.copy();
    }







    pAcquisitionInfo = GetAcquisitionInfo();
    if(pAcquisitionInfo->GetPatientInfo()->strPatientID.length() > 0 &&
            pAcquisitionInfo->GetPatientInfo()->strPatientName.length() >0)
    {
        pAcquisitionInfo->m_strImageFilename = pCaptureImage->m_strImageFilename;
        pAcquisitionInfo->m_strVideoFilename = pCaptureImage->m_strVideoFilename;

        // 1. 이 로직 블록에서만 사용할 DB 인스턴스를 지역 변수로 생성
        SUTIL::SDatabase db("ConvertCaptureImage_Connection");
        if (db.OpenDatabase("/home/birdhead/test.db") == 0) // 0이 성공
        {
            // 2. 지역 인스턴스 'db'를 사용하여 함수 호출
            if(pCaptureImage->m_nType==DISPLAY_IMAGE)
            {
                db.InsertImage(pAcquisitionInfo);
            }
            else if(pCaptureImage->m_nType==DISPLAY_VIDEO)
            {
                db.InsertVideo(pAcquisitionInfo);
            }
        }
        else
        {
            qWarning() << "DB open failed in ConvertCaptureImage";
        }
        // 이 블록이 끝나면 'db' 객체는 자동으로 소멸되어 커넥션이 정리됩니다.
    }
    ReleaseAcquisitionInfo();

    usleep(100);

    return true;
}



void CommonData::ConvertCaptureImageRGBA(CAPTURE_IMAGE* pCaptureImage, int nWidth, int nHeight)
{
    //uint8_t* pData = pCaptureImage->m_pImageCaptureRaw;

    //int nYear = pCaptureImage->m_DateTime.date().year();
    //int nMonth = pCaptureImage->m_DateTime.date().month();
    //int nDay = pCaptureImage->m_DateTime.date().day();
    //int nHour = pCaptureImage->m_DateTime.time().hour();
    //int nMinute = pCaptureImage->m_DateTime.time().minute();
    //int nSec = pCaptureImage->m_DateTime.time().second();

    //QString strStorageDirectory = GetStorageDirectory();
    //QString strDirectoryImage = QString("%1").arg(strStorageDirectory);
    //QString strPatientID = "123";
    QString strImageExtention = m_strImageExtension;

    pCaptureImage->m_pImage = new QImage((uchar*)pCaptureImage->m_pImageCaptureRaw, nWidth, nHeight, QImage::Format_RGB32);

    *pCaptureImage->m_pImage = pCaptureImage->m_pImage->convertToFormat(QImage::Format_RGB888);

    *pCaptureImage->m_pImage = pCaptureImage->m_pImage->rgbSwapped();


    //QString strFile = QString("%1/%2%3%4.%5").arg(strDirectoryImage).arg(QString::number(nHour).rightJustified(2, '0')).arg(QString::number(nMinute).rightJustified(2, '0')).arg(QString::number(nSec).rightJustified(2, '0')).arg(strImageExtention);
    QString strFile = GetNewFilename(DISPLAY_IMAGE);
    {
        /*
        vector<CAPTURE_IMAGE*>::iterator it;

        int nCheckCount = -1;
        for(it=m_pListCaptureImage->begin() ; it!=m_pListCaptureImage->end() ; ++it)
        {
            CAPTURE_IMAGE* pCheckImage = *it;
            if(pCheckImage->m_strImageFilename==strFile)
            {
                nCheckCount++;

                strFile = QString("%1/%2%3%4_%5.%6").arg(strDirectoryImage).arg(QString::number(nHour).rightJustified(2, '0')).arg(QString::number(nMinute).rightJustified(2, '0')).arg(QString::number(nSec).rightJustified(2, '0')).arg(QString::number(nCheckCount)).arg(strImageExtention);

            }
        }
        */
    }


    pCaptureImage->m_strImageFilename = strFile;

    if(pCaptureImage->m_nType==DISPLAY_VIDEO)
    {
        QString strVideo = strFile;
        strVideo = strVideo.replace(strImageExtention, "mp4");
        pCaptureImage->m_strVideoFilename = strVideo;
    }

    pCaptureImage->m_bSaveFile = false;

    m_pThreadCaptureImage->AddCaptureSaveToFile(pCaptureImage);

    QImage image = pCaptureImage->m_pImage->scaled(nWidth/4, nHeight/4, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);

    pCaptureImage->m_pImageSmall = new QImage(nWidth/4, nHeight/4, image.format());
    *pCaptureImage->m_pImageSmall = image;

    SAFE_ARRAY_DELETE(pCaptureImage->m_pImageCaptureRaw);

    // 1. Mutex를 사용하는 Get/Release 함수로 안전하게 공유 데이터에 접근
    ACQUISITION_INFO* pAcquisitionInfo = GetAcquisitionInfo();
    if(pAcquisitionInfo->GetPatientInfo()->strPatientID.length() > 0 &&
            pAcquisitionInfo->GetPatientInfo()->strPatientName.length() >0)
    {
        pAcquisitionInfo->m_strImageFilename = pCaptureImage->m_strImageFilename;
        pAcquisitionInfo->m_strVideoFilename = pCaptureImage->m_strVideoFilename;

        // 2. 지역 DB 인스턴스 생성 및 사용
        SUTIL::SDatabase db("ConvertRGBA_Connection");
        if (db.OpenDatabase("/home/birdhead/test.db") == 0) // 0이 성공
        {
            if(pCaptureImage->m_nType==DISPLAY_IMAGE)
            {
                db.InsertImage(pAcquisitionInfo);
            }
            else if(pCaptureImage->m_nType==DISPLAY_VIDEO)
            {
                db.InsertVideo(pAcquisitionInfo);
            }
        }
        else
        {
            qWarning() << "DB open failed in ConvertCaptureImageRGBA";
        }
    }
    ReleaseAcquisitionInfo(); // 3. 접근이 끝난 후 반드시 Release 호출

    usleep(10*1000);

}

/*
SDatabase* CommonData::GetDatabase()
{
    m_LockDatabase.lock();
    return m_pDatabase;
}

void CommonData::ReleaseDatabase()
{
    m_LockDatabase.unlock();
}
*/

ACQUISITION_INFO* CommonData::GetAcquisitionInfo()
{
    m_LockAcquisitionInfo.lock();
    return &m_AcquisitionInfo;
}

void CommonData::ReleaseAcquisitionInfo()
{
    m_LockAcquisitionInfo.unlock();
}

vector<ImageSelect*>* CommonData::GetListHistoryImage()
{
    m_LockAddHistory.lock();
    return m_pListHistoryImage;
}

void CommonData::ReleaseListHistoryImage()
{
    m_LockAddHistory.unlock();
}

void CommonData::ClearHistoryImage()
{
    m_LockAddHistory.lock();

    int i=0;
    for(i=0 ; i<m_pListHistoryImage->size() ; i++)
    {
        ImageSelect* pHistoryImage = (*m_pListHistoryImage)[i];
        if(pHistoryImage!=NULL)
        {
            SAFE_ARRAY_DELETE(pHistoryImage->m_pImageData);
        }
        SAFE_DELETE(pHistoryImage);
    }
    m_pListHistoryImage->clear();

    SAFE_DELETE(m_pListHistoryImage);
    m_pListHistoryImage = new vector<ImageSelect*>;

    m_LockAddHistory.unlock();
}

vector<HISTORY_STUDY*>* CommonData::GetHistorySearchResult()
{
    return m_pListHistorySearch;
}

void CommonData::ClearHistorySearchResult()
{
    m_LockCurrentHistoryStudy.lock();

    int i=0;
    for(i=0 ; i<m_pListHistorySearch->size() ; i++)
    {
        HISTORY_STUDY* pHistoryStudy = (*m_pListHistorySearch)[i];
        SAFE_DELETE(pHistoryStudy);
    }

    m_pListHistorySearch->clear();
    m_pCurrentHistoryStudy = NULL;

    m_LockCurrentHistoryStudy.unlock();
}



HISTORY_STUDY* CommonData::GetCurrentHistoryStudy()
{
    m_LockCurrentHistoryStudy.lock();
    return m_pCurrentHistoryStudy;
}

void CommonData::ReleaseCurrentHistoryStudy()
{
    m_LockCurrentHistoryStudy.unlock();
}

void CommonData::SetCurrentHistoryStudy(int nIndex)
{
    m_LockCurrentHistoryStudy.lock();
    if(nIndex < m_pListHistorySearch->size())
    {
        m_pCurrentHistoryStudy = (*m_pListHistorySearch)[nIndex];
    }
    else
    {
        m_pCurrentHistoryStudy = NULL;
    }
    m_LockCurrentHistoryStudy.unlock();
}

bool CommonData::IsEncodingVideo()
{
    return m_bVideoEncoding;
}

void CommonData::SetEncodingVideo(bool bEncoding)
{
    m_bVideoEncoding = bEncoding;
}


STableHeader* CommonData::GetWorklistTableHeader()
{
    return m_pWorklistTableHeader;
}

STableHeader* CommonData::GetHistoryTableHeader()
{
    return m_pHistoryTableHeader;
}


void CommonData::Exit()
{
    if(m_pRTSPThread!=NULL)
    {
        m_pRTSPThread->ChangeState(1000);
        while(m_pRTSPThread->isRunning()==true)
        {
            usleep(10*1000);
        }
        m_pRTSPThread->stop();
    }

    if(m_pThreadCaptureImage!=NULL)
    {
        m_pThreadCaptureImage->ChangeState(1000);
        while(m_pThreadCaptureImage->isRunning()==true)
        {
            usleep(10*1000);
        }
    }





}

int CommonData::GetDisplayType()
{
    return m_nDisplayType;
}

void CommonData::SetDisplayType(int nType)
{
    m_nDisplayType = nType;
}

SDCMWorklist* CommonData::GetWorklistClass()
{
    return m_pDCMWorklist;
}

#define pp pair<int, int>

bool cmp(const pp& a, const pp& b)
{
    //if(a.second==b.second) return a.first < b.first;
    //return a.second < b.second;
    return a.first > b.first;
}

void CommonData::InitWorklistIndex()
{
    // 1. 함수 내에서 사용할 지역 DB 인스턴스 생성
    SUTIL::SDatabase db("InitWorklist_Connection");
    if (db.OpenDatabase("/home/birdhead/test.db") != 0) {
        qWarning() << "DB Open Failed in InitWorklistIndex";
        return;
    }

    // 2. 지역 인스턴스 'db'를 통해 함수 호출
    QList<QStringList> result = db.QueryWorklistTableHeader();
    m_pWorklistTableHeader->SetDataWorklist(result);
}

void CommonData::UpdateWorklistIndex()
{
    // 1. 지역 DB 인스턴스 생성
    SUTIL::SDatabase db("UpdateWorklist_Connection");
    if (db.OpenDatabase("/home/birdhead/test.db") != 0) return;

    // 2. 여러 UPDATE 작업을 하나의 트랜잭션으로 묶어 원자성을 보장
    if (!db.BeginTransaction()) {
        qWarning() << "Failed to begin transaction in UpdateWorklistIndex";
        return;
    }

    bool bSuccess = true;
    QString query = "UPDATE WorklistTableHeader SET DisplayIndex = ?, Visible = ? WHERE DefaultIndex = ?;";

    vector<TableHeader*>* pListActivate = m_pWorklistTableHeader->GetListActive();
    for(size_t i = 0; i < pListActivate->size() && bSuccess; ++i)
    {
        TableHeader* pHeader = (*pListActivate)[i];
        pHeader->m_nIndex = i;
        // 3. 파라미터 바인딩으로 안전하게 쿼리 실행
        bSuccess = db.ExecuteNonQuery(query, {pHeader->m_nIndex, 1, pHeader->m_nIndexDefault});
    }

    vector<TableHeader*>* pListInactivate = m_pWorklistTableHeader->GetListInactive();
    size_t nIndexOffset = pListActivate->size();
    for(size_t i = 0; i < pListInactivate->size() && bSuccess; ++i)
    {
        TableHeader* pHeader = (*pListInactivate)[i];
        pHeader->m_nIndex = nIndexOffset + i;
        bSuccess = db.ExecuteNonQuery(query, {pHeader->m_nIndex, 0, pHeader->m_nIndexDefault});
    }

    // 4. 모든 작업이 성공했을 때만 Commit, 하나라도 실패하면 Rollback
    if (bSuccess) {
        db.Commit();
    } else {
        qWarning() << "UpdateWorklistIndex failed, rolling back transaction.";
        db.Rollback();
    }
}

void CommonData::InitHistoryIndex()
{
    // 1. 함수 내에서 사용할 지역 DB 인스턴스 생성
    SUTIL::SDatabase db("InitHistory_Connection");
    if (db.OpenDatabase("/home/birdhead/test.db") != 0) {
        qWarning() << "DB Open Failed in InitHistoryIndex";
        return;
    }

    // 2. 지역 인스턴스 'db'를 통해 함수 호출
    QList<QStringList> result = db.QueryHistoryTableHeader();
    m_pHistoryTableHeader->SetDataHistory(result);
}

void CommonData::UpdateHistoryIndex()
{
    // 1. 지역 DB 인스턴스 생성
    SUTIL::SDatabase db("UpdateHistory_Connection");
    if (db.OpenDatabase("/home/birdhead/test.db") != 0) return;

    // 2. 트랜잭션 시작
    if (!db.BeginTransaction()) {
        qWarning() << "Failed to begin transaction in UpdateHistoryIndex";
        return;
    }

    bool bSuccess = true;
    QString query = "UPDATE HistoryTableHeader SET DisplayIndex = ?, Visible = ? WHERE DefaultIndex = ?;";

    vector<TableHeader*>* pListActivate = m_pHistoryTableHeader->GetListActive();
    for (size_t i = 0; i < pListActivate->size() && bSuccess; ++i)
    {
        TableHeader* pHeader = (*pListActivate)[i];
        pHeader->m_nIndex = i;
        // 3. 파라미터 바인딩으로 안전하게 쿼리 실행
        bSuccess = db.ExecuteNonQuery(query, {pHeader->m_nIndex, 1, pHeader->m_nIndexDefault});
    }

    vector<TableHeader*>* pListInactivate = m_pHistoryTableHeader->GetListInactive();
    size_t nIndexOffset = pListActivate->size();
    for (size_t i = 0; i < pListInactivate->size() && bSuccess; ++i)
    {
        TableHeader* pHeader = (*pListInactivate)[i];
        pHeader->m_nIndex = nIndexOffset + i;
        bSuccess = db.ExecuteNonQuery(query, {pHeader->m_nIndex, 0, pHeader->m_nIndexDefault});
    }

    // 4. 성공/실패에 따른 Commit 또는 Rollback
    if (bSuccess) {
        db.Commit();
    } else {
        qWarning() << "UpdateHistoryIndex failed, rolling back transaction.";
        db.Rollback();
    }
}


SDCM_SERVER_INFO* CommonData::GetServerWorklistInfo()
{
    m_LockServerWorklistInfo.lock();
    return &m_ServerWorklistInfo;
}

void CommonData::ReleaseServerWorklistInfo()
{
    m_LockServerWorklistInfo.unlock();
}

SDCM_SERVER_INFO* CommonData::GetServerStorageInfo()
{
    m_LockServerStorageInfo.lock();
    return &m_ServerStorageInfo;
}

void CommonData::ReleaseServerStorageInfo()
{
    m_LockServerStorageInfo.unlock();
}


void CommonData::UpdateSetting()
{
    SUTIL::SDatabase db("UpdateSetting_Connection");
    if (db.OpenDatabase("/home/birdhead/test.db") != 0) return;

    QString query = "UPDATE ConnectionInfo SET WorklistServerIP=?, WorklistPort=?, WorklistServerTitle=?, WorklistClientTitle=?, "
                    "StorageServerIP=?, StoragePort=?, StorageServerTitle=?, StorageClientTitle=?, Modality=?, "
                    "HospitalName=?, StationName=?, EnableLog=?, LocalImageFolder=?, LocalLogFolder=?, LocalHistoryFolder=? "
                    "WHERE ID=1";

    QVariantList params;
    params << m_ServerWorklistInfo.m_strServer_IP << m_ServerWorklistInfo.m_nServer_Port << m_ServerWorklistInfo.m_strServer_AETitle
           << m_ServerWorklistInfo.m_strClient_AETitle << m_ServerStorageInfo.m_strServer_IP << m_ServerStorageInfo.m_nServer_Port
           << m_ServerStorageInfo.m_strServer_AETitle << m_ServerStorageInfo.m_strClient_AETitle << m_strModality
           << m_strInstitutionName << m_strStationName << (m_bEnableLog ? "Enabled" : "Disabled")
           << m_strLocalImageFolder << m_strLogFolder << m_strLocalHistoryFolder;

    db.ExecuteNonQuery(query, params);
}

void CommonData::UpdateAdvancedSetting()
{
    SUTIL::SDatabase db("UpdateAdvancedSetting_Connection");
        if (db.OpenDatabase("/home/birdhead/test.db") != 0) return;

        QString query = "UPDATE AdvancedSetting SET EnableNetworkShare=?, NetworkShareIP=?, NetworkShareFolder=?, NetworkShareID=?, NetworkSharePassword=?, "
                        "NetworkSMBVersion=?, NetworkAutoSend=?, AutoExitCaptureSendDICOM=?, AutoCaptureSendDICOM=?, AutoVideoCapture=?, "
                        "DICOMCharacterSet=?, AutoCloseSendFinish=?, AutoLogin=?, DICOMCompress=?, VideoMode=?, CropMode=?, "
                        "UseFixWidthLevel=?, UseLogLevel=?, ScreenSaverTime=?, USBBackup=? WHERE ID=1";

        QVariantList params;
        params << (m_NetworkShareInfo.m_bEnable ? "Enabled" : "Disabled")
               << m_NetworkShareInfo.m_strIP << m_NetworkShareInfo.m_strShareFolder << m_NetworkShareInfo.m_strID
               << m_NetworkShareInfo.m_strPassword << m_NetworkShareInfo.m_strVersion
               << (m_NetworkShareInfo.m_bAutoSend ? "Enabled" : "Disabled")
               << m_bAutoExitCaptureSendDICOM << m_bAutoCaptureSendDICOM << m_bAutoVideoCapture
               << m_strDICOMCharacterSet << m_bAutoCloseSendFinish << m_bAutoLogin << m_nTransferSyntax
               << m_nVideoMode << m_nCropMode << m_nUseFixWidthLevel << m_nUseLogLevel
               << m_nScreenSaverTime << m_nUseUSBBackup;

        db.ExecuteNonQuery(query, params);

    if(m_nUseLogLevel==0)
    {
        if(m_pLogFile!=NULL)
        {
            m_pLogFile->flush();
            m_pLogFile->close();

            SAFE_DELETE(m_pLogFile);
        }
    }
}



void CommonData::InitSetting()
{
    SUTIL::SDatabase db("InitSetting_Connection");
    if (db.OpenDatabase("/home/birdhead/test.db") != 0) {
        qWarning() << "Database connection failed for InitSetting.";
        return;
    }

    // QSqlQuery를 직접 사용하여 컬럼 이름으로 안전하게 파싱
    QSqlDatabase qdb = QSqlDatabase::database(db.connectionName()); // 내부 QSqlDatabase 객체 가져오기
    QSqlQuery query(qdb);

    // 1. ConnectionInfo 테이블 조회
    if (query.exec("SELECT * FROM ConnectionInfo WHERE ID = 1") && query.next()) {
        QSqlRecord rec = query.record();
        m_ServerWorklistInfo.m_strServer_IP = rec.value("WorklistServerIP").toString();
        m_ServerWorklistInfo.m_nServer_Port = rec.value("WorklistPort").toInt();
        m_ServerWorklistInfo.m_strServer_AETitle = rec.value("WorklistServerTitle").toString();
        m_ServerWorklistInfo.m_strClient_AETitle = rec.value("WorklistClientTitle").toString();
        m_ServerStorageInfo.m_strServer_IP = rec.value("StorageServerIP").toString();
        m_ServerStorageInfo.m_nServer_Port = rec.value("StoragePort").toInt();
        m_ServerStorageInfo.m_strServer_AETitle = rec.value("StorageServerTitle").toString();
        m_ServerStorageInfo.m_strClient_AETitle = rec.value("StorageClientTitle").toString();
        m_strModality = rec.value("Modality").toString();
        m_strInstitutionName = rec.value("HospitalName").toString();
        m_strStationName = rec.value("StationName").toString();
        m_bEnableLog = (rec.value("EnableLog").toString() == "Enabled");
        m_strLocalImageFolder = rec.value("LocalImageFolder").toString();
        m_strLogFolder = rec.value("LocalLogFolder").toString();
        m_strLocalHistoryFolder = rec.value("LocalHistoryFolder").toString();
    }

    // 2. AdvancedSetting 테이블 조회
    if (query.exec("SELECT * FROM AdvancedSetting WHERE ID = 1") && query.next()) {
        QSqlRecord rec = query.record();
        m_NetworkShareInfo.m_bEnable = (rec.value("EnableNetworkShare").toString() == "Enabled");
        m_NetworkShareInfo.m_strIP = rec.value("NetworkShareIP").toString();
        m_NetworkShareInfo.m_strShareFolder = rec.value("NetworkShareFolder").toString();
        m_NetworkShareInfo.m_strID = rec.value("NetworkShareID").toString();
        m_NetworkShareInfo.m_strPassword = rec.value("NetworkSharePassword").toString();
        m_NetworkShareInfo.m_strVersion = rec.value("NetworkSMBVersion").toString();
        m_NetworkShareInfo.m_bAutoSend = (rec.value("NetworkAutoSend").toString() == "Enabled");
        m_bAutoExitCaptureSendDICOM = rec.value("AutoExitCaptureSendDICOM").toBool();
        m_bAutoCaptureSendDICOM = rec.value("AutoCaptureSendDICOM").toBool();
        m_bAutoVideoCapture = rec.value("AutoVideoCapture").toBool();
        m_strDICOMCharacterSet = rec.value("DICOMCharacterSet").toString();
        m_bAutoCloseSendFinish = rec.value("AutoCloseSendFinish").toBool();
        m_bAutoLogin = rec.value("AutoLogin").toBool();
        m_nTransferSyntax = rec.value("DICOMCompress").toInt();
        m_nVideoMode = rec.value("VideoMode").toInt();
        m_nCropMode = rec.value("CropMode").toInt();
        m_nUseFixWidthLevel = rec.value("UseFixWidthLevel").toInt();
        m_nUseLogLevel = rec.value("UseLogLevel").toInt();
        m_nScreenSaverTime = rec.value("ScreenSaverTime").toInt();
        m_nUseUSBBackup = rec.value("USBBackup").toInt();
    }

    SetVideoMode(m_nVideoMode);
    SetCropMode(m_nCropMode);
    SetUseFixWidthLevel(m_nUseFixWidthLevel);
    SetLogLevel(m_nUseLogLevel);
    SetScreenSaverTime(m_nScreenSaverTime);
    SetUseUSBBackup(m_nUseUSBBackup);

    if(m_nUseLogLevel>0)
    {
        if(m_pLogFile==NULL)
        {
            QDir().mkdir("Log");
            QString strLogFile = QString("Log/%1.log").arg(QDateTime::currentDateTime().toString("yyyyMMdd_HHmmss"));

            m_pLogFile = new QFile(strLogFile);
            m_pLogFile->open(QFile::ReadWrite | QFile::Unbuffered);
        }
    }


    //test code
    //m_bAutoExitCaptureSendDICOM = true;
    //m_bAutoVideoCapture = true;


    m_pDCMWorklist->SetWorklistInfo(m_ServerWorklistInfo.m_strServer_IP, QString::number(m_ServerWorklistInfo.m_nServer_Port), m_ServerWorklistInfo.m_strServer_AETitle, m_ServerWorklistInfo.m_strClient_AETitle);

}

QString CommonData::GetModality()
{
    return m_strModality;
}

QString CommonData::GetInstitutionName()
{
    return m_strInstitutionName;
}

QString CommonData::GetStationName()
{
    return m_strStationName;
}

int CommonData::GetTransferSyntax()
{
    return m_nTransferSyntax;
}

void CommonData::SetModality(QString strModality)
{
    m_strModality = strModality;
}

void CommonData::SetInstitutionName(QString strInstitutionName)
{
    m_strInstitutionName = strInstitutionName;
}

void CommonData::SetStationName(QString strStationName)
{
    m_strStationName = strStationName;
}

void CommonData::SetTransferSyntax(int nTransferSyntax)
{
    m_nTransferSyntax = nTransferSyntax;
}


bool CommonData::GetEnableLog()
{
    return m_bEnableLog;
}

QString CommonData::GetLocalImageFolder()
{
    return m_strLocalImageFolder;
}

QString CommonData::GetLogFolder()
{
    return m_strLogFolder;
}

QString CommonData::GetLocalHistoryFolder()
{
    return m_strLocalHistoryFolder;
}

void CommonData::SetEnableLog(int bEnable)
{
    m_bEnableLog = bEnable;
}

void CommonData::SetLocalImageFolder(QString strLocalImageFolder)
{
    m_strLocalImageFolder = strLocalImageFolder;
}

void CommonData::SetLogFolder(QString strLogFolder)
{
    m_strLogFolder = strLogFolder;
}

void CommonData::SetLocalHistoryFolder(QString strLocalHistoryFolder)
{
    m_strLocalHistoryFolder = strLocalHistoryFolder;
}

void CommonData::Beep(bool bSound)
{
    if(m_nGPIO_Buzzer<=0)
    {
        return;
    }

    if(bSound==true)
    {
        m_bIsCapturing = true;
        if(write(m_nGPIO_Buzzer, "1", 1) != 1)
        {

        }
    }
    else
    {
        m_bIsCapturing = false;
        if(write(m_nGPIO_Buzzer, "0", 1) != 1)
        {

        }
    }
}

int CommonData::GetHandSwitchValue()
{
    char cRead = 0;
    int nReadCount = 0;

    if(m_nGPIO_HandSwitch>0)
    {
        nReadCount = read(m_nGPIO_HandSwitch, &cRead, sizeof(char));
    }


    if(nReadCount==0)
    {
        close(m_nGPIO_HandSwitch);
        //m_nGPIO_HandSwitch = open("/sys/class/gpio/gpio271/value", O_RDONLY);
        m_nGPIO_HandSwitch = open(m_strGPIOHandSwitch.toUtf8(), O_RDONLY);
    }

    if(m_nGPIO_HandSwitch==-1)
    {
        qDebug() << "271 Open Failed";
    }
    else
    {
        //qDebug() << "271 Open success";

        nReadCount = read(m_nGPIO_HandSwitch, &cRead, sizeof(char));

        if(nReadCount>0)
        {
            //qDebug() << cRead;
            if(cRead=='1')
            {
                return 1;
            }
            return 0;
        }

        //close(m_nGPIO_HandSwitch);
    }



    //m_nGPIO_HandSwitch = 0;

    return -1;
}

bool CommonData::IsCapturing()
{
    return m_bIsCapturing;
}

WorklistResponseData CommonData::GetCurrentHistoryWorklistData()
{
    WorklistResponseData rd;

    //rd.m_Patient = m_pCurrentHistoryStudy->pStrPatientName->toStdString().c_str();

    rd.m_Patient.strPatientID = m_pCurrentHistoryStudy->pStrPatientID->toStdString().c_str();
    rd.m_Patient.strPatientName = m_pCurrentHistoryStudy->pStrPatientName->toStdString().c_str();
    rd.m_Patient.strPatientWeight = m_pCurrentHistoryStudy->pStrPatientWeight->toStdString().c_str();
    rd.m_Patient.strPatientSex = m_pCurrentHistoryStudy->pStrPatientSex->toStdString().c_str();
    rd.m_Patient.strPatientBirthDate = m_pCurrentHistoryStudy->pStrPatientBirthDate->toStdString().c_str();

    rd.m_Study.strStudyInstanceUID = m_pCurrentHistoryStudy->pStrStudyInstanceUID->toStdString().c_str();
    rd.m_Study.strStudyDescription = m_pCurrentHistoryStudy->pStrStudyDescription->toStdString().c_str();
    rd.m_Study.strStudyDate = m_pCurrentHistoryStudy->pStrStudyDate->toStdString().c_str();
    rd.m_Study.strStudyTime = m_pCurrentHistoryStudy->pStrStudyTime->toStdString().c_str();
    rd.m_ScheduledData.strScheduledCodeValue = m_pCurrentHistoryStudy->pStrStudyCodeValue->toStdString().c_str();

    rd.m_Study.strReferringPhysiciansName = m_pCurrentHistoryStudy->pStrReferringPhysiciansName->toStdString().c_str();
    rd.m_Study.strAccessionNumber = m_pCurrentHistoryStudy->pStrAccessionNumber->toStdString().c_str();

    rd.m_Series.strSeriesInstanceUID = m_pCurrentHistoryStudy->pStrSeriesInstanceUID->toStdString().c_str();
    rd.m_Series.strSeriesDescription = m_pCurrentHistoryStudy->pStrSeriesDescription->toStdString().c_str();
    rd.m_Series.strModality = m_pCurrentHistoryStudy->pStrModality->toStdString().c_str();
    rd.m_Series.strSeriesDate = m_pCurrentHistoryStudy->pStrSeriesDate->toStdString().c_str();
    rd.m_Series.strSeriesTime = m_pCurrentHistoryStudy->pStrSeriesTime->toStdString().c_str();

    //rd.m_Series.strBodyPartExamined;
    rd.m_Series.strOperatorsName = m_pCurrentHistoryStudy->pStrOperatorsName->toStdString().c_str();

    return rd;
}

WorklistResponseData CommonData::GetCurrentWorklistData()
{
    WorklistResponseData rd;

    m_LockAcquisitionInfo.lock();

    rd.m_Patient = *m_AcquisitionInfo.GetPatientInfo();
    rd.m_Study = *m_AcquisitionInfo.GetStudyInfo();
    rd.m_Series = *m_AcquisitionInfo.GetSeriesInfo();
    rd.m_Image = *m_AcquisitionInfo.GetImageInfo();
    rd.m_ScheduledData = *m_AcquisitionInfo.GetScheduledDataInfo();

    return rd;
}

void CommonData::ReleaseCurrentWorklistData()
{
    m_LockAcquisitionInfo.unlock();
}



qint64 CommonData::ComputeStorageSize()
{
    m_nStorageFreeSize = 0;
    m_nStorageSize = 0;
    foreach (const QStorageInfo &storage, QStorageInfo::mountedVolumes()) {

        QString strRootPath = storage.rootPath();

       qDebug() << strRootPath;

       if(strRootPath=="/data")
       {
           if (storage.isReadOnly())
               qDebug() << "isReadOnly:" << storage.isReadOnly();



           qDebug() << "name:" << storage.name();
           qDebug() << "fileSystemType:" << storage.fileSystemType();
           qDebug() << "size:" << storage.bytesTotal()/1000/1000 << "MB";
           qDebug() << "availableSize:" << storage.bytesAvailable()/1000/1000 << "MB";

           m_nStorageFreeSize = storage.bytesAvailable();
           m_nStorageSize = storage.bytesTotal();
       }



    }

    return m_nStorageSize;

    QString strDirectory = "/data";
    QFileInfo pathInfo(strDirectory);
    if(pathInfo.isDir()==false)
    {
        return 0;
    }

    QDirIterator it(strDirectory, QDirIterator::Subdirectories);
    qint64 total = 0;

    while(it.hasNext()==true)
    {
        it.next();
        QFileInfo fi = it.fileInfo();
        if(fi.isFile()==true && fi.isSymLink()==false && fi.isAbsolute()==true)
        {
            total += fi.size();
        }

    }

    qDebug() << "/data size: " << total;

    m_nStorageSize = total;

    return total;
}

int CommonData::GetStorageSize()
{
    return (int)(m_nStorageSize/(1000*1000));
}

int CommonData::GetStorageFreeSize()
{
    return (int)(m_nStorageFreeSize/(1000*1000));
}


vector<QString>* CommonData::GetExportList()
{
    return &m_ListExport;
}

QString* CommonData::GetExternalDiskPath()
{
    return &m_strExternalDiskPath;
}


QString* CommonData::GetImageExtension()
{
    return &m_strImageExtension;
}


void CommonData::SetSearchItemHistory(SEARCH_ITEM si)
{
    m_SearchItemHistory = si;
}

void CommonData::SetHistorySearchStudyIndex(int nStudyIndex)
{
    m_nSearchItemHistoryStudyIndex = nStudyIndex;
}

SEARCH_ITEM* CommonData::GetSearchItemHistory()
{
    return &m_SearchItemHistory;
}

int CommonData::GetHistorySearchStudyIndex()
{
    return m_nSearchItemHistoryStudyIndex;
}

void CommonData::ClearHistorySearchItem()
{
    m_SearchItemHistory.Clear();
}

void CommonData::ClearHistorySearchStudyIndex()
{
    m_nSearchItemHistoryStudyIndex = -1;
}

bool CommonData::IsAutoCloseSendFinish()
{
    return m_bAutoCloseSendFinish;
}

bool CommonData::IsAutoLogin()
{
    return m_bAutoLogin;
}

void CommonData::SetAutoLogin(bool bEnable)
{
    m_bAutoLogin = bEnable;
}


QString CommonData::GetBeepGPIONumber()
{
    return m_strGPIOBeep;
}

QString CommonData::GetHandswitchGPIONumber()
{
    return m_strGPIOHandSwitch;
}

bool CommonData::IsActiveDetect()
{
    return m_bActiveDetect;
}

void CommonData::SetActiveDetect(bool bActive)
{
    m_bActiveDetect = bActive;
}


void CommonData::SetUseNetworkBackupVideo(bool bUse)
{
    m_NetworkShareInfo.m_bEnable = bUse;
}

bool CommonData::IsUseNetworkBackupVideo()
{
    return m_NetworkShareInfo.m_bEnable;
}


NetworkShareInfo* CommonData::GetNetworkShareInfo()
{
    return &m_NetworkShareInfo;
}

bool CommonData::IsAutoExitCaptureSendDICOM()
{
    return m_bAutoExitCaptureSendDICOM;
}

bool CommonData::IsAutoCaptureSendDICOM()
{
    return m_bAutoCaptureSendDICOM;
}

bool CommonData::IsAutoVideoCapture()
{
    return m_bAutoVideoCapture;
}

void CommonData::SetAutoExitCaptureSendDICOM(bool bEnable)
{
    m_bAutoExitCaptureSendDICOM = bEnable;
}

void CommonData::SetAutoCaptureSendDICOM(bool bEnable)
{
    m_bAutoCaptureSendDICOM = bEnable;
}

void CommonData::SetAutoVideoCapture(bool bEnable)
{
    m_bAutoVideoCapture = bEnable;
}


SambaClient* CommonData::GetSambaClient()
{
    return m_pSambaClient;
}


void CommonData::CreateSambaClient()
{
    m_pSambaClient = new SambaClient;
}

QString CommonData::GetDICOMCharacterSet()
{
    return m_strDICOMCharacterSet;
}

void CommonData::SetDICOMCharacterSet(QString strCharacterSet)
{
    m_strDICOMCharacterSet = strCharacterSet;
}

void CommonData::SetAutoCloseSendComplete(bool bEnable)
{
    m_bAutoCloseSendFinish = bEnable;
}

void CommonData::WriteLog(QString strLog)
{
    if(m_nUseLogLevel>0)
    {
        m_LockLog.lock();
        m_ListLog.push_back(strLog);
        m_LockLog.unlock();
    }
}

void CommonData::WriteLogFile(QString strLog)
{
    m_LockLog.lock();
    if(m_pLogFile!=NULL)
    {
        if(m_pLogFile->exists()==true)
        {
            m_pLogFile->write(strLog.toStdString().c_str());
            fsync(m_pLogFile->handle());
        }
    }

    m_LockLog.unlock();


}

QStringList* CommonData::GetListLog()
{
    m_LockLog.lock();

    return &m_ListLog;
}

void CommonData::ReleaseListLog()
{
    m_LockLog.unlock();
}

void CommonData::SetVideoMode(int nMode)
{
    nMode = 0;
    m_nVideoMode = nMode;

    if(m_nVideoMode==0)
    {
#ifdef _4K
        m_nVideoWidth = 3840;
        m_nVideoHeight = 2160;
#else
        m_nVideoWidth = 1920;
        m_nVideoHeight = 1080;
#endif
    }
    else if(m_nVideoMode==1)
    {
        m_nVideoWidth = 1280;
        m_nVideoHeight = 720;
    }
}

int CommonData::GetVideoMode()
{
    return m_nVideoMode;
}

void CommonData::SetCropMode(int bCropMode)
{
    m_nCropMode = bCropMode;
}

int CommonData::GetCropMode()
{
    return m_nCropMode;
}

void CommonData::SetUseFixWidthLevel(int bFixWidthLevel)
{
    m_nUseFixWidthLevel = bFixWidthLevel;
}

int CommonData::GetUseFixWidthLevel()
{
    return m_nUseFixWidthLevel;
}

void CommonData::SetLogLevel(int nLevel)
{
    m_nUseLogLevel = nLevel;
}

int CommonData::GetLogLevel()
{
    return m_nUseLogLevel;
}

void CommonData::SetUseUSBBackup(int nUseUSBBackup)
{
    m_nUseUSBBackup = nUseUSBBackup;
}

int CommonData::IsUseUSBBackup()
{
    return m_nUseUSBBackup;
}


int CommonData::GetVideoWidth()
{
    return m_nVideoWidth;
}

int CommonData::GetVideoHeight()
{
    return m_nVideoHeight;
}


void CommonData::MakeBitmapHeader(int nWidth, int nHeight)
{
    memset(m_pBitmapData, 0, m_nVideoWidth*m_nVideoHeight*3+1000);

    int nSizeBitmapHeader = sizeof(BITMAPFILEHADER);
    int nSizeBitmapInfoHeader = sizeof(BITMAPINFOHEADER);
    memset(&m_bf, 0, sizeof(&m_bf));
    m_bf.bfType = 0x4d42;
    m_bf.bfOffBits = nSizeBitmapHeader + nSizeBitmapInfoHeader;
    m_bf.bfSize = m_bf.bfOffBits + nWidth*nHeight*3;
    m_bf.bfReserved1 = 0;
    m_bf.bfReserved2 = 0;

    memcpy(&m_pBitmapData[0], &m_bf, nSizeBitmapHeader);

    memset(&m_bi, 0, sizeof(&m_bi));
    m_bi.biSize = sizeof(BITMAPINFOHEADER);
    m_bi.biWidth = nWidth;
    m_bi.biHeight = -1* nHeight;
    m_bi.biPlanes = 1;
    m_bi.biBitCount = 24;
    m_bi.biCompression = 0;//BI_RGB;
    m_bi.biSizeImage = nWidth*nHeight*3;
    m_bi.biXPelsPerMeter = 2835;
    m_bi.biYPelsPerMeter = 2835;
    m_bi.biClrUsed = 0;
    m_bi.biClrImportant = 0;

    memcpy(&m_pBitmapData[nSizeBitmapHeader], &m_bi, nSizeBitmapInfoHeader);
}


bool CommonData::WriteBitmapFile(QString strFile, QImage* pImage)
{
    int nWidth = pImage->width();
    int nHeight = pImage->height();
    MakeBitmapHeader(nWidth, nHeight);

    //QImage tmpImage = pImage->rgbSwapped();
    //memcpy(&m_pBitmapData[m_bf.bfOffBits], tmpImage.bits(), nWidth*nHeight*3);
    memcpy(&m_pBitmapData[m_bf.bfOffBits], pImage->bits(), nWidth*nHeight*3);

    QFile t2(strFile);
    if(t2.exists()==true)
    {
        t2.remove();
    }
    t2.open(QFile::ReadWrite);

    t2.write((const char*)m_pBitmapData, m_bf.bfSize);

    t2.flush();
    fsync(t2.handle());
    t2.close();

    bool bCreate = false;

    QFile fileBitmap(strFile);
    if(fileBitmap.exists()==true)
    {
        int nFileSize = fileBitmap.size();
        if(nFileSize>850 && nFileSize<7230854)
        {
            bCreate = true;
        }
        fileBitmap.close();
    }

    if(bCreate==false)
    {

    }



    return bCreate;


}

bool CommonData::WriteJPEG(QString strFile, uint8_t* pData, int nWidth, int nHeight, int nQualilty)
{
#ifdef _PC
    QImage imageWrite(pData, nWidth, nHeight, QImage::Format_RGB888);
    imageWrite.save(strFile, "jpg", nQualilty);
#else
    QImage imageWrite(pData, nWidth, nHeight, QImage::Format_BGR888);
    imageWrite.save(strFile, "jpg", nQualilty);
#endif

    return true;
    /*
    FILE* outfile = fopen(strFile.toStdString().c_str(), "wb");
    if(outfile == NULL) return false;

    jpeg_compress_struct cinfo;
    jpeg_error_mgr       jerr;

    cinfo.err = jpeg_std_error(&jerr);
    jpeg_create_compress(&cinfo);
    jpeg_stdio_dest(&cinfo, outfile);

    cinfo.image_width      = nWidth;
    cinfo.image_height     = nHeight;
    cinfo.input_components = 3;
    cinfo.in_color_space   = JCS_EXT_BGR;

    jpeg_set_defaults(&cinfo);
    //set the quality [0..100]
    jpeg_set_quality(&cinfo, nQualilty, true);
    jpeg_start_compress(&cinfo, true);

    JSAMPROW row_pointer;

    while (cinfo.next_scanline < cinfo.image_height)
    {
        row_pointer = (JSAMPROW) pData[cinfo.next_scanline*nWidth];
        jpeg_write_scanlines(&cinfo, &row_pointer, 1);
    }
    jpeg_finish_compress(&cinfo);

    fclose(outfile);
    */
}

bool CommonData::WriteBitmapFile(QString strFile, uint8_t* pData, int nWidth, int nHeight)
{
    MakeBitmapHeader(nWidth, nHeight);
    memcpy(&m_pBitmapData[m_bf.bfOffBits], pData, nWidth*nHeight*3);

    QFile t2(strFile);
    if(t2.exists()==true)
    {
        t2.remove();
    }
    t2.open(QFile::ReadWrite);

    t2.write((const char*)m_pBitmapData, m_bf.bfSize);

    t2.flush();
    fsync(t2.handle());
    t2.close();

    bool bCreate = false;

    QFile fileBitmap(strFile);
    if(fileBitmap.exists()==true)
    {
        int nFileSize = fileBitmap.size();
        if(nFileSize>850 && nFileSize<7230854)
        {
            bCreate = true;
        }
        fileBitmap.close();
    }
    return bCreate;
}


void CommonData::SetScreenSaverTime(int nMinutes)
{
    m_nScreenSaverTime = nMinutes;
}

int CommonData::GetScreenSaverTime()
{
    return m_nScreenSaverTime;
}

void CommonData::SetConnectHDMI(bool bConnect)
{
    m_bConnectHDMI = bConnect;
}

bool CommonData::IsConnectHDMI()
{
    return m_bConnectHDMI;
}

void CommonData::GetSearchDateStartEnd(int nSearchDurationType, QDate& nDateStart, QDate& nDateEnd)
{
    QDate nDateCurrent = QDate::currentDate();

    switch(nSearchDurationType)
    {
    case SEARCH_TODAY: //Today
        nDateStart = nDateCurrent;
        nDateEnd = nDateCurrent;
        break;
    case SEARCH_3DAY:
        nDateEnd = nDateCurrent;
        nDateStart = nDateEnd.addDays(-2);
        break;
    case SEARCH_WEEK:
        nDateEnd = nDateCurrent;
        nDateStart = nDateEnd.addDays(-6);
        break;
    case SEARCH_2WEEK:
        nDateEnd = nDateCurrent;
        nDateStart = nDateEnd.addDays(-13);
        break;
    case SEARCH_3WEEK:
        nDateEnd = nDateCurrent;
        nDateStart = nDateEnd.addDays(-20);
        break;
    case SEARCH_1MONTH:
        nDateEnd = nDateCurrent;
        nDateStart = nDateCurrent.addMonths(-1);
        nDateStart = nDateStart.addDays(1);
        break;
    case SEARCH_2MONTH:
        nDateEnd = nDateCurrent;
        nDateStart = nDateCurrent.addMonths(-2);
        nDateStart = nDateStart.addDays(1);
        break;
    case SEARCH_USER_DEFINED:
        break;
    default:
        break;
    }
}


void CommonData::RestartNetworkManager()
{
    WRITE_FUNCTION_LOG();

    QProcess process1;
    QProcess process2;

    process1.setStandardOutputProcess(&process2);

    process1.start("echo 1");
#ifdef _PC
    process2.start("sudo systemctl restart NetworkManager");
#else
    process2.start("sudo -S systemctl restart NetworkManager");
#endif
    process2.setProcessChannelMode(QProcess::ForwardedChannels);

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

    bool retval = false;
    QByteArray buffer;
    // 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();
}


void CommonData::SetUseWebDisplay(bool bUse)
{
    m_bUseWebDisplay = bUse;
}

bool CommonData::IsUseWebDisplay()
{
    return m_bUseWebDisplay;
}

/*
void CommonData::ReOpenDatabase()
{
    m_pDatabase->CloseDatabase();
    m_pDatabase->OpenDatabase("/home/birdhead/test.db", false);
}
*/
