#include "serialport.h"
#include  <QtDebug>
#include <QSignalSpy>

SerialPort::SerialPort(QObject *parent) : QObject(parent)
{
    //m_serial = new QSerialPort;

    //connect(this,&SerialUi::sendConnect,mSerialPort,&SerialPort::receiveConnect);

    //  connect(this,&SerialPort::sendOk,this,&SerialPort::recieveData);
    // connect(m_serial,&QSerialPort::readyRead,this,&SerialPort::recieveData);

}

void SerialPort::receiveInit()
{
    m_serial = new QSerialPort;
    //connect(m_serial,&QSerialPort::readyRead,this,&SerialPort::recieveData);
}


SerialPort::~SerialPort()
{
    qDebug()<<"SerialPort destory";
    if(m_serial->isOpen())
    {
        m_serial->clear();
        m_serial->close();
    }
    m_serial->deleteLater();
}

bool SerialPort::serialConnect(QString port, QString baudrate, QString databits, QString parity, QString stopbits)
{
    m_serial->setPortName(port);
    if(!m_serial->open(QIODevice::ReadWrite))
    {
        qDebug()<<"Open" +port+" Error";
        return false;
    }

    switch (baudrate.toInt()) {
    case 4800:
        m_serial->setBaudRate(QSerialPort::Baud4800);
        break;
    case 9600:
        m_serial->setBaudRate(QSerialPort::Baud9600);
        break;
    case 115200:
        m_serial->setBaudRate(QSerialPort::Baud115200);
        break;
    default:
        qDebug("BaudRate Error");
        return false;
    }

    switch (databits.toInt()) {
    case 6:
        m_serial->setDataBits(QSerialPort::Data6);
        break;
    case 7:
        m_serial->setDataBits(QSerialPort::Data7);
        break;
    case 8:
        m_serial->setDataBits(QSerialPort::Data8);
        break;
    default:
        qDebug("DataBits Error");
        return 0;
    }
    //model: ["NONE","ODD","EVEN"]  0  1  2
    switch (parity.toInt()) {
    case 0:
        m_serial->setParity(QSerialPort::NoParity); //Check digit is set to 0
        qDebug("parity = NONE");
        break;
    case 2:
        m_serial->setParity(QSerialPort::EvenParity);
        qDebug("parity = EVEN");
        break;
    case 1:
        m_serial->setParity(QSerialPort::OddParity);
        qDebug("parity = ODD");
        break;
    default:
        qDebug("Parity Error");
        return 0;
    }

    switch (stopbits.toInt()) {
    case 1:
        m_serial->setStopBits(QSerialPort::OneStop); //Stop bit is set to 1
        break;
    case 2:
        m_serial->setStopBits(QSerialPort::TwoStop);
        break;
    case 3:
        m_serial->setStopBits(QSerialPort::OneAndHalfStop);
        break;
    default:
        printf("StopBits Error");
        return 0;
    }

    m_serial->setFlowControl(QSerialPort::NoFlowControl);//Set to no flow control

    return  true;
}

void SerialPort::closeConnect()
{
    qDebug()<<"SerialPort closeConnect";
    if(m_serial->isOpen())
    {
        m_serial->clear();
        m_serial->close();
    }
    // m_serial->deleteLater();
}


QByteArray SerialPort::serialRead()
{
    return mData;
}

bool SerialPort::getOpenStatus()
{
    return m_serial->isOpen();
}

/*
bool SerialPort::serialWrite(QString sendStr)
{

    m_serial->write(sendStr.toLatin1().data(),strlen(sendStr.toLatin1().data()));
    return 1;
}
*/


void SerialPort::receiveConnect(QString port, QString baudrate, QString databits, QString parity, QString stopbits)
{
    bool  status =  serialConnect( port,  baudrate,  databits,  parity,  stopbits);
    emit sendPortStatus(status);
}

void SerialPort::receiveOnlyWrite(QByteArray sendData)
{
    //延时用 没其他意义 把队列内容 依次发出
    QSignalSpy spy(m_serial, SIGNAL(readChannelFinished()));
    spy.wait(300);
    if(m_serial->isOpen() == false){
        return  ;
    }

    int retryCnt=0;
 retry:
     m_serial->readAll();
     m_serial->write(sendData);
     m_serial->waitForBytesWritten(1000);

     QSignalSpy spy1(m_serial, SIGNAL(readyRead()));
     bool ret = spy1.wait(300);
     if(ret == true){
            qDebug()<<"get response";
            QByteArray responseData = m_serial->readAll();
            qDebug()<<responseData;
     }
     else{
         qDebug()<<"get timeout";
         QByteArray responseData = m_serial->readAll();
         qDebug()<<responseData;
         retryCnt++;
         if(retryCnt > 2)
             return;
         goto retry;
     }

}
void SerialPort::receiveWrite(QByteArray sendData)
{

    mData.clear();

    if(m_serial->isOpen() == false){
        emit sendReceiveData();
        return  ;
    }


    QByteArray response = m_serial->readAll(); //clear buffer
    if(response.length() > 0){
        qDebug()<< "may be lost data";
    }

    m_serial->write(sendData);
    m_serial->waitForBytesWritten(200);

#if 1

    QSignalSpy spy(m_serial, SIGNAL(readyRead()));
    bool ret = spy.wait(300);
    if(ret == true){
        mData = m_serial->readAll();
        while (spy.wait(30) == true){
            mData += m_serial->readAll();
        }
    }
    else{
        //qDebug()<<"modbus time out";
        mData = m_serial->readAll();
        if(0 == mData.size()){
            qDebug()<<"modbus time out";
            emit sendTimeout();
        }

    }

    emit sendReceiveData();

#endif

}

void SerialPort::reveiveClose()
{
    closeConnect();
}


