#include "serialworker.h"
#include "thermalwidget.h"
#include <QApplication>
#include <QtWidgets/QMessageBox>
#include <cstring>

QVector<float> g_qvecf_time;
QVector<float> g_qvecf_cur_time;
QVector<double> g_qvecd_temper;
QVector<double> g_qvecd_dsc;
QVector<double> g_qvecd_riserate;
QVector<float> g_qvecf_cooltemper;
int g_send_flag;

QVector<double> g_real_temper;
QVector<double> g_real_dsc;

extern QuadraticFitResult g_result1;

SerialWorker::SerialWorker(QObject *parent) : QObject(parent)
{
    m_recBuf.clear();
    port = new QSerialPort(this);
    m_bOpen = false;
    g_send_flag = 0;
    m_write_flag = 0;
    m_read_flag = 0;
    ///init_port();
    connect(port, SIGNAL(readyRead()), this, SLOT(handle_data()), Qt::QueuedConnection); //Qt::DirectConnection
}

SerialWorker::~SerialWorker()
{
    port->close();
    port->deleteLater();
}

void SerialWorker::init_port(QString comName)
{
    m_comName = comName;
    port->setPortName(comName);                         //串口名
    port->setBaudRate(115200);                         //波特率
    port->setDataBits(QSerialPort::Data8);             //数据位
    port->setStopBits(QSerialPort::OneStop);           //停止位
    port->setParity(QSerialPort::NoParity);            //奇偶校验
    port->setFlowControl(QSerialPort::NoFlowControl);  //流控制

    qDebug() << "Port init ok "<<comName<<Qt::endl;
}


void SerialWorker::open_serial_port()
{
    // port->setPortName(m_comName);                         //串口名
    // port->setBaudRate(115200);                         //波特率
    // port->setDataBits(QSerialPort::Data8);             //数据位
    // port->setStopBits(QSerialPort::OneStop);           //停止位
    // port->setParity(QSerialPort::NoParity);            //奇偶校验
    // port->setFlowControl(QSerialPort::NoFlowControl);  //流控制

    if (port->open(QIODevice::ReadWrite))
    {
        qDebug() << "Port have been opened";
        emit show_success_msgbox();
        m_bOpen = true;
        port->setDataTerminalReady(true);
    }
    else
    {
        qDebug() << "open COM failed";
        emit show_failed_msgbox();
    }
    qDebug() << "init_port thread is:" << QThread::currentThreadId();


}


void SerialWorker::close_serial_port()
{
    if(m_bOpen==true)
    {
        port->close();
        emit close_serial_port_success();
        m_bOpen = false;
    }
}

void SerialWorker::change_send_flag()
{
    ///m_send_flag = 1;
}

void SerialWorker::change_test_start_flag_slot()
{
    m_test_start_flag = 1;
}

void SerialWorker::handle_data()
{
    int valid_data=0;
    int valid_len=0;
    uint16_t crcrec = 0;
    unsigned char* objBuf= NULL;
    unsigned char* validBuf = NULL;
    unsigned char* crcdataBuf=NULL;

    unsigned char* dealBuf= NULL;
    unsigned char* sendBuf= NULL;

    QByteArray recBuf= port->readAll();
    ///m_recBuf.append(recBuf);
    emit receive_data(recBuf);

    int lenbuf = recBuf.size();             //总数据长度
    objBuf = (unsigned char*)std::malloc(lenbuf);
    std::memcpy(objBuf, (unsigned char*)recBuf.data(), lenbuf);

    for(int i=0; i<(lenbuf-1); i++)
    {
        if((objBuf[i]==0xA5)&&(objBuf[i+1]==0x5A))
        {
            valid_data = i;
            ///qDebug() << "in for i = "<< i <<Qt::endl;
            ///m_framecount++;
            break;
        }
    }

    valid_len = lenbuf-valid_data;          //有效数据长度，去掉前面的无效数据
    validBuf = (unsigned char*)std::malloc(valid_len);
    std::memcpy(validBuf, objBuf, valid_len);

    if((validBuf[0]==0xA5)&&(validBuf[1]==0x5A))    //开始解析
    {
        m_whole_len = validBuf[2];          //全数据长度
        m_data_len = m_whole_len - 3;       //载荷数据长度

        if(validBuf[3]==0x82)         //写指令
            m_write_flag = 1;
        if (validBuf[3]==0x83)   //读指令
            m_read_flag = 1;

        crcdataBuf = (unsigned char*)std::malloc((m_data_len+1));          //CRC校验
        std::memcpy(crcdataBuf, validBuf+3, (m_data_len+1));
        ///int len = sizeof(crcdataBuf);               //错误
        int len = m_data_len+1;
        uint16_t crcret = CRC16_MODBUS(crcdataBuf, len);
        crcrec = (validBuf[m_whole_len+2]<<8)|(validBuf[m_whole_len+1]);  //获得的CRC值，高位在后，低位在前

        if(crcret==crcrec)
        {
            m_crc_flag = 1;
            qDebug("crc check right!");
        }else
        {
            m_crc_flag = 0;
            qDebug("crc check wrong!");
        }
        std::free(crcdataBuf);
        crcdataBuf = NULL;
        //0,运行状态
        //1,当前阶段
        //26,硬件错误
        //27,当前气氛
        if(1==m_crc_flag)
        {
            if((1==m_read_flag)&&(0==g_send_flag))
            {
                if(validBuf[4] == char(0x00))
                {
                    qDebug("start parse data!");
                    m_run_state_continue = validBuf[6];           //0运行状态

                    data_t.x[0] = validBuf[8];                    //2累计运行时间
                    data_t.x[1] = validBuf[9];
                    data_t.x[2] = validBuf[10];
                    data_t.x[3] = validBuf[11];
                    ///g_qvecf_time.append(data_t.f);

                    data_curaccum_t.x[0] = validBuf[12];          //6当前阶段恒温时间
                    data_curaccum_t.x[1] = validBuf[13];
                    data_curaccum_t.x[2] = validBuf[14];
                    data_curaccum_t.x[3] = validBuf[15];
                    // g_qvecf_cur_time.append(data_curaccum_t.f);

                    data_temper.x[0] = validBuf[16];              //A样品温度
                    data_temper.x[1] = validBuf[17];
                    data_temper.x[2] = validBuf[18];
                    data_temper.x[3] = validBuf[19];
                    data_temper.x[4] = validBuf[20];
                    data_temper.x[5] = validBuf[21];
                    data_temper.x[6] = validBuf[22];
                    data_temper.x[7] = validBuf[23];                   
                    // g_qvecd_temper.append(data_temper.d);
                    // mutex.lock();
                    // g_real_temper.append(data_temper.d);
                    // mutex.unlock();


                    data_dsc.x[0] = validBuf[24];                 //12热流
                    data_dsc.x[1] = validBuf[25];
                    data_dsc.x[2] = validBuf[26];
                    data_dsc.x[3] = validBuf[27];
                    data_dsc.x[4] = validBuf[28];
                    data_dsc.x[5] = validBuf[29];
                    data_dsc.x[6] = validBuf[30];
                    data_dsc.x[7] = validBuf[31];
                    // g_qvecd_dsc.append(data_dsc.d);
                    // mutex.lock();
                    // g_real_dsc.append(data_dsc.d);
                    // mutex.unlock();

                    data_riserate.x[0] = validBuf[32];           //1A升温速率
                    data_riserate.x[1] = validBuf[33];
                    data_riserate.x[2] = validBuf[34];
                    data_riserate.x[3] = validBuf[35];
                    data_riserate.x[4] = validBuf[36];
                    data_riserate.x[5] = validBuf[37];
                    data_riserate.x[6] = validBuf[38];
                    data_riserate.x[7] = validBuf[39];
                    // g_qvecd_riserate.append(data_riserate.d);

                    data_cooltemper.x[0] = validBuf[40];         //22冷端温度
                    data_cooltemper.x[1] = validBuf[41];
                    data_cooltemper.x[2] = validBuf[42];
                    data_cooltemper.x[3] = validBuf[43];
                    // g_qvecf_cooltemper.append(data_cooltemper.f);

                    ///m_qmap_fd.insert(data_t.f, data_dsc.d);
                    if(m_run_state_continue==char(0x01))
                    {
                        mutex.lock();
                        g_qvecf_time.append(data_t.f);
                        g_qvecf_cur_time.append(data_curaccum_t.f);
                        g_qvecd_temper.append(data_temper.d);
                        g_qvecd_dsc.append(data_dsc.d);
                        g_qvecd_riserate.append(data_riserate.d);
                        g_qvecf_cooltemper.append(data_cooltemper.f);

                        g_real_temper.append(data_temper.d);
                        g_real_dsc.append(data_dsc.d);
                        mutex.unlock();
                        qDebug()<<"m_run_state_continue check ok"<<Qt::endl;
                    }

                    if(1 == m_test_start_flag)
                    {
                        mutex.lock();
                        m_test_start_flag = 0;
                        g_qvecf_time.clear();
                        g_qvecf_cur_time.clear();
                        g_qvecd_temper.clear();
                        g_qvecd_dsc.clear();
                        g_qvecd_riserate.clear();
                        g_qvecf_cooltemper.clear();

                        g_real_temper.clear();
                        g_real_dsc.clear();
                        mutex.unlock();
                    }

                    qDebug()<<"run_state_continue="<<(int)m_run_state_continue<<"time="<<data_t.f<<"current_acc_time="<<data_curaccum_t.f<< "temper=" << data_temper.d <<"DSC="
                             << data_dsc.d<< "riserate="<<data_riserate.d <<"cooltemper="<< data_cooltemper.f <<Qt::endl;
                }
            }
            if((1==m_read_flag)&&(1==g_send_flag)&&(0==m_write_flag))
            {
                    g_send_flag = 0;
                    m_read_flag = 0;
                    int readback_len = 0;

                    int lebuf = m_dealSendBytes.size();             //总数据长度
                    sendBuf = (unsigned char*)std::malloc(lebuf);
                    std::memcpy(sendBuf, (unsigned char*)m_dealSendBytes.data(), lebuf);

                    if(validBuf[4] == sendBuf[4])
                    {
                        readback_len = validBuf[2]-5;
                        if(validBuf[4] == 0x00)
                        {
                            m_run_state = validBuf[6];
                            emit show_run_state_box_state(m_run_state);
                            qDebug()<<"read addr 0x00 success!"<<Qt::endl;
                        }
                        if(validBuf[4] == 0x2C)
                        {
                            unsigned char mode_state = validBuf[6];
                            emit show_checkbox_state(mode_state);
                            qDebug()<<"read addr 0x2C success!"<<Qt::endl;
                        }
                        if(validBuf[4] == 0x50)
                        {
                            m_stage1_state = validBuf[6];
                            stage1_until.x[0] = validBuf[7];
                            stage1_until.x[1] = validBuf[8];
                            stage1_until.x[2] = validBuf[9];
                            stage1_until.x[3] = validBuf[10];
                            stage1_riserate.x[0] = validBuf[11];
                            stage1_riserate.x[1] = validBuf[12];
                            stage1_riserate.x[2] = validBuf[13];
                            stage1_riserate.x[3] = validBuf[14];
                            m_stage1_time = (validBuf[15]<<8)|validBuf[16];
                            m_stage1_airchoose = validBuf[17];

                            emit set_stage1_edit_box(m_stage1_state, stage1_until.f, stage1_riserate.f, m_stage1_time, m_stage1_airchoose);
                            qDebug()<<"read addr 0x50 success!"<<"m_stage1_state"<<m_stage1_state<<"stage1_until"
                                     <<stage1_until.f<<"stage1_riserate"<<stage1_riserate.f<<"m_stage1_time"<<m_stage1_time<<"m_stage1_airchoose"<<m_stage1_airchoose<<Qt::endl;
                        }
                        if(validBuf[4] == 0x5c)
                        {
                            m_stage2_state = validBuf[6];
                            stage2_until.x[0] = validBuf[7];
                            stage2_until.x[1] = validBuf[8];
                            stage2_until.x[2] = validBuf[9];
                            stage2_until.x[3] = validBuf[10];
                            stage2_riserate.x[0] = validBuf[11];
                            stage2_riserate.x[1] = validBuf[12];
                            stage2_riserate.x[2] = validBuf[13];
                            stage2_riserate.x[3] = validBuf[14];
                            m_stage2_time = (validBuf[15]<<8)|validBuf[16];
                            m_stage2_airchoose = validBuf[17];

                            emit set_stage2_edit_box(m_stage2_state, stage2_until.f, stage2_riserate.f, m_stage2_time, m_stage2_airchoose);
                            qDebug()<<"read addr 0x5C success!"<<"m_stage2_state"<<m_stage2_state<<"stage2_until"
                                     <<stage2_until.f<<"stage2_riserate"<<stage2_riserate.f<<"m_stage2_time"<<m_stage2_time<<"m_stage2_airchoose"<<m_stage2_airchoose<<Qt::endl;

                        }
                        if(validBuf[4] == 0x68)
                        {
                            m_stage3_state = validBuf[6];
                            stage3_until.x[0] = validBuf[7];
                            stage3_until.x[1] = validBuf[8];
                            stage3_until.x[2] = validBuf[9];
                            stage3_until.x[3] = validBuf[10];
                            stage3_riserate.x[0] = validBuf[11];
                            stage3_riserate.x[1] = validBuf[12];
                            stage3_riserate.x[2] = validBuf[13];
                            stage3_riserate.x[3] = validBuf[14];
                            m_stage3_time = (validBuf[15]<<8)|validBuf[16];
                            m_stage3_airchoose = validBuf[17];

                            emit set_stage3_edit_box(m_stage3_state, stage3_until.f, stage3_riserate.f, m_stage3_time, m_stage3_airchoose);
                            qDebug()<<"read addr 0x68 success!"<<"m_stage3_state"<<m_stage3_state<<"stage3_until"
                                     <<stage3_until.f<<"stage3_riserate"<<stage3_riserate.f<<"m_stage3_time"<<m_stage3_time<<"m_stage3_airchoose"<<m_stage3_airchoose<<Qt::endl;

                        }
                        if(validBuf[4] == 0x74)
                        {
                            m_stage4_state = validBuf[6];
                            stage4_until.x[0] = validBuf[7];
                            stage4_until.x[1] = validBuf[8];
                            stage4_until.x[2] = validBuf[9];
                            stage4_until.x[3] = validBuf[10];
                            stage4_riserate.x[0] = validBuf[11];
                            stage4_riserate.x[1] = validBuf[12];
                            stage4_riserate.x[2] = validBuf[13];
                            stage4_riserate.x[3] = validBuf[14];
                            m_stage4_time = (validBuf[15]<<8)|validBuf[16];
                            m_stage4_airchoose = validBuf[17];

                            emit set_stage4_edit_box(m_stage4_state, stage4_until.f, stage4_riserate.f, m_stage4_time, m_stage4_airchoose);
                            qDebug()<<"read addr 0x74 success!"<<"m_stage4_state"<<m_stage4_state<<"stage4_until"
                                     <<stage4_until.f<<"stage4_riserate"<<stage4_riserate.f<<"m_stage4_time"<<m_stage4_time<<"m_stage4_airchoose"<<m_stage4_airchoose<<Qt::endl;

                        }
                        if(validBuf[4] == 0x80)
                        {
                            m_stage5_state = validBuf[6];
                            stage5_until.x[0] = validBuf[7];
                            stage5_until.x[1] = validBuf[8];
                            stage5_until.x[2] = validBuf[9];
                            stage5_until.x[3] = validBuf[10];
                            stage5_riserate.x[0] = validBuf[11];
                            stage5_riserate.x[1] = validBuf[12];
                            stage5_riserate.x[2] = validBuf[13];
                            stage5_riserate.x[3] = validBuf[14];
                            m_stage5_time = (validBuf[15]<<8)|validBuf[16];
                            m_stage5_airchoose = validBuf[17];

                            emit set_stage5_edit_box(m_stage5_state, stage5_until.f, stage5_riserate.f, m_stage5_time, m_stage5_airchoose);
                            qDebug()<<"read addr 0x80 success!"<<"m_stage5_state"<<m_stage5_state<<"stage5_until"
                                     <<stage5_until.f<<"stage5_riserate"<<stage5_riserate.f<<"m_stage5_time"<<m_stage5_time<<"m_stage5_airchoose"<<m_stage5_airchoose<<Qt::endl;

                        }

                        if(validBuf[4] == 0x8C)
                        {
                            m_stage6_state = validBuf[6];
                            stage6_until.x[0] = validBuf[7];
                            stage6_until.x[1] = validBuf[8];
                            stage6_until.x[2] = validBuf[9];
                            stage6_until.x[3] = validBuf[10];
                            stage6_riserate.x[0] = validBuf[11];
                            stage6_riserate.x[1] = validBuf[12];
                            stage6_riserate.x[2] = validBuf[13];
                            stage6_riserate.x[3] = validBuf[14];
                            m_stage6_time = (validBuf[15]<<8)|validBuf[16];
                            m_stage6_airchoose = validBuf[17];

                            emit set_stage6_edit_box(m_stage6_state, stage6_until.f, stage6_riserate.f, m_stage6_time, m_stage6_airchoose);
                            qDebug()<<"read addr 0x8C success!"<<"m_stage6_state"<<m_stage6_state<<"stage6_until"
                                     <<stage6_until.f<<"stage6_riserate"<<stage6_riserate.f<<"m_stage6_time"<<m_stage6_time<<"m_stage6_airchoose"<<m_stage6_airchoose<<Qt::endl;

                        }

                        if(validBuf[4] == 0xE5)
                        {
                            fit_coff_a.x[0] = validBuf[6];
                            fit_coff_a.x[1] = validBuf[7];
                            fit_coff_a.x[2] = validBuf[8];
                            fit_coff_a.x[3] = validBuf[9];
                            fit_coff_b.x[0] = validBuf[10];
                            fit_coff_b.x[1] = validBuf[11];
                            fit_coff_b.x[2] = validBuf[12];
                            fit_coff_b.x[3] = validBuf[13];
                            fit_coff_c.x[0] = validBuf[14];
                            fit_coff_c.x[1] = validBuf[15];
                            fit_coff_c.x[2] = validBuf[16];
                            fit_coff_c.x[3] = validBuf[17];

                            ///emit set_stage6_edit_box(fit_coff_a.f, fit_coff_b.f, fit_coff_c.f);
                            g_result1.a = fit_coff_a.f;
                            g_result1.b = fit_coff_b.f;
                            g_result1.c = fit_coff_c.f;
                            qDebug()<<"read addr 0xE5 success!"<<"fit_coff_a"<<fit_coff_a.f<<"fit_coff_b"<<fit_coff_b.f<<"fit_coff_c"<<fit_coff_c.f<<Qt::endl;

                        }

                        qDebug()<<"readback_len="<<readback_len<<Qt::endl;
                        qDebug()<<"read target success!"<<Qt::endl;

                    }else
                    {
                        qDebug()<<"read target failed!"<<Qt::endl;
                    }

                    std::free(sendBuf);
                    sendBuf = NULL;
            }
            if(m_write_flag == 1)
            {
                m_write_flag = 0;
                int lbuf = m_dealSendBytes.size();             //总数据长度
                dealBuf = (unsigned char*)std::malloc(lbuf);
                std::memcpy(dealBuf, (unsigned char*)m_dealSendBytes.data(), lbuf);

                if(validBuf[4] == dealBuf[4])
                {
                    qDebug()<<"write target success!"<<Qt::endl;
                    emit write_target_success();

                }else
                {
                    qDebug()<<"write target failed!"<<Qt::endl;
                    ///emit write_target_failed();
                }

                std::free(dealBuf);
                dealBuf = NULL;

            }
        }
    std::free(objBuf);
    std::free(validBuf);

    objBuf = NULL;
    validBuf = NULL;
  }
}


uint16_t SerialWorker::CRC16_MODBUS(unsigned char *data, unsigned int datalen)
{
    unsigned short wCRCin = 0xFFFF;
    unsigned short wCPoly = 0x8005;

    InvertUint16(&wCPoly,&wCPoly);
    while (datalen--)
    {
        wCRCin ^= *(data++);
        for(int i = 0;i < 8;i++)
        {
            if(wCRCin & 0x01)
                wCRCin = (wCRCin >> 1) ^ wCPoly;
            else
                wCRCin = wCRCin >> 1;
        }
    }
    return (wCRCin);
}


void SerialWorker::InvertUint16(unsigned short *dBuf,unsigned short *srcBuf)
{
    int i;
    unsigned short tmp[4]={0};

    for(i=0;i< 16;i++)
    {
        if(srcBuf[0]& (1 << i))
            tmp[0]|=1<<(15 - i);
    }
    dBuf[0] = tmp[0];
}

//CRC16计算函数
uint16_t SerialWorker::ModbusCRC16(QByteArray senddata)
{
    int len=senddata.size();
    uint16_t wcrc=0XFFFF;//预置16位crc寄存器，初值全部为1
    uint8_t temp;//定义中间变量
    int i=0,j=0;//定义计数
    for(i=0;i<len;i++)//循环计算每个数据
    {
        temp=senddata.at(i);
        wcrc^=temp;
        for(j=0;j<8;j++){
            //判断右移出的是不是1，如果是1则与多项式进行异或。
            if(wcrc&0X0001){
                wcrc>>=1;//先将数据右移一位
                wcrc^=0XA001;//与上面的多项式进行异或
            }
            else//如果不是1，则直接移出
                wcrc>>=1;//直接移出
        }
    }
    temp=wcrc;//crc的值
    return wcrc;
}

void SerialWorker::write_data(QByteArray SendBytes)
{
    // 串口未打开
    if ( !m_bOpen )
    {
        qDebug() << "串口未打开，发送失败！" << Qt::endl;
        emit serial_port_not_open();
        return;
    }
    if ( !SendBytes.isEmpty() )
    {
        port->write(SendBytes);
        qDebug() << "写端口完成！" << Qt::endl;
    }

    m_dealSendBytes = SendBytes;

    qDebug() << "write_id is:" << QThread::currentThreadId();

}
