#include "testwin.h"
#include "gutil/qgui.h"
#include "globalfunc.h"
#include "crc.h"
#include <QTextEdit>
#include <QPushButton>
#include <QMessageBox>
#include <QSplitter>
#include <QDateTime>
#include <QRadioButton>
#include <QTabWidget>
#include <QLineEdit>

TestWin::TestWin(QWidget *parent) : QWidget{parent, Qt::Window} {
    setAttribute(Qt::WA_DeleteOnClose);
    setWindowTitle(tr("协议调试"));
    resize(800, 800);

    auto mainVBox = new VBox(this);
    mainVBox->setContentsMargins(0,0,0,0);

    auto tab = new QTabWidget;
    mainVBox->addWidget(tab);

    TestPanel *pnl;
    tab->addTab(pnl = new TestPanel, "调试窗口1");
    fdReceives.append(pnl->fdReceive);
    tab->addTab(pnl = new TestPanel, "调试窗口2");
    fdReceives.append(pnl->fdReceive);
    tab->addTab(pnl = new TestPanel, "调试窗口3");
    fdReceives.append(pnl->fdReceive);

    auto splitter = new QSplitter;
    tab->addTab(splitter, "全局调试");

    auto wgt = new QWidget;
    splitter->addWidget(wgt);

    auto vv = new VBox(wgt);
    vv->setContentsMargins(0,0,0,0);
    vv->setSpacing(3);

    auto hh = new HBox(vv);

    hh->addLabel(tr("接收:"));
    auto fdIntro = new QLineEdit("55 55");
    connect(fdIntro, &QLineEdit::editingFinished, this, [=] {
        reThd->intro = QByteArray::fromHex(fdIntro->text().toLatin1());
    });
    hh->addWidget(fdIntro);

    hh->addStretch();

    auto fdStart = new QRadioButton(tr("开始"));
    fdStart->setChecked(true);
    connect(fdStart, &QPushButton::toggled, this, [](bool checked) {
        reThd->status = checked ? 1 : 2;
    });
    hh->addWidget(fdStart);
    hh->addSpacing(20);

    auto fdEnd = new QRadioButton(tr("暂停"));
    hh->addWidget(fdEnd);

    hh->addStretch();

    auto btnClear = new QPushButton(tr("清空"));
    btnClear->setMinimumWidth(120);
    hh->addWidget(btnClear);
    hh->addStretch();

    auto fdReceive = new QTextEdit;
    fdReceive->setFontFamily("Consolas");
    fdReceive->setReadOnly(true);
    fdReceive->document()->setMaximumBlockCount(200);
    vv->addWidget(fdReceive);
    fdReceives.append(fdReceive);

    connect(btnClear, &QPushButton::clicked, fdReceive, &QTextEdit::clear);

    splitter->addWidget(wgt = new QWidget);
    vv = new VBox(wgt);
    vv->setContentsMargins(0,0,0,0);
    vv->setSpacing(3);

    hh = new HBox(vv);
    hh->addStretch();

    auto btnSend = new QPushButton(tr("发送"));
    btnSend->setMinimumWidth(120);
    hh->addWidget(btnSend);

    hh->addStretch();

    btnClear = new QPushButton(tr("清空"));
    btnClear->setMinimumWidth(120);
    hh->addWidget(btnClear);
    hh->addStretch();

    auto fdSend = new QTextEdit;
    fdSend->setFontFamily("Consolas");
    vv->addWidget(fdSend);

    splitter->setSizes({3000, 2000});

    connect(btnSend, &QPushButton::clicked, this, [this, fdSend] {
        auto text = fdSend->toPlainText();
        auto len = text.size();
        QByteArray bytes;
        for(int i=0; i<len; i++) {
            auto ch = text[i].toLatin1();
            if((ch>='0' && ch<='9') || (ch>='A' && ch<='F') || (ch>='a' && ch<='f')) bytes.append(ch);
        }
        if(bytes.size() % 2) bytes.append('0');
        bytes = QByteArray::fromHex(bytes);
        if(pcap_sendpacket(pcapSend, (u_char*)bytes.data(), bytes.size())) {
            QMessageBox::critical(this, "Error", QString(tr("发送失败: "))+pcap_geterr(pcapSend));
            return;
        }
    });
    connect(btnClear, &QPushButton::clicked, fdSend, &QTextEdit::clear);


    connect(reThd, &PcapReThread::onMsg, fdReceive, [=](const QString &msg) {
        for(auto fdReceive : fdReceives) if(fdReceive->isVisible()) fdReceive->append(msg);
    });
    reThd->status = 1;
}
TestWin::~TestWin() {
    reThd->status = 0;
}



TestPanel::TestPanel(QWidget *parent) : QWidget{parent} {
    auto vBox = new VBox(this);
    vBox->setContentsMargins(0,0,0,0);
    vBox->setSpacing(3);

    auto hBox = new HBox(vBox);

    auto fdVer = new QLineEdit("01");
    fdVer->setMaximumWidth(30);
    hBox->addWidget(fdVer);

    auto fdSrv = new QLineEdit("AD");
    fdSrv->setMaximumWidth(30);
    hBox->addWidget(fdSrv);

    auto fdAddr = new QLineEdit("FFFFFFFF 0000ABCD");
    fdAddr->setMaximumWidth(180);
    hBox->addWidget(fdAddr);

    auto fdPtr = new QComboBox;
    fdPtr->setEditable(true);
    fdPtr->addItem("B0000000 (系统配置)");
    fdPtr->addItem("B1000000 (模组寄存器)");
    fdPtr->addItem("B2000000 (保留)");
    fdPtr->addItem("B3000000 (箱体寄存器)");
    fdPtr->addItem("B4000000 (灰度寄存器)");
    fdPtr->addItem("B5100000 (驱动ic寄存器 DCLK)");
    fdPtr->addItem("B5200000 (驱动ic寄存器 LAT)");
    fdPtr->addItem("B5300000 (驱动ic寄存器 R)");
    fdPtr->addItem("B5400000 (驱动ic寄存器 G)");
    fdPtr->addItem("B5500000 (驱动ic寄存器 B)");
    fdPtr->addItem("B6000000 (Flash存储地址)");
    fdPtr->addItem("D0000000 (SDRAM内存地址)");
    fdPtr->addItem("A0000000 (其他)");
    hBox->addWidget(fdPtr);
    hBox->addStretch();

    auto btnSend = new QPushButton(tr("发送"));
    hBox->addWidget(btnSend);

    auto btnClear = new QPushButton(tr("清空"));
    btnClear->setMaximumWidth(60);
    hBox->addWidget(btnClear);

    auto btnClearRece = new QPushButton(tr("清空接收"));
    hBox->addWidget(btnClearRece);

    auto splitter = new QSplitter(Qt::Vertical);
    vBox->addWidget(splitter);

    auto fdBody = new QTextEdit;
    fdBody->setPlainText("00 00 00 00");
    fdBody->setFontFamily("Consolas");
    splitter->addWidget(fdBody);
    connect(btnSend, &QPushButton::clicked, this, [=] {
        auto body = QByteArray::fromHex(fdBody->toPlainText().toLatin1());
        if(body.isEmpty()) {
            QMessageBox::critical(this, "Error", "发送内容为空");
            return;
        }
        auto bLen = body.size();
        QByteArray msg;
        msg.reserve(headMap.end+bLen+16);
        msg.append("\x55\x55");
        msg.append(QByteArray::fromHex(fdVer->text().toLatin1())[0]);
        byte srv = QByteArray::fromHex(fdSrv->text().toLatin1())[0];
        msg.append(srv);
        auto bodyLen = bLen + 6;
        msg.append(bodyLen>>8).append(bodyLen);
        msg.append(QByteArray::fromHex(fdAddr->text().toLatin1()));
        auto ptrRaw = fdPtr->currentText();
        auto idx = ptrRaw.indexOf('(');
        if(idx > -1) ptrRaw = ptrRaw.left(idx);
        auto ptr = QByteArray::fromHex(ptrRaw.toLatin1());
        msg.append(ptr);
        msg.append(6, 0);
        auto check = (quint32_be*)(msg.data() + msg.size() - 4);
        *check = crc32_calc((byte*)msg.data()+2, msg.size()-6);
        msg.append(ptr);
        msg[msg.size()-4] = srv;
        msg.append(bLen>>8).append(bLen);
        msg.append(body);
        msg.append(4, 0);
        check = (quint32_be*)(msg.data() + msg.size() - 4);
        *check = crc32_calc((byte*)msg.data()+headMap.body, msg.size()-headMap.body-4);

        if(pcap_sendpacket(pcapSend, (u_char*)msg.data(), msg.size())) {
            QMessageBox::critical(this, "Error", QString(tr("发送失败: "))+pcap_geterr(pcapSend));
            return;
        }
    });
    connect(btnClear, &QPushButton::clicked, fdBody, &QTextEdit::clear);

    fdReceive = new QTextEdit;
    fdReceive->setFontFamily("Consolas");
    fdReceive->setReadOnly(true);
    fdReceive->document()->setMaximumBlockCount(200);
    splitter->addWidget(fdReceive);
    splitter->setSizes({1000, 3000});

    connect(btnClearRece, &QPushButton::clicked, fdReceive, &QTextEdit::clear);
}