#include <QTimer>
#include <unistd.h>
#include "fileprocessdlg.h"
#include "ui_fileprocessdlg.h"
#include "fileprocessor.h"
#include "ovenstatics.h"
#include "stringer.h"
#include <QDebug>


#define ERROR_LOG_FILE_TOP  "/GasErrorHistoryTop.csv"
#define ERROR_LOG_FILE_STEAM  "/GasErrorHistorySteam.csv"
#define ERROR_LOG_FILE_BOTTOM  "/GasErrorHistoryBottom.csv"
#define ERROR_LOG_FILE_TOTAL    "/TotalError.csv"
#define SERVICE_DATA_FILE   "/ServiceData.csv"


ProgramCopyWorker::ProgramCopyWorker(){
    m_bStop = false;
}


ProgramCopyWorker::ProgramCopyWorker(QString strDest){
    m_strDestDir = strDest;
}

void ProgramCopyWorker::setDestPath(QString strDest){
    m_strDestDir = strDest;
}

void ProgramCopyWorker::workerMain(){
    quint64 nTotalFileSize=0;
    quint64 nCpyFileSize=0;
    uint16_t nCurProgress=0;
    int nRemainSec = 0;
    QStringList strdirlist;
    QStringList strFilelist;
    QString srcFilepath;
    QString destFilePath;

    int i;

    //make destination folder
    QDir destdir(m_strDestDir);
    if(!destdir.isRoot() && destdir.exists()==false){
        destdir.mkpath(m_strDestDir);
    }
    qDebug() << "Target Path is " << m_strDestDir;


    foreach(QString strinfo, m_arrSrcFileList){
        QString filepath = strinfo.left(strinfo.indexOf(',',0));
        QFileInfo finfo(filepath);
        nTotalFileSize+= finfo.size();        
    }
    qDebug() << "File List info : count = " << m_arrSrcFileList.size() << ", File Total Size = " << nTotalFileSize;

    foreach(QString srcpath, m_arrSrcDirList){
        nTotalFileSize += FileProcessor::getDirSize(srcpath);
    }
    qDebug() << " Dir List info : count = " << m_arrSrcFileList.size() << ", File Total Size = " << nTotalFileSize;
    if(nTotalFileSize <=0 ){
        emit finished();
        progressed(0,0);
        return;
    }


    foreach(QString strinfo, m_arrSrcFileList){
        QString filepath = strinfo.left(strinfo.indexOf(',',0));
        QString destfiledir = strinfo.right(strinfo.size() - (strinfo.indexOf(',',0)+1));
        QDir destdir(destfiledir);
        if(destdir.exists() == false) destdir.mkpath(destfiledir);
        QFileInfo finfo(filepath);
        srcFilepath = filepath;
        destFilePath = QString("%1/%2").arg(destfiledir).arg(finfo.fileName());
        if(QFile::exists(destFilePath)){
            QFile::rename(destFilePath, QString("%1.bak").arg(destFilePath));
        }
        QFile::copy(srcFilepath,destFilePath);
        nCpyFileSize += finfo.size();
        nCurProgress = (nCpyFileSize *100) / nTotalFileSize;
        nRemainSec = (nTotalFileSize-nCpyFileSize)/200000;
        emit progressed(nCurProgress,nRemainSec);
        if(QThread::currentThread()->isInterruptionRequested()){
            sync();
            QThread::currentThread()->quit();
            break;
        }
        QThread::currentThread()->msleep(10);
    }
    qDebug() << "File List Copy Finished";

    if(QThread::currentThread()->isInterruptionRequested() == false){
        foreach(QString srcpath, m_arrSrcDirList){
            qDebug() << "src dir : " << srcpath;

            QDir srcdir(srcpath);
            strdirlist.append(srcpath);
            FileProcessor::getAllDirList(srcdir, strdirlist);
            qDebug() << "dir size  : " <<strdirlist.size();

            QString targetpath =QString("%1%2").arg(m_strDestDir).arg(srcpath.mid(srcpath.lastIndexOf('/')));
            qDebug() << "target dir : " << targetpath;

            QDir destDir(targetpath);
            if(destDir.exists()) {
                qDebug() << "rename target path";
                QDir().rename(targetpath, QString("%1_").arg(targetpath));
            }

            foreach(QString strDir, strdirlist){
                QDir srcItem(strDir);
                srcItem.mkpath( QString(strDir).replace(srcpath,targetpath));
                QFileInfoList strFileInfolist = srcItem.entryInfoList(QDir::Files |  QDir::NoSymLinks | QDir::NoDotAndDotDot);
                foreach(QFileInfo finfo, strFileInfolist){
                    srcFilepath = finfo.absoluteFilePath();
                    destFilePath = QString("%1/%2").arg(QString(strDir).replace(srcpath,targetpath)).arg(finfo.fileName());
                    nCpyFileSize += finfo.size();
                    nCurProgress = (nCpyFileSize *100) / nTotalFileSize;
                    nRemainSec = (nTotalFileSize-nCpyFileSize)/200000;
                    //qDebug() << srcFilepath << destFilePath << "total size " << nTotalFileSize << "nCpyFileSize " << nCpyFileSize;
                    emit progressed(nCurProgress,nRemainSec);
                    if(QThread::currentThread()->isInterruptionRequested()){
                        sync();
                        break;
                    }
                    //QThread::currentThread()->msleep(100);
                }
                if(QThread::currentThread()->isInterruptionRequested()) break;
            }
            strdirlist.clear();
            if(QThread::currentThread()->isInterruptionRequested()) break;
        }
    }
    qDebug() << "File Copy Complete! SRC File Size = " << nTotalFileSize << "DEST File Size = " << nCpyFileSize;

    if(QThread::currentThread()->isInterruptionRequested()){
        foreach(QString strinfo, m_arrSrcFileList){
            QString filepath = strinfo.left(strinfo.indexOf(',',0)+1);
            QString destfiledir = strinfo.right(strinfo.size() - (strinfo.indexOf(',',0)+1));
            QFileInfo finfo(filepath);
            srcFilepath = filepath;
            destFilePath = QString("%1/%2").arg(destfiledir).arg(finfo.fileName());
            if(QFile::exists( QString("%1.bak").arg(destFilePath))){
                QFile::remove(destFilePath);
                QFile::rename(QString("%1.bak").arg(destFilePath), destFilePath);
                nCpyFileSize -= finfo.size();
                nCurProgress = (nCpyFileSize *100) / nTotalFileSize;
                emit progressed(nCurProgress, nRemainSec);
            }
            QThread::currentThread()->msleep(1);
        }
        foreach(QString srcpath, m_arrSrcDirList){
            qDebug() << "src dir : " << srcpath;

            QDir srcdir(srcpath);
            QString targetpath =QString("%1%2").arg(m_strDestDir).arg(srcpath.mid(srcpath.lastIndexOf('/')));
            qDebug() << "target dir : " << targetpath;

            QDir destDir(targetpath);
            QDir renameDir(QString("%1_").arg(targetpath));
            if(renameDir.exists()) {
                qDebug() << "remove target path";
                destDir.removeRecursively();
                QDir().rename(QString("%1_").arg(targetpath), targetpath);
            }
            emit progressed(0, 0);
        }
    }
    else{
        foreach(QString srcpath, m_arrSrcDirList){
            qDebug() << "src dir : " << srcpath;
            QDir srcdir(srcpath);
            QString targetpath =QString("%1%2").arg(m_strDestDir).arg(srcpath.mid(srcpath.lastIndexOf('/')));
            qDebug() << "target dir : " << targetpath;
            QDir destDir(targetpath);
            QDir renameDir(QString("%1_").arg(targetpath));
            if(renameDir.exists()) {
                renameDir.removeRecursively();
            }
            emit progressed(0, 0);
        }
    }
    sync();
    emit finished();
}

void ProgramCopyWorker::addSrcDir(QString strDirPath){
    m_arrSrcDirList.append(strDirPath);
}

void ProgramCopyWorker::addSrcFile(QString strfilename){
    m_arrSrcFileList.append(strfilename);
}

void ProgramCopyWorker::workerStop(){
    //QMutexLocker locker(&m_mutex);
   // qDebug() << "stop thread";
   m_bStop = true;
}


FileProcessDlg::FileProcessDlg(QWidget *parent, ConfigType type, bool isDown) :
    QDialog(parent),
    ui(new Ui::FileProcessDlg)
{
    ui->setupUi(this);
    setAttribute(Qt::WA_DeleteOnClose);
    setAttribute(Qt::WA_TranslucentBackground);
    setWindowFlags(Qt::FramelessWindowHint);

    ui->ctrWjProcess->setMinimum(0);
    ui->ctrWjProcess->setMaximum(100);

    if(isDown){
        QPixmap pxmap;
        pxmap.load(":/images/config/102_usb_upload_icon.png");
        ui->label_2->setPixmap(pxmap);
    }

    switch(type){
    case config_info_data_download:
        QTimer::singleShot(100,this,SLOT(infodataDownload()));
        break;
    case config_service_data_download:
        QTimer::singleShot(100,this,SLOT(servicedataDownload()));
        break;
    case config_program_download:
        QTimer::singleShot(100,this,SLOT(programDownload()));
        break;
    case config_program_upload:
        QTimer::singleShot(100,this,SLOT(programUpload()));
        break;
    case config_set_download:
        QTimer::singleShot(100,this,SLOT(configDownload()));
        break;
    case config_set_upload:
        QTimer::singleShot(100,this,SLOT(configUpload()));
        break;
    default:
        QTimer::singleShot(200,this,SLOT(deleteLater()));
        break;
    }
}

FileProcessDlg::~FileProcessDlg()
{
    delete ui;
}

void FileProcessDlg::on_ctrBtnCancel_clicked()
{

    //emit stopcopy();
    programCopyThd.requestInterruption();
    //close();
}

void FileProcessDlg::saveHistoryLineData(QTextStream &out, uint16_t i,  uint16_t fired_cnt, time_t first_fired, time_t last_fried){
    QString strLine;
    QDateTime dt;
    //for(int i =0;i<m_arrErrorMaxIdx[(uint16_t)type];i++){
   //     err_item = &(ovenst->srvdata->err_log.values[m_arrErrorIdxs[type][i]]);
        strLine = tr("erro%1,").arg(i);
        if(first_fired == 0){
            strLine += "-,0,-";
        }
        else{
            dt.setTime_t(first_fired);
            strLine+= Stringer::DateTimeString(dt,Stringer::datetime_string_type_oneline) + ",";
            strLine += QString("%1").arg(fired_cnt) + ",";
            dt.setTime_t(last_fried);
            strLine += Stringer::DateTimeString(dt,Stringer::datetime_string_type_oneline) + ",";
        }
        out << strLine << "\n";
        qDebug() << strLine;
    //}
}

void FileProcessDlg::saveHistoryTotalData(QTextStream &out){
    int i = 0;
    error_item *item;
    time_t firsttimebuf=0,lasttimebuf=0;
    uint16_t firecntbuf=0;
    QString strLine;
    QDateTime dt;
    OvenStatistics *ovenst = OvenStatistics::getInstance();

    //01 상부 점화 장치 데이터 초기화
//    for(i=0;i<m_arrErrorMaxIdx[ERROR_HISTORY_UPPERBUNNER];i++){
//        item = &(ovenst->srvdata->err_log.values[m_arrErrorIdxs[ERROR_HISTORY_UPPERBUNNER][i]]);
//       if(i==0) {firsttimebuf = item->first_fired;lasttimebuf = item->last_fried;firecntbuf=item->fired_cnt;}
//       else{
//            if( firsttimebuf > item->first_fired && item->first_fired != 0 ) firsttimebuf = item->first_fired;
//            if( lasttimebuf < item->last_fried ) lasttimebuf = item->last_fried;
//            firecntbuf += item->fired_cnt;
//       }

//    }
//    total_items[0].fired_cnt = firecntbuf;
//    total_items[0].first_fired = firsttimebuf;
//    total_items[0].last_fried = lasttimebuf;


}



void FileProcessDlg::infodataDownload(){
    QString strUsbPath;
    QString strFile;
    QFile file;
    error_item *item;
    OvenStatistics *ovenst = OvenStatistics::getInstance();
    time_t firsttimebuf=0,lasttimebuf=0;
    uint16_t firecntbuf=0;
    uint16_t erridx = 0;
    int i;

    if(FileProcessor::detectUSB(strUsbPath)){
        //Top
        strFile = strUsbPath + ERROR_LOG_FILE_TOP;
        qDebug() << strUsbPath;
        file.setFileName(strFile);
        if(file.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate)){
            QTextStream out(&file);
            out << tr("Gas Error History\n") << "Top Ignition Box" <<"\n";
            out << tr("no,") << tr("First Appearance,") << tr("Counter,") << tr("Last Appearance\n");
            for(i =0;i<m_arrErrorMaxIdx[ERROR_HISTORY_UPPERBUNNER];i++){
                item = &(ovenst->srvdata->err_log.values[m_arrErrorIdxs[ERROR_HISTORY_UPPERBUNNER][i]]);
                saveHistoryLineData(out,i+1,item->fired_cnt,item->first_fired,item->last_fried);
            }
            file.close();
        }
        ui->ctrWjProcess->setValue(25);
        ui->ctrLbRemainTime->setText(tr("남은 예상 시간 : 1초"));
        //Bottom
        strFile = strUsbPath + ERROR_LOG_FILE_BOTTOM;
        qDebug() << strUsbPath;
        file.setFileName(strFile);
        if(file.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate)){
            QTextStream out(&file);
            out << tr("Gas Error History\n") << "Bottom Ignition Box" <<"\n";
            out << tr("no,") << tr("First Appearance,") << tr("Counter,") << tr("Last Appearance\n");
            for(i =0;i<m_arrErrorMaxIdx[ERROR_HISTORY_LOWERBUNNER];i++){
                item = &(ovenst->srvdata->err_log.values[m_arrErrorIdxs[ERROR_HISTORY_LOWERBUNNER][i]]);
                saveHistoryLineData(out,i+1,item->fired_cnt,item->first_fired,item->last_fried);
            }
            file.close();
        }
        ui->ctrWjProcess->setValue(50);
        ui->ctrLbRemainTime->setText(tr("남은 예상 시간 : 1초"));
        //Steam
        strFile = strUsbPath + ERROR_LOG_FILE_STEAM;
        qDebug() << strUsbPath;
        file.setFileName(strFile);
        if(file.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate)){
            QTextStream out(&file);
            out << tr("Gas Error History\n") << "Steam Ignition Box" <<"\n";
            out << tr("no,") << tr("First Appearance,") << tr("Counter,") << tr("Last Appearance\n");
            for(i =0;i<m_arrErrorMaxIdx[ERROR_HISTORY_STEAMBUNNER];i++){
                item = &(ovenst->srvdata->err_log.values[m_arrErrorIdxs[ERROR_HISTORY_STEAMBUNNER][i]]);
                saveHistoryLineData(out,i+1,item->fired_cnt,item->first_fired,item->last_fried);
            }
            file.close();
        }
        ui->ctrWjProcess->setValue(75);
        ui->ctrLbRemainTime->setText(tr("남은 예상 시간 : 1초"));
        //Total
        strFile = strUsbPath + ERROR_LOG_FILE_TOTAL;
        qDebug() << strUsbPath;
        file.setFileName(strFile);
        if(file.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate)){
            QTextStream out(&file);
            out << tr("Service Error History\n\n");
            out << tr("no,") << tr("First Appearance,") << tr("Counter,") << tr("Last Appearance\n");
            //01 상부 점화 장치 데이터 초기화
             firecntbuf = 0;firsttimebuf =  0; lasttimebuf=0;
            for(i=0;i<m_arrErrorMaxIdx[ERROR_HISTORY_UPPERBUNNER];i++){
                item = &(ovenst->srvdata->err_log.values[m_arrErrorIdxs[ERROR_HISTORY_UPPERBUNNER][i]]);
               if(i==0) {firsttimebuf = item->first_fired;lasttimebuf = item->last_fried;firecntbuf=item->fired_cnt;}
               else{
                    if( (firsttimebuf > item->first_fired && item->first_fired != 0) || firsttimebuf == 0 ) firsttimebuf = item->first_fired;
                    if( lasttimebuf < item->last_fried ) lasttimebuf = item->last_fried;
                    firecntbuf += item->fired_cnt;
               }
            }
            saveHistoryLineData(out,erridx+1, firecntbuf,firsttimebuf,lasttimebuf);erridx++;
            //02 스팀 점화 장치 데이터 초기화
            firecntbuf = 0;firsttimebuf =  0; lasttimebuf=0;
            for(i=0;i<m_arrErrorMaxIdx[ERROR_HISTORY_STEAMBUNNER];i++){
                item = &(ovenst->srvdata->err_log.values[m_arrErrorIdxs[ERROR_HISTORY_STEAMBUNNER][i]]);
               if(i==0) {firsttimebuf = item->first_fired;lasttimebuf = item->last_fried;firecntbuf=item->fired_cnt;}
               else{
                    if((firsttimebuf > item->first_fired && item->first_fired != 0) || firsttimebuf == 0 ) firsttimebuf = item->first_fired;
                    if( lasttimebuf < item->last_fried ) lasttimebuf = item->last_fried;
                    firecntbuf += item->fired_cnt;
               }
            }
            saveHistoryLineData(out, erridx,firecntbuf,firsttimebuf,lasttimebuf);erridx++;
            //03 하부 점화 장치 데이터 초기화
            firecntbuf = 0;firsttimebuf =  0; lasttimebuf=0;
            for(i=0;i<m_arrErrorMaxIdx[ERROR_HISTORY_LOWERBUNNER];i++){
                item = &(ovenst->srvdata->err_log.values[m_arrErrorIdxs[ERROR_HISTORY_LOWERBUNNER][i]]);
               if(i==0) {firsttimebuf = item->first_fired;lasttimebuf = item->last_fried;firecntbuf=item->fired_cnt;}
               else{
                    if((firsttimebuf > item->first_fired && item->first_fired != 0) || firsttimebuf == 0 ) firsttimebuf = item->first_fired;
                    if( lasttimebuf < item->last_fried ) lasttimebuf = item->last_fried;
                    firecntbuf += item->fired_cnt;
               }
            }
            saveHistoryLineData(out, erridx,firecntbuf,firsttimebuf,lasttimebuf);erridx++;
            //04 WATER
            firecntbuf = 0;firsttimebuf =  0; lasttimebuf=0;
            item = &(ovenst->srvdata->err_log.items.inner_temp_fail);
            firsttimebuf = item->first_fired;lasttimebuf = item->last_fried;firecntbuf=item->fired_cnt;
            item = &(ovenst->srvdata->err_log.items.qunching_temp_fail);
            if( firsttimebuf > item->first_fired && item->first_fired != 0 ) firsttimebuf = item->first_fired;
            if( lasttimebuf < item->last_fried ) lasttimebuf = item->last_fried;
            firecntbuf += item->fired_cnt;
            saveHistoryLineData(out, erridx,firecntbuf,firsttimebuf,lasttimebuf);erridx++;
            //05 구성품
            firecntbuf = 0;firsttimebuf =  0; lasttimebuf=0;
            saveHistoryLineData(out, erridx,firecntbuf,firsttimebuf,lasttimebuf);erridx++;
            //07 B1 센서 에러
            firecntbuf = 0;firsttimebuf =  0; lasttimebuf=0;
            item = &(ovenst->srvdata->err_log.items.inner_temp_high_alarm);
            firsttimebuf = item->first_fired;lasttimebuf = item->last_fried;firecntbuf=item->fired_cnt;
            saveHistoryLineData(out, erridx,firecntbuf,firsttimebuf,lasttimebuf);erridx++;
            //08 B2 센서 에러
            firecntbuf = 0;firsttimebuf =  0; lasttimebuf=0;
            item = &(ovenst->srvdata->err_log.items.qunching_temp_high_alarm);
            saveHistoryLineData(out, erridx,firecntbuf,firsttimebuf,lasttimebuf);erridx++;
            //10 B4 센서 에러
            firecntbuf = 0;firsttimebuf =  0; lasttimebuf=0;
            item = &(ovenst->srvdata->err_log.items.wall_temp1_high_alarm);
            firsttimebuf = item->first_fired;lasttimebuf = item->last_fried;firecntbuf=item->fired_cnt;
            saveHistoryLineData(out, erridx,firecntbuf,firsttimebuf,lasttimebuf);erridx++;
            //11 B5 센서 에러
            firecntbuf = 0;firsttimebuf =  0; lasttimebuf=0;
            item = &(ovenst->srvdata->err_log.items.steam_gen_temp_high_alram);
            firsttimebuf = item->first_fired;lasttimebuf = item->last_fried;firecntbuf=item->fired_cnt;
            saveHistoryLineData(out, erridx,firecntbuf,firsttimebuf,lasttimebuf);erridx++;
            firecntbuf = 0;firsttimebuf =  0; lasttimebuf=0;
            item = &(ovenst->srvdata->err_log.items.water_level_sensor_fail);
            firsttimebuf = item->first_fired;lasttimebuf = item->last_fried;firecntbuf=item->fired_cnt;
            saveHistoryLineData(out, erridx,firecntbuf,firsttimebuf,lasttimebuf);erridx++;
            file.close();
        }
        sync();
        ui->ctrWjProcess->setValue(100);
        ui->ctrLbRemainTime->setText(tr("남은 예상 시간 : 완료"));
        QTimer::singleShot(1000,this,SLOT(close()));
    }
}

void FileProcessDlg::servicedataDownload(){
    QString strUsbPath;
    QString strHeader = "no,name,time\n";
    QString strFile;
    QFile file;
    error_item *item;
    uint32_t timetemp, totaltime=0;
    int i = 1;
    OvenStatistics *ovs = OvenStatistics::getInstance();
    if(FileProcessor::detectUSB(strUsbPath)){
        strFile = strUsbPath + SERVICE_DATA_FILE;
        file.setFileName(strFile);
        if(file.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate)){
            QTextStream out(&file);
            out.setCodec("UTF-8");
            out<< strHeader;
            timetemp = ovs->srvdata->use_log.items.steam_heat/3600;
            out << i++ << tr(",Steam Heating Time,") << timetemp << "h\n";
            timetemp = ovs->srvdata->use_log.items.dry_heat/3600;
            out << i++ << tr(",Hot Air Heating Time,") << timetemp << "h\n";

            i=1;out<< strHeader;
            timetemp = ovs->srvdata->use_log.items.cook_dry_mode/3600;
            totaltime+= ovs->srvdata->use_log.items.cook_dry_mode;
            out << i++ << tr(",Hot Air Mode,") << timetemp << "h\n";
            timetemp = ovs->srvdata->use_log.items.cook_steam_mode/3600;
            totaltime +=  ovs->srvdata->use_log.items.cook_steam_mode;
            out << i++ << tr(",Steam Mode,") << timetemp << "h\n";
            timetemp = ovs->srvdata->use_log.items.cook_combi_mode/3600;
            totaltime += ovs->srvdata->use_log.items.cook_combi_mode;
            out << i++ << tr(",Combi Mode,") << timetemp << "h\n";
            timetemp = ovs->srvdata->use_log.items.wash_mode_nocleanser/3600;
            totaltime += ovs->srvdata->use_log.items.wash_mode_nocleanser;
            out << i++ << tr(",세제없이 헹굼,").toUtf8() << timetemp << "h\n";
            timetemp = ovs->srvdata->use_log.items.wash_mode_simple/3600;
            totaltime += ovs->srvdata->use_log.items.wash_mode_simple;
            out << i++ << tr(",간이세척,").toUtf8() << timetemp << "h\n";
            timetemp = ovs->srvdata->use_log.items.wash_mode_standard/3600;
            totaltime += ovs->srvdata->use_log.items.wash_mode_standard;
            out << i++ << tr(",표준세척,").toUtf8() << timetemp << "h\n";
            timetemp = ovs->srvdata->use_log.items.wash_mode_strong/3600;
            totaltime +=  ovs->srvdata->use_log.items.wash_mode_strong;
            out << i++ << tr(",강세척").toUtf8() << timetemp << "h\n";
            timetemp = ovs->srvdata->use_log.items.wash_mode_speed/3600;
            totaltime +=ovs->srvdata->use_log.items.wash_mode_speed;
            out << i++ << tr(",고속세척,").toUtf8() << timetemp << "h\n";
            timetemp = ovs->srvdata->use_log.items.cooldown_mode/3600;
            totaltime += ovs->srvdata->use_log.items.cooldown_mode;
            out << i++ << tr(",쿨다운,").toUtf8() << timetemp << "h\n";
            timetemp = totaltime/3600;
            out << i++ << tr(",전체작동시간,").toUtf8() << timetemp << "h\n";

            i=1;out<< strHeader;
            timetemp = ovs->srvdata->use_log.items.door_open/60;
            out << i++ << tr(",도어 Open,").toUtf8() << timetemp << "min\n";
            timetemp = ovs->srvdata->use_log.items.dv_open/60;
            out << i++ << tr(",볼밸브 Open,").toUtf8() << timetemp << "min\n";
            timetemp = ovs->srvdata->use_log.items.ssv_open/60;
            out << i++ << tr(",S/G 급수 솔레노이드,").toUtf8() << timetemp << "min\n";
            timetemp = ovs->srvdata->use_log.items.qnv_open/60;
            out << i++ << tr(",퀀칭 솔레노이드,").toUtf8() << timetemp << "min\n";
            timetemp = ovs->srvdata->use_log.items.snv_open/60;
            out << i++ << tr(",고내살수 노즐 솔레노이드 ,").toUtf8() << timetemp << "min\n";
            timetemp = 0;
            out << i++ << tr(",호스릴 솔레노이드,").toUtf8() << timetemp << "min\n";
            timetemp = ovs->srvdata->use_log.items.ssp_open/60;
            out << i++ << tr(",세제공급장치,").toUtf8() << timetemp << "min\n";
            timetemp = ovs->srvdata->use_log.items.hdm_open/60;
            out << i++ << tr(",배습댐퍼,").toUtf8() << timetemp << "min\n";
            timetemp = ovs->srvdata->use_log.items.dp_open/60;
            out << i++ << tr(",소형펌프모터,").toUtf8() << timetemp << "min\n";
            timetemp = ovs->srvdata->use_log.items.unp_open/60;
            out << i++ << tr(",중형펌프모터,").toUtf8() << timetemp << "min\n";
            ui->ctrWjProcess->setValue(100);
            ui->ctrLbRemainTime->setText(tr("남은 예상 시간 : 완료"));
            file.close();
            sync();
            QTimer::singleShot(1000,this,SLOT(close()));
        }
    }
}

void FileProcessDlg::programDownload(){
    QString strDescPath;
    QString strSrcPath;

    if(FileProcessor::detectUSB(strDescPath)){
        worker.setDestPath(QString("%1").arg(strDescPath));
        worker.addSrcDir("/prime/cookbook");
        worker.moveToThread(&programCopyThd);

        connect(&programCopyThd,SIGNAL(started()), &worker, SLOT(workerMain()));
        connect(&worker, SIGNAL(progressed(int,int)), this, SLOT(onProgressed(int,int)));
        connect(this, SIGNAL(stopcopy()), &worker, SLOT(workerStop()));
        connect(&worker, SIGNAL(finished()), &programCopyThd,SLOT(quit()));
        connect(&programCopyThd, SIGNAL(finished()), this, SLOT(onProgressFinished()));
        //connect(ui->ctrBtnCancel, SIGNAL(clicked(bool)), &worker, SLOT(workerStop()));

        programCopyThd.start();
        qDebug() << "thread start";
    }
    else{
        ui->ctrLbRemainTime->setText(tr("USB 인식을 실패하였습니다."));
        QTimer::singleShot(1000,this,SLOT(close()));
    }
}

void FileProcessDlg::onProgressFinished(){
    ui->ctrLbRemainTime->setText(tr("완료"));
    QTimer::singleShot(1000,this, SLOT(close()));
}

void FileProcessDlg::onProgressed(int progress, int sec){
    int min, _sec;
    QString strTemp;
    ui->ctrWjProcess->setValue(progress);
    min = sec/60;
    _sec = sec%60;
    if(min >0){
        strTemp.sprintf("남은 예상 시간 : %d분 %d초", min, _sec);
        ui->ctrLbRemainTime->setText(strTemp);
    }
    else{
        strTemp.sprintf("남은 예상 시간 : %d초",  sec);
        ui->ctrLbRemainTime->setText(strTemp);
    }
}

void FileProcessDlg::programUpload(){
    QString strDescPath;
    QString strSrcPath;

    if(FileProcessor::detectUSB(strSrcPath)){
        worker.addSrcFile(QString("%1/prime/falinux/run.sh,/falinux").arg(strSrcPath));
        worker.addSrcFile(QString("%1/prime/falinux/app-prime-modbus,/falinux").arg(strSrcPath));
        worker.addSrcFile(QString("%1/prime/falinux/app-prime-gui,/falinux").arg(strSrcPath));
        worker.addSrcFile(QString("%1/prime/falinux/service-web,/falinux").arg(strSrcPath));
        worker.addSrcFile(QString("%1/prime/falinux/templates/main.tmpl,/falinux/templates").arg(strSrcPath));
        worker.addSrcFile(QString("%1/prime/falinux/system.ini,/falinux").arg(strSrcPath));
        //worker.addSrcFile(QString("%1/prime/falinux/superdaemon,/falinux").arg(strSrcPath));
        //worker.addSrcFile(QString("%1/prime/falinux/superdaemon.ini,/falinux").arg(strSrcPath));
       worker.setDestPath("/prime");
        worker.addSrcDir(QString("%1/%2").arg(strSrcPath,"cookbook"));
        worker.moveToThread(&programCopyThd);

        connect(&programCopyThd,SIGNAL(started()), &worker, SLOT(workerMain()));
        connect(&worker, SIGNAL(progressed(int,int)), this, SLOT(onProgressed(int,int)));
        connect(this, SIGNAL(stopcopy()), &worker, SLOT(workerStop()));
        connect(&worker, SIGNAL(finished()), &programCopyThd,SLOT(quit()));
        connect(&programCopyThd, SIGNAL(finished()), this, SLOT(onProgressFinished()));
        //connect(ui->ctrBtnCancel, SIGNAL(clicked(bool)), &worker, SLOT(workerStop()));

        programCopyThd.start();
        qDebug() << "thread start";
    }
    else{
        ui->ctrLbRemainTime->setText(tr("USB 인식을 실패하였습니다."));
        QTimer::singleShot(1000,this,SLOT(close()));
    }
}

void FileProcessDlg::configDownload(){
    QString strUsbPath;
    if(FileProcessor::detectUSB(strUsbPath)){
        strUsbPath.append("/config.ini");
        qDebug() << strUsbPath;
        QFile file;
        file.setFileName(strUsbPath);
        if(file.exists()) file.remove();
        if(QFile::copy("/prime/config/config.ini", strUsbPath)){
            sync();
            ui->ctrWjProcess->setValue(50);
            ui->ctrLbRemainTime->setText(tr("남은 예상 시간 : 1초"));
        }
        else{
            ui->ctrLbRemainTime->setText(tr("설정 다운로드에 실패하였습니다."));
            QTimer::singleShot(1000,this,SLOT(close()));
            return;
        }
        strUsbPath.replace("/config.ini","/favorite.ini");
        file.setFileName(strUsbPath);
        if(file.exists()) file.remove();
        if(QFile::copy("/prime/config/favorite.ini", strUsbPath)){
            sync();
            ui->ctrWjProcess->setValue(100);
            ui->ctrLbRemainTime->setText("남은 예상 시간 : 0초");
            ui->ctrLbRemainTime->setText(tr("남은 예상 시간 : 완료"));
            QTimer::singleShot(1000,this,SLOT(close()));
        }
        else{
            ui->ctrLbRemainTime->setText(tr("즐겨찾기 다운로드에 실패하였습니다."));
            QTimer::singleShot(1000,this,SLOT(close()));
        }
    }
    else{
        ui->ctrLbRemainTime->setText(tr("USB 인식을 실패하였습니다."));
        QTimer::singleShot(1000,this,SLOT(close()));
    }
}

void FileProcessDlg::configUpload(){
    QString strUsbPath;
    Config *cfg = Config::getInstance();
    if(FileProcessor::detectUSB(strUsbPath)){
        strUsbPath.append("/config.ini");
        qDebug() << strUsbPath;
        QFile file("/prime/config/config.ini");
        file.remove();
        if(QFile::copy( strUsbPath , "/prime/config/config.ini")){
            sync();
            cfg->loadConfig();
            cfg->applyConfig();
            ui->ctrWjProcess->setValue(50);
            ui->ctrLbRemainTime->setText(tr("남은 예상 시간 : 1초"));
        }
        else{
            ui->ctrLbRemainTime->setText(tr("설정 업로드에 실패하였습니다."));
            QTimer::singleShot(1000,this,SLOT(close()));
            return;
        }
        QFile file2("/prime/config/favorite.ini");
        file2.remove();
        strUsbPath.replace("/config.ini", "/favorite.ini");
        qDebug() << strUsbPath;
        if(QFile::copy( strUsbPath , "/prime/config/favorite.ini")){
            sync();
            cfg->loadFavorite();
            ui->ctrWjProcess->setValue(100);
            ui->ctrLbRemainTime->setText(tr("남은 예상 시간 : 완료"));
            QTimer::singleShot(1000,this,SLOT(close()));
        }
        else{
            ui->ctrLbRemainTime->setText(tr("즐겨찾기 업로드에 실패하였습니다."));
            QTimer::singleShot(1000,this,SLOT(close()));
        }
    }
    else{
        ui->ctrLbRemainTime->setText(tr("USB 인식을 실패하였습니다."));
        QTimer::singleShot(1000,this,SLOT(close()));
    }
}