#include "ovenstatics.h"
#include <QtDebug>
#include <QApplication>
#include <QTimer>
#include "mainwindow.h"
#include "ovencontroller.h"
#include "engineermenuwindow.h"
#include "errorpopupdlg.h"
#include "historylistwindow.h"
#include "servicepassinputdlg.h"
#include "haccp.h"

OvenStatistics* OvenStatistics::p_singletonInstance=NULL;

OvenStatistics* OvenStatistics::getInstance(QObject *parent){
    if(!p_singletonInstance){
        p_singletonInstance = new OvenStatistics(parent);
        p_singletonInstance->udp = UdpHandler::getInstance();
        p_singletonInstance->oven = Oven::getInstance();
        p_singletonInstance->cfg = Config::getInstance();
        //for singletone event debug
//        MainWindow* mw = (MainWindow*)parent;
//        connect(mw->pcombiButton, SIGNAL(clicked()),p_singtonInstance, SLOT(onDataChanged()));
        connect(p_singletonInstance->udp , SIGNAL(changed()), p_singletonInstance, SLOT(onDataChanged()));
        QTimer *timer = new QTimer(p_singletonInstance);
        connect(timer, SIGNAL(timeout()),p_singletonInstance,SLOT(oneSecTimerFired()));
        timer->start(1000); //1000ms fired
    }
    return p_singletonInstance;
}

void OvenStatistics::destroy(){
    if(!p_singletonInstance)
        delete p_singletonInstance;
}


OvenStatistics::OvenStatistics(QObject* parent) :QObject(parent)
{
    int i = 0;
    curdoorstate = false;
    curSysErrorState = 0;
    curCommErrorState = 0;
    curSensorErrorState = 0;
    curControlErrorState = 0;
    bDataRefreshed = false;
    realdata.d32 = 0;
    m_bPopupShow = false;
    m_nLastPopupidx = MAX_ERROR_TYPE_CNT;

    for(i=0;i<MAX_LOG_SENSOR;i++){
        curSensorValue[i].utemp = 0;
    }

    curSensorValue[12].itemp = 100;

    srvdata = new ServiceData();

}

OvenStatistics::~OvenStatistics(){
    delete srvdata;
}


void OvenStatistics::onDataChanged()
{
    error_item *item;
    time_t ltime=0;
    uint16_t errstatetemp;
    uint8_t cookingstate=0;
    udp->fillControl(control);
    udp->fillData(state);
    bDataRefreshed = true;
    time(&ltime);

    if((control.cooking || oven->cooking() || oven->preheating() || oven->cooldown())) cookingstate = 1;
    else if(state.cleaning_sate != 0 ) cookingstate = 2;

    if(oven->cooking() && control.system){
        if(state.door_state ==1 && curdoorstate==0){
            //door error
            item = &(srvdata->err_log.items.door);
            item->fired_cnt+=1;
            if(item->first_fired==0)item->first_fired = ltime;
            item->last_fried = ltime;
        }
        curdoorstate = state.door_state;
    }

    qDebug() << "cooking state " << cookingstate << "model " << cfg->getConfigValue(Define::config_model).d32;
    qDebug() << state.system_error << "and sys mask " << sys_err_mask[cookingstate][cfg->getConfigValue(Define::config_model).d32];
    if(state.system_error!=0 &&  state.system_error != curSysErrorState){
        processSystemError( (state.system_error & sys_err_mask[cookingstate][cfg->getConfigValue(Define::config_model).d32]) ,ltime);
    }
    curSysErrorState = state.system_error;

//    errstatetemp = state.communication_error;
//    if(errstatetemp!=0 && errstatetemp != curCommErrorState ){
//        processCommError( (errstatetemp & comm_err_mask[cookingstate][cfg->getConfigValue(Define::config_model).d32]),ltime );
//    }
//    curCommErrorState = errstatetemp;

    errstatetemp = state.sensor_error;
    if(errstatetemp!=0 && errstatetemp != curSensorErrorState ){
        processSensorError( (errstatetemp& sensor_err_mask[cookingstate][cfg->getConfigValue(Define::config_model).d32]),ltime );
    }
    curSensorErrorState = errstatetemp;

//    errstatetemp = state.controller_error;
//    if(errstatetemp != 0 && errstatetemp != curControlErrorState){
//        processStateError((errstatetemp&state_err_mask[cookingstate][cfg->getConfigValue(Define::config_model).d32]),ltime);
//    }
//    curControlErrorState = errstatetemp;

}

void OvenStatistics::processSensorError(uint16_t errflag, time_t ltime){
    error_item *item;
    QString strMsg = "",strTitle="";
    uint8_t state;
    bool bCookingState = (control.cooking || oven->cooking() || oven->preheating() || oven->cooldown());
    if( control.system==0 && !bCookingState  ) state = SYS_OFF_COOK_OFF;
    else if(control.system != 0 && !bCookingState) state = SYS_ON_COOK_OFF;
    else if(control.system !=0 && bCookingState) state = SYS_ON_COOK_ON;
    else if(control.system !=0 && this->state.cleaning_sate  !=0 ) state = SYS_ON_WASH;
    else state = SYS_ON_COOK_OFF;

    if(errflag & MAKE_MASK(SENSOR_ERR_SENSOR_1)){
        item = &(srvdata->err_log.items.inner_temp_fail);
        strTitle = tr("내부 온도 센서 이상");
        strMsg  = tr("조리실 내부 온도센서 오류가 발생하였습니다.\n제품의 전원을 OFF한 후 다시 ON해 주십시오.\n이 후에도 문제가 해결되지 않을 경우, 서비스센터로 연락하여 주십시오.");
        processErrorItems(item,sensor_err_type_def[state][SENSOR_ERR_SENSOR_1],strMsg,strTitle, ltime, sensor_err_sound_def[SENSOR_ERR_SENSOR_1]);
    }
    if(errflag & MAKE_MASK(SENSOR_ERR_SENSOR_2)){
        item = &(srvdata->err_log.items.qunching_temp_fail);
        strTitle  = tr("배수 탱크 온도 센서 이상");
        strMsg  = tr("배수 탱크 온도센서 오류가 발생하였습니다.\n제품의 전원을 OFF한 후 다시 ON해 주십시오.\n이 후에도 문제가 해결되지 않을 경우, 서비스센터로 연락하여 주십시오.");
        processErrorItems(item,sensor_err_type_def[state][SENSOR_ERR_SENSOR_2],strMsg,strTitle, ltime,sensor_err_sound_def[SENSOR_ERR_SENSOR_2]);
    }
    if(errflag & MAKE_MASK(SENSOR_ERR_SENSOR_3)){
        //Reserved allerrornoe 설정
        item = &(srvdata->err_log.items.qunching_temp_fail);
        strTitle  = tr("퀀칭 온도 센서 발생");
        strMsg  = tr("퀀칭 온도센서 오류가 발생하였습니다.\n제품의 전원을 OFF한 후 다시 ON해 주십시오.\n이 후에도 문제가 해결되지 않을 경우, 서비스센터로 연락하여 주십시오.");
        processErrorItems(item,sensor_err_type_def[state][SENSOR_ERR_SENSOR_3],strMsg,strTitle, ltime,sensor_err_sound_def[SENSOR_ERR_SENSOR_3]);
    }
    if(errflag & MAKE_MASK(SENSOR_ERR_SENSOR_4)){
        item = &(srvdata->err_log.items.wall_temp1_fail);
        strTitle  = tr("벽면 온도 센서 이상");
        strMsg  = tr("조리실 벽면 센서 오류가 발생하였습니다.\n제품의 전원을 OFF한 후 다시 ON해 주십시오.\n이 후에도 문제가 해결되지 않을 경우, 서비스센터로 연락하여 주십시오.");
        processErrorItems(item,sensor_err_type_def[state][SENSOR_ERR_SENSOR_4],strMsg,strTitle, ltime,sensor_err_sound_def[SENSOR_ERR_SENSOR_4]);
    }
    if(errflag & MAKE_MASK(SENSOR_ERR_SENSOR_5)){
        item = &(srvdata->err_log.items.steam_gen_temp_fail);
        strTitle  = tr("스팀발생기 온도 센서 이상");
        strMsg  = tr("스팀발생기 내부 센서 오류가 발생하였습니다.\n제품의 전원을 OFF한 후 다시 ON해 주십시오.\n이 후에도 문제가 해결되지 않을 경우, 서비스센터로 연락하여 주십시오.");
        processErrorItems(item,sensor_err_type_def[state][SENSOR_ERR_SENSOR_5],strMsg,strTitle, ltime,sensor_err_sound_def[SENSOR_ERR_SENSOR_5]);
    }
    if(errflag & MAKE_MASK(SENSOR_ERR_SENSOR_6)){
        item = &(srvdata->err_log.items.meatprove_temp1_fail);
        strTitle  = tr("중심온도 센서 이상");
        strMsg  = tr("중심온도계 센서 오류가 발생하였습니다.\n제품의 전원을 OFF한 후 다시 ON해 주십시오.\n이 후에도 문제가 해결되지 않을 경우, 서비스센터로 연락하여 주십시오.");
        processErrorItems(item,sensor_err_type_def[state][SENSOR_ERR_SENSOR_6],strMsg,strTitle, ltime,sensor_err_sound_def[SENSOR_ERR_SENSOR_6]);
    }
    if(errflag & MAKE_MASK(SENSOR_ERR_SENSOR_7)){
       //Reseved
        item = &(srvdata->err_log.items.meatprove_temp2_fail);
        strTitle  = tr("중심온도 센서 이상");
        strMsg  = tr("중심온도계 센서 오류가 발생하였습니다.\n제품의 전원을 OFF한 후 다시 ON해 주십시오.\n이 후에도 문제가 해결되지 않을 경우, 서비스센터로 연락하여 주십시오.");
        processErrorItems(item,sensor_err_type_def[state][SENSOR_ERR_SENSOR_7],strMsg , strTitle, ltime,sensor_err_sound_def[SENSOR_ERR_SENSOR_7]);
    }
    if(errflag & MAKE_MASK(SENSOR_ERR_SENSOR_8)){
        //Reserved
        item = &(srvdata->err_log.items.meatprove_temp3_fail);
        strTitle  = tr("중심온도 센서 이상");
        strMsg  = tr("중심온도계 센서 오류가 발생하였습니다.\n제품의 전원을 OFF한 후 다시 ON해 주십시오.\n이 후에도 문제가 해결되지 않을 경우, 서비스센터로 연락하여 주십시오.");
        processErrorItems(item,sensor_err_type_def[state][SENSOR_ERR_SENSOR_8],strMsg,strTitle, ltime,sensor_err_sound_def[SENSOR_ERR_SENSOR_8]);
    }
    if(errflag & MAKE_MASK(SENSOR_ERR_SENSOR_9)){
        //Reserved
        item = &(srvdata->err_log.items.meatprove_temp4_fail);
        strTitle  = tr("중심온도 센서 이상");
        strMsg  = tr("중심온도계 센서 오류가 발생하였습니다.\n제품의 전원을 OFF한 후 다시 ON해 주십시오.\n이 후에도 문제가 해결되지 않을 경우, 서비스센터로 연락하여 주십시오.");
        processErrorItems(item,sensor_err_type_def[state][SENSOR_ERR_SENSOR_9],strMsg,strTitle, ltime,sensor_err_sound_def[SENSOR_ERR_SENSOR_9]);
    }
    if(errflag & MAKE_MASK(SENSOR_ERR_SENSOR_10)){
        item = &(srvdata->err_log.items.pcb_temp_fail);
        strTitle  = tr("PCB온도 과열 이상");
        strMsg  = tr("PCB 과열  안전장치가 작동하였습니다.\n제품의 전원을 OFF한 뒤, 즉시 서비스센터에 연락하여 주십시오.");
        processErrorItems(item,sensor_err_type_def[state][SENSOR_ERR_SENSOR_10],strMsg,strTitle, ltime,sensor_err_sound_def[SENSOR_ERR_SENSOR_10]);
    }
}

void OvenStatistics::processCommError(uint16_t errflag, time_t ltime){
    error_item *item;
    QString strMsg = "",strTitle="";
    uint8_t state;
    bool bCookingState = (control.cooking || oven->cooking() || oven->preheating() || oven->cooldown());
    if( control.system==0 && !bCookingState  ) state = SYS_OFF_COOK_OFF;
    else if(control.system != 0 && !bCookingState) state = SYS_ON_COOK_OFF;
    else if(control.system !=0 && bCookingState) state = SYS_ON_COOK_ON;
    else if(control.system !=0 && this->state.cleaning_sate  !=0 ) state = SYS_ON_WASH;
    else state = SYS_ON_COOK_OFF;

    if(errflag & MAKE_MASK(COMM_ERR_BUNNER1)){
        item = &(srvdata->err_log.items.upper_pan_fail);
        strTitle  = tr("상부 버너 컨트롤러 통신 이상");
        strMsg  = tr("상부 버너 컨트롤러 PCB 통신 불량이 발생하였습니다.\n제품의 전원을 OFF한 후 다시 ON해 주십시오.\n이 후에도 문제가 해결되지 않을 경우, 서비스센터로 연락하여 주십시오.");
        processErrorItems(item,comm_err_type_def[state][COMM_ERR_BUNNER1],strMsg,strTitle, ltime, comm_err_sound_def[COMM_ERR_BUNNER1]);
    }
    if(errflag & MAKE_MASK(COMM_ERR_BUNNER2)){
        item = &(srvdata->err_log.items.lower_pan_fail);
        strTitle  = tr("하부 버너 컨트롤러 통신 이상");
        strMsg  = tr("하 버너 컨트롤러 PCB 통신 불량이 발생하였습니다.\n제품의 전원을 OFF한 후 다시 ON해 주십시오.\n이 후에도 문제가 해결되지 않을 경우, 서비스센터로 연락하여 주십시오.");
        processErrorItems(item,comm_err_type_def[state][COMM_ERR_BUNNER2],strMsg,strTitle, ltime, comm_err_sound_def[COMM_ERR_BUNNER2]);
    }
    if(errflag & MAKE_MASK(COMM_ERR_BUNNER3)){
        item = &(srvdata->err_log.items.steam_pan_fail);
        strTitle  = tr("스팀 버너 컨트롤러 통신 이상");
        strMsg  = tr("스팀발생기 버너 컨트롤러 PCB 통신 불량이 발생하였습니다.\n제품의 전원을 OFF한 후 다시 ON해 주십시오.\n이 후에도 문제가 해결되지 않을 경우, 서비스센터로 연락하여 주십시오.");
        processErrorItems(item,comm_err_type_def[state][COMM_ERR_BUNNER3],strMsg,strTitle, ltime, comm_err_sound_def[COMM_ERR_BUNNER3]);
    }
    if(errflag & MAKE_MASK(COMM_ERR_LOWERFAN)){
        item = &(srvdata->err_log.items.lower_motor_fail);
        strTitle  = tr("하부 FAN 모터 컨트롤러 이상");
        strMsg  = tr("하부 Fan 모터 컨트롤러 이상 상황이 발생하였습니다.\n제품의 전원을 OFF한 후 다시 ON해 주십시오.\n이 후에도 문제가 해결되지 않을 경우, 서비스센터로 연락하여 주십시오.");
        processErrorItems(item,comm_err_type_def[state][COMM_ERR_BUNNER2],strMsg,strTitle, ltime, comm_err_sound_def[COMM_ERR_LOWERFAN]);
    }
    if(errflag & MAKE_MASK(COMM_ERR_UPPERFAN)){
        item = &(srvdata->err_log.items.upper_motor_fail);
        strTitle  = tr("상부 FAN 모터 컨트롤러 이상");
        strMsg  = tr("상부 Fan 모터 컨트롤러 이상 상황이 발생하였습니다.\n제품의 전원을 OFF한 후 다시 ON해 주십시오.\n이 후에도 문제가 해결되지 않을 경우, 서비스센터로 연락하여 주십시오.");
        processErrorItems(item,comm_err_type_def[state][COMM_ERR_BUNNER2],strMsg,strTitle, ltime, comm_err_sound_def[COMM_ERR_UPPERFAN]);
    }
}

void OvenStatistics::processStateError(uint16_t errflag, time_t ltime){
    error_item *item;
    QString strMsg = "",strTitle="";
    uint8_t state;
    bool bCookingState = (control.cooking || oven->cooking() || oven->preheating() || oven->cooldown());
    if( control.system==0 && !bCookingState  ) state = SYS_OFF_COOK_OFF;
    else if(control.system != 0 && !bCookingState) state = SYS_ON_COOK_OFF;
    else if(control.system !=0 && bCookingState) state = SYS_ON_COOK_ON;
    else if(control.system !=0 && this->state.cleaning_sate  !=0 ) state = SYS_ON_WASH;
    else state = SYS_ON_COOK_OFF;

    if(errflag & MAKE_MASK(STATE_ERR_BUNNER1)){
        item = &(srvdata->err_log.items.upper_pan_fail);
        strMsg  = tr("버너컨트롤러 1 이상 발생하였습니다.");
        strTitle  = tr("버너컨트롤러 1 이상 발생");
        processErrorItems(item,state_err_type_def[state][STATE_ERR_BUNNER1],strMsg,strTitle, ltime, state_err_sound_def[STATE_ERR_BUNNER1]);
    }
    if(errflag & MAKE_MASK(STATE_ERR_BUNNER2)){
        item = &(srvdata->err_log.items.lower_pan_fail);
        strMsg  = tr("버너컨트롤러 2 이상  발생하였습니다.");
        strTitle  = tr("버너컨트롤러 2 이상 발생");
        processErrorItems(item,state_err_type_def[state][STATE_ERR_BUNNER2],strMsg,strTitle, ltime, state_err_sound_def[STATE_ERR_BUNNER2]);
    }
    if(errflag & MAKE_MASK(STATE_ERR_BUNNER3)){
        item = &(srvdata->err_log.items.steam_pan_fail);
        strMsg  = tr("버너컨트롤러 3 이상 발생하였습니다.");
        strTitle  = tr("버너컨트롤러 3 이상 발생");
        processErrorItems(item,state_err_type_def[state][STATE_ERR_BUNNER3],strMsg,strTitle, ltime, state_err_sound_def[STATE_ERR_BUNNER3]);
    }
    if(errflag & MAKE_MASK(STATE_ERR_LOWERFAN)){
        item = &(srvdata->err_log.items.lower_motor_fail);
        strMsg  = tr("하부 FAN 컨트롤러 이상 발생하였습니다.");
        strTitle  = tr("하부 FAN 컨트롤러 이상 발생");
        processErrorItems(item,state_err_type_def[state][STATE_ERR_BUNNER2],strMsg,strTitle, ltime, state_err_sound_def[STATE_ERR_LOWERFAN]);
    }
    if(errflag & MAKE_MASK(STATE_ERR_UPPERFAN)){
        item = &(srvdata->err_log.items.upper_motor_fail);
        strMsg  = tr("상부 FAN 컨트롤러 이상 발생하였습니다.");
        strTitle  = tr("상부 FAN 컨트롤러 이상 발생");
        processErrorItems(item,state_err_type_def[state][STATE_ERR_BUNNER2],strMsg,strTitle, ltime, state_err_sound_def[STATE_ERR_UPPERFAN]);
    }
}

void OvenStatistics::processSystemError(uint16_t errflag,time_t ltime){
   error_item *item;
   QString strMsg = "",strTitle = "";
   uint8_t state;
   bool bCookingState = (control.cooking || oven->cooking() || oven->preheating() || oven->cooldown());
   if( control.system==0 && !bCookingState  ) state = SYS_OFF_COOK_OFF;
   else if(control.system != 0 && !bCookingState) state = SYS_ON_COOK_OFF;
   else if(control.system !=0 && bCookingState) state = SYS_ON_COOK_ON;
   else if(control.system !=0 && this->state.cleaning_sate  !=0 ) state = SYS_ON_WASH;
   else state = SYS_ON_COOK_OFF;

    if( errflag & MAKE_MASK(SYS_ERR_FIRE_TRIGGER1)){
        //버너 컨트롤러 1 착화 이상
        item = &(srvdata->err_log.items.upper_fire_fail);
        strTitle = tr("상부 버너 착화 이상");
        strMsg  = tr("상부 버너 착화 이상 안전장치가 작동하였습니다.\n제품의 전원을 OFF한 후 가스 밸브가 잠겨있는지 확인 해 주십시오.\n가스 밸브가 열려 있는데도 에러 발생 시, 즉시 서비스센터에 연락하여 주십시오.");
        processErrorItems(item, sys_err_type_def[state][SYS_ERR_FIRE_TRIGGER1],strMsg,strTitle,ltime, sys_err_sound_def[SYS_ERR_FIRE_TRIGGER1]);
    }
    if(errflag & MAKE_MASK(SYS_ERR_FIRE_TRIGGER2)){
        //버너 컨트롤러 2 착화 이상
        item = &(srvdata->err_log.items.lower_fire_fail);
        strTitle = tr("하부 버너 착화 이상");
        strMsg  = tr("하부 버너 착화 이상 안전장치가 작동하였습니다.\n제품의 전원을 OFF한 후 가스 밸브가 잠겨있는지 확인 해 주십시오.\n가스 밸브가 열려 있는데도 에러 발생 시, 즉시 서비스센터에 연락하여 주십시오.");
        processErrorItems(item, sys_err_type_def[state][SYS_ERR_FIRE_TRIGGER2],strMsg,strTitle,ltime, sys_err_sound_def[SYS_ERR_FIRE_TRIGGER1]);
    }
    if(errflag & MAKE_MASK(SYS_ERR_FIRE_TRIGGER3)){
        item = &(srvdata->err_log.items.steam_fire_fail);
        strTitle = tr("스팀 버너 착화 이상");
        strMsg  = tr("스팀발생기 버너 착화 이상 안전장치가 작동하였습니다.\n제품의 전원을 OFF한 후 가스 밸브가 잠겨있는지 확인 해 주십시오.\n가스 밸브가 열려 있는데도 에러 발생 시, 즉시 서비스센터에 연락하여 주십시오.");
         processErrorItems(item, sys_err_type_def[state][SYS_ERR_FIRE_TRIGGER3],strMsg,strTitle,ltime, sys_err_sound_def[SYS_ERR_FIRE_TRIGGER3]);
    }
    if(errflag & MAKE_MASK(SYS_ERR_OVNE_TEMP_ALARM)){
        item = &(srvdata->err_log.items.inner_temp_high_alarm);
        strTitle  = tr("내부 온도 과열 이상");
        strMsg  = tr("조리실 내부 과열 안전장치가 작동하였습니다.\n제품의 전원을 OFF한 뒤, 즉시 서비스센터에 연락하여 주십시오.");
         processErrorItems(item, sys_err_type_def[state][SYS_ERR_OVNE_TEMP_ALARM],strMsg,strTitle,ltime,sys_err_sound_def[SYS_ERR_OVNE_TEMP_ALARM]);
    }
    if(errflag & MAKE_MASK(SYS_ERR_QUN_TEMP_ALARM)){
        //퀀칭 온도 센서 과열
        item = &(srvdata->err_log.items.qunching_temp_high_alarm);
        strTitle  = tr("배수 탱크 온도 과열 이상");
        strMsg  = tr("배수 탱크 과열 안전장치가 작동하였습니다.\n제품의 전원을 OFF한 뒤, 즉시 서비스센터에 연락하여 주십시오.");
         processErrorItems(item, sys_err_type_def[state][SYS_ERR_QUN_TEMP_ALARM],strMsg,strTitle,ltime,sys_err_sound_def[SYS_ERR_QUN_TEMP_ALARM]);
    }
    if(errflag & MAKE_MASK(SYS_ERR_CENTER_TEMP_ALARM)){
        //중심 온도 과열
        item = &(srvdata->err_log.items.meatprove_temp1_high_alarm);
        strTitle  = tr("중심 온도 과열 이상");
        strMsg  = tr("중심온도계 과열 안전장치가 작동하였습니다.\n제품의 전원을 OFF한 뒤, 즉시 서비스센터에 연락하여 주십시오.");
         processErrorItems(item, sys_err_type_def[state][SYS_ERR_CENTER_TEMP_ALARM],strMsg,strTitle,ltime, sys_err_sound_def[SYS_ERR_CENTER_TEMP_ALARM]);
    }
    if(errflag & MAKE_MASK(SYS_ERR_WALL_TEMP_ALARM)){
        item = &(srvdata->err_log.items.wall_temp1_high_alarm);
        strTitle  = tr("벽면 온도 과열 이상");
        strMsg  = tr("조리실 벽면 과열 안전장치가 작동하였습니다.\n제품의 전원을 OFF한 뒤, 즉시 서비스센터에 연락하여 주십시오.");
         processErrorItems(item, sys_err_type_def[state][SYS_ERR_WALL_TEMP_ALARM],strMsg,strTitle,ltime, sys_err_sound_def[SYS_ERR_WALL_TEMP_ALARM]);
    }
   if(errflag & MAKE_MASK(SYS_ERR_STAM_TEMP_ALARM)){
       item = &(srvdata->err_log.items.steam_gen_temp_high_alram);
       strTitle  = tr("스팀 온도 과열 이상");
       strMsg  = tr("스팀통 내부 과열 안전장치가 작동하였습니다.\n제품의 전원을 OFF한 뒤, 즉시 서비스센터에 연락하여 주십시오.");
        processErrorItems(item, sys_err_type_def[state][SYS_ERR_STAM_TEMP_ALARM],strMsg,strTitle,ltime, sys_err_sound_def[SYS_ERR_STAM_TEMP_ALARM]);
   }
    if(errflag & MAKE_MASK(SYS_ERR_WATER_SPLY_FAIL)){
        //급수 이상 -> 유량 센서 이상
        item = &(srvdata->err_log.items.water_level_sensor_fail);
        strTitle  = tr("급수 이상");
        strMsg  = tr("제품 급수이상 안전장치가 작동하였습니다.\n제품에 들어가는 물 공급을 확인하십시오.\n물 공급이 정상적으로 들어갈 시 즉시 서비스센터에 연락하여 주십시오.\n단수 유무는 샤워건을 사용하십시오.");
         processErrorItems(item, sys_err_type_def[state][SYS_ERR_WATER_SPLY_FAIL],strMsg,strTitle,ltime, sys_err_sound_def[SYS_ERR_WATER_SPLY_FAIL]);
    }
    if(errflag & MAKE_MASK(SYS_ERR_WATER_LEVEL_FAIL)){
        //급수 이상 -> 수위 센서 이상
        item = &(srvdata->err_log.items.water_level_sensor_fail);
        strTitle  = tr("수위 센서 이상");
        strMsg  = tr("스팀통 수위 감지 안전장치가 작동하였습니다.\n제품에 들어가는 물 공급을 확인하십시오.\n물 공급이 정상적으로 들어갈 시 즉시 서비스센터에 연락하여 주십시오.\n단수 유무는 샤워건을 사용하십시오.");
         processErrorItems(item, sys_err_type_def[state][SYS_ERR_WATER_LEVEL_FAIL],strMsg,strTitle,ltime, sys_err_sound_def[SYS_ERR_WATER_LEVEL_FAIL]);
    }
}




bool OvenStatistics::getNeedErrorClear(){
    return bNeedErrorClear;
}

void OvenStatistics::clearNeedErrorClear(){
    //에러클리어 송신 후 flag clear
    bNeedErrorClear = false;
}

void OvenStatistics::oneSecTimerFired(void){
    static int nOneSecCnt=1;
    time_t ltime;

    static int nStateErrValStableCnt = 0;
    static int nCommErrValStableCnt = 0;
    static uint16_t nCommErrVal = 0;
    static uint16_t nStateErrVal = 0;
    uint16_t errstatetemp=0;
    int cookingstate=0;
    if((control.cooking || oven->cooking() || oven->preheating() || oven->cooldown())) cookingstate  =1;
    else if(state.cleaning_sate !=0) cookingstate = 2;

    ltime = time(NULL);

    nOneSecCnt++;
    if( (nOneSecCnt % 10) ==0 ) {
        srvdata->saveServiceData();
    }


    if(bDataRefreshed) bDataRefreshed= false;
    else{
        udp->fillControl(control);
        udp->fillData(state);
    }

    if(nCommErrVal !=  state.communication_error){
        nCommErrVal = state.communication_error;
        if(nCommErrVal ==0) {
            curCommErrorState = nCommErrVal;
            nCommErrValStableCnt = DELAY_ERROR_TIME;
        }
        else {
            nCommErrValStableCnt=0;
        }
    }
    else{
        if(nCommErrValStableCnt >=DELAY_ERROR_TIME){
            errstatetemp = state.communication_error;
            if(errstatetemp!=0 && errstatetemp != curCommErrorState ){
                processCommError( (errstatetemp & comm_err_mask[cookingstate][cfg->getConfigValue(Define::config_model).d32]),ltime );
            }
            curCommErrorState = errstatetemp;
        }
        else nCommErrValStableCnt++;
    }

    if(nStateErrVal != state.controller_error){
        nStateErrVal = state.controller_error;
        if(nStateErrVal == 0 ) {
            curControlErrorState = nStateErrVal;
            nStateErrValStableCnt=DELAY_ERROR_TIME;
        }
        else{
            nStateErrValStableCnt=0;
        }
    }
    else{
        if(nStateErrValStableCnt>=DELAY_ERROR_TIME){
            errstatetemp = state.controller_error;
            if(errstatetemp != 0 && errstatetemp != curControlErrorState){
                processStateError((errstatetemp&state_err_mask[cookingstate][cfg->getConfigValue(Define::config_model).d32]),ltime);
            }
            curControlErrorState = errstatetemp;
        }
        else nStateErrValStableCnt++;
    }

    //가열부 시간 측정
    if( (state.onoff_state1 & LOAD_STATE1_STEAM_BUNNER) !=0){
        srvdata->use_log.items.steam_heat +=1;
    }
    if( (state.onoff_state1 & (LOAD_STATE1_UPPER_BUNNER | LOAD_STATE1_LOWER_FAN))!=0){
        srvdata->use_log.items.dry_heat+=1;
        if(state.onoff_state1 & (LOAD_STATE1_UPPER_BUNNER)){
            srvdata->use_log.items.upper_heat +=1;
        }
        if((state.onoff_state2 & LOAD_STATE1_LOWER_BUNNER)!=0){
            srvdata->use_log.items.lower_heat +=1;
        }
    }
    //모드 시간 계산
    if(state.cooking_mode !=0){
        if(state.cooking_humidity==0){
            //건열 모드
            srvdata->use_log.items.cook_dry_mode+=1;
        }
        else if(state.cooking_humidity ==100){
            //스팀모드
            srvdata->use_log.items.cook_steam_mode+=1;
        }
        else srvdata->use_log.items.cook_combi_mode+=1;
    }
    if(state.cleaning_mode !=0 && state.cleaning_sate !=0){
        switch (state.cleaning_mode) {
        case (uint16_t)wash_mode_nocleanser:
            srvdata->use_log.items.wash_mode_nocleanser+=1;
            break;
        case (uint16_t)wash_mode_simple:
            srvdata->use_log.items.wash_mode_simple+=1;
            break;
        case (uint16_t)wash_mode_standard:
            srvdata->use_log.items.wash_mode_standard+=1;
            break;
        case (uint16_t)wash_mode_strong:
            srvdata->use_log.items.wash_mode_strong+=1;
            break;
        case (uint16_t)wash_mode_highspeed:
            srvdata->use_log.items.wash_mode_speed+=1;
            break;
        default:
            break;
        }
    }
    if(control.cooldown ==1){
        srvdata->use_log.items.cooldown_mode+=1;
    }
    //부품
    if(state.door_state !=0){
        srvdata->use_log.items.door_open+=1;

    }


    if(state.onoff_state2 !=0){
           if( (state.onoff_state2 & LOAD_STATE2_DV)!=0){
               srvdata->use_log.items.dv_open+=1;
           }
           if((state.onoff_state2 & LOAD_STATE2_SSV)!=0){
               srvdata->use_log.items.ssv_open+=1;
           }
           if((state.onoff_state2 & LOAD_STATE2_QNV)!=0){
               srvdata->use_log.items.qnv_open+=1;
           }
           if((state.onoff_state2 & LOAD_STATE2_SNV)!=0){
               srvdata->use_log.items.snv_open+=1;
           }
           if((state.onoff_state2 & LOAD_STATE2_SSP)!=0){
               srvdata->use_log.items.ssp_open+=1;
           }
           if((state.onoff_state2 & LOAD_STATE2_HDM)!=0){
               srvdata->use_log.items.hdm_open+=1;
           }
           if((state.onoff_state2 & LOAD_STATE2_DP)!=0){
               srvdata->use_log.items.dp_open+=1;
           }
           if((state.onoff_state2 & LOAD_STATE2_UNP) !=0){
               srvdata->use_log.items.unp_open+=1;
           }
    }

    //Real time Data Refresh

    realdata.b.door_open = state.door_state==0?0:1;
    realdata.b.dv_open = (state.onoff_state2&LOAD_STATE2_DV)==0?0:1;
    realdata.b.qnv_open = (state.onoff_state2&LOAD_STATE2_QNV)==0?0:1;
    realdata.b.sgnv_open = (state.onoff_state2&LOAD_STATE2_SGNV)==0?0:1;
    realdata.b.snv_open = (state.onoff_state2&LOAD_STATE2_SNV)==0?0:1;
    realdata.b.wsv_open = (state.onoff_state2&LOAD_STATE2_WSV)==0?0:1;
    realdata.b.ssv_open = (state.onoff_state2&LOAD_STATE2_SSV)==0?0:1;

    if( (state.reserved11&0x0018)  ==  0x0018)  realdata.b.water_level = water_level_high;
    else if( (state.reserved11&0x0018)  == 0x0000) realdata.b.water_level = water_level_low;
    else realdata.b.water_level = water_level_normal;

    if(srvdata->sensor_log.items.B1.high_temp.itemp < state.sensor1 ){
        srvdata->sensor_log.items.B1.high_temp.itemp = state.sensor1;
        srvdata->sensor_log.items.B1.last_high_time = ltime;
    }
    curSensorValue[0].itemp = state.sensor1;

    if(srvdata->sensor_log.items.B2.high_temp.itemp < state.sensor2 ){
        srvdata->sensor_log.items.B2.high_temp.itemp = state.sensor2;
        srvdata->sensor_log.items.B2.last_high_time = ltime;
    }
    curSensorValue[1].itemp = state.sensor2;

    if(srvdata->sensor_log.items.B3_1.high_temp.itemp < state.sensor6 ){
        srvdata->sensor_log.items.B3_1.high_temp.itemp = state.sensor6;
        srvdata->sensor_log.items.B3_1.last_high_time = ltime;
    }
    curSensorValue[5].itemp = state.sensor6;

    if(srvdata->sensor_log.items.B4.high_temp.itemp < state.sensor4 ){
        srvdata->sensor_log.items.B4.high_temp.itemp = state.sensor4;
        srvdata->sensor_log.items.B4.last_high_time = ltime;
    }
     curSensorValue[3].itemp = state.sensor4;

    if(srvdata->sensor_log.items.B5.high_temp.itemp < state.sensor5 ){
        srvdata->sensor_log.items.B5.high_temp.itemp = state.sensor5;
        srvdata->sensor_log.items.B5.last_high_time = ltime;
    }
    curSensorValue[4].itemp = state.sensor5;

    if(srvdata->sensor_log.items.B3_2.high_temp.itemp < state.sensor7 ){
        srvdata->sensor_log.items.B3_2.high_temp.itemp = state.sensor7;
        srvdata->sensor_log.items.B3_2.last_high_time = ltime;
    }
    curSensorValue[6].itemp = state.sensor7;

    if(srvdata->sensor_log.items.B3_3.high_temp.itemp < state.sensor8 ){
        srvdata->sensor_log.items.B3_3.high_temp.itemp = state.sensor8;
        srvdata->sensor_log.items.B3_3.last_high_time = ltime;
    }
    curSensorValue[7].itemp = state.sensor8;

    if(srvdata->sensor_log.items.B3_4.high_temp.itemp < state.sensor9 ){
        srvdata->sensor_log.items.B3_4.high_temp.itemp = state.sensor9;
        srvdata->sensor_log.items.B3_4.last_high_time = ltime;
    }
    curSensorValue[8].itemp = state.sensor9;

    if(srvdata->sensor_log.items.mbar1.high_temp.utemp < state.sensor11 ){
        srvdata->sensor_log.items.mbar1.high_temp.utemp = state.sensor11;
        srvdata->sensor_log.items.mbar1.last_high_time = ltime;
    }
    curSensorValue[10].utemp = state.sensor11;
    if(srvdata->sensor_log.items.mbar2.high_temp.utemp < state.sensor12 ){
        srvdata->sensor_log.items.mbar2.high_temp.utemp = state.sensor12;
        srvdata->sensor_log.items.mbar2.last_high_time = ltime;
    }
    curSensorValue[11].utemp = state.sensor12;

    if(srvdata->sensor_log.items.pcb.high_temp.itemp < state.sensor13 ){
        srvdata->sensor_log.items.pcb.high_temp.itemp = state.sensor13;
        srvdata->sensor_log.items.pcb.last_high_time = ltime;
    }
    curSensorValue[12].itemp = state.sensor13;

    if(srvdata->sensor_log.items.adc.high_temp.itemp < state.sensor14 ){
        srvdata->sensor_log.items.adc.high_temp.itemp = state.sensor14;
        srvdata->sensor_log.items.adc.last_high_time = ltime;
    }
    curSensorValue[13].itemp = state.sensor14;




}

void OvenStatistics::processErrorItems(error_item *item, error_exe_type errtype, const QString &MsgDesc, const QString &MsgTitle, time_t ltime, error_sound_type sndtype){
    QWidget* pParent;
    uint32_t erridx = (uint32_t) (item - &(srvdata->err_log.values[0]));

    qDebug() << (uint32_t) (item - &(srvdata->err_log.values[0]))  <<   "ERROR Fired!";
   if(m_pLastErrItem == item ){
        srvdata->err_log.items.repeat_error.fired_cnt =item->fired_cnt;
        srvdata->err_log.items.repeat_error.first_fired = item->first_fired;
        srvdata->err_log.items.repeat_error.last_fried = item->last_fried;
   }
   m_pLastErrItem = item;
    qDebug() << "error type" << errtype;
    if(errtype >= error_type_onlychk){
        item->fired_cnt+=1;
        if(item->first_fired == 0) item->first_fired = ltime;
        item->last_fried = ltime;
    }

    emit onErrorFired(erridx);
    HACCP::error(MsgTitle);

    if(errtype>=error_type_chkclrstopcmd){
        qDebug() << "exec killchild";
        if(MainWindow::killChildCook()){
            pParent = MainWindow::getInstance();
        }
        else{
            pParent = QApplication::activeWindow();
        }
    }
    else{
        pParent = QApplication::activeWindow();
    }



    switch(errtype){
        case error_type_onlypop:
        case error_type_popclr:
        case error_type_popnonclr:
        case error_type_popclrstopcmd:
            {
                if(m_mapPopupList.find(erridx) == m_mapPopupList.end()){
                    ErrorPopupDlg *dlg = new ErrorPopupDlg(pParent,MsgDesc,MsgTitle , (errtype > error_type_clrsplit), erridx, sndtype);
                    connect(dlg,SIGNAL(closedErrorPopup(int)), this, SLOT(onErrorPopupClosed(int)));
                    m_mapPopupList.insert(erridx,dlg);
                    qApp->setActiveWindow(dlg);
                    dlg->showFullScreen();
                }
                break;
            }
        case error_type_engclr:
        case error_type_engnonclr:
        case error_type_onlyeng:
        case error_type_engclrstopcmd:
            {
                //EngineerMenuWindow *w = new EngineerMenuWindow(0);
                //w->showFullScreen();
                if(m_mapPopupList.find(erridx)==m_mapPopupList.end()){
                    ErrorPopupDlg *dlg = new ErrorPopupDlg(pParent,MsgDesc,MsgTitle, false,erridx,sndtype);
                    connect(dlg,SIGNAL(closedErrorPopup(int)),this,SLOT(onErrorPopupClosed(int)));
                    m_mapPopupList.insert(erridx,dlg);
                    dlg->showFullScreen();

                    ServicePassInputDlg *w = new ServicePassInputDlg(pParent, NORMAL_SERVICE_PASS_MODE, (errtype > error_type_clrsplit));
                    //w->exec();
                    connect(dlg, SIGNAL(destroyed(QObject*)), w, SLOT(showFullScreen()));
                 }
                break;
            }
        default:
            break;
    }

//    if(errtype > error_type_clrsplit){
//        //에러 클리어 명령 송신
////       if(errtype == error_type_engclr){
////            //확인 후 송신
////            bNeedErrorClear = true;
////        }
////        else{
////            //에러클리어 메시지 즉시 송신
//           qDebug() << "send error clr";
//            udp->set(TG_ERROR_CLEAR,0xCECE);
////        }
    //}


}

realtime_data OvenStatistics::getPartsRealtimeData(void){
    return realdata;
}

uint8_t OvenStatistics::getSensorTypeByIdx(uint16_t idx){
    if(idx > MAX_LOG_SENSOR)  return 0;
    return sensorTypeInfo[idx];
}

type_temp OvenStatistics::getCurSensorValueByIdx(uint16_t idx){
    return curSensorValue[idx];
}

void OvenStatistics::resetSensorHistory()
{
    srvdata->resetSensorlogData();
}

void OvenStatistics::onErrorPopupClosed(int erridx){
    qDebug() << "error idx" << erridx;
    if(m_mapPopupList.find(erridx)!= m_mapPopupList.end()){
        m_mapPopupList.remove(erridx);
    }
}