#include "mainwin.h"
#include "pcaprethread.h"
#include "fast.h"
#include "expertwin.h"
#include "brightwin.h"
#include "pcapwin.h"
#include "videowin.h"
#include <QLabel>
#include <QPushButton>
#include <QToolButton>
#include <QComboBox>
#include <QMouseEvent>
#include <QPainter>
#include <QPainterPath>
#include <QTimer>
#include <QMessageBox>
#include <QDebug>
#include "globalfunc.h"
#include "basewin.h"
#include <QSettings>
#include <QDir>
#include <QApplication>

class ImgBtn : public QToolButton {
public:
    ImgBtn() {
        setStyleSheet("QToolButton{border: none; padding-top: 4px;}");
    }
    bool isEnter{false};
protected:
    void resizeEvent(QResizeEvent *event) override {
        QToolButton::resizeEvent(event);
        if(isEnter) setIconSize(QSize(width(), width()));
        else setIconSize(QSize(width()-8, width()-8));
    }
    void enterEvent(QEvent *event) override {
        QToolButton::enterEvent(event);
        setStyleSheet("QToolButton{border: none;}");
        setIconSize(QSize(width(), width()));
    }
    void leaveEvent(QEvent *event) override {
        QToolButton::leaveEvent(event);
        setIconSize(QSize(width()-8, width()-8));
        setStyleSheet("QToolButton{border: none; padding-top: 4px;}");
    }
};

inline QLabel *newImgLabel(QPixmap pixmap){
    QLabel *lb = new QLabel();
    lb->setPixmap(pixmap);
    return lb;
}
inline QLabel *newSubLabel(QString txt){
    QLabel *lb = new QLabel(txt);
    lb->setAlignment(Qt::AlignCenter);
    return lb;
}
ImgBtn *addImg(QHBoxLayout *parent, const QIcon &icon, const QString &text) {
    auto imgBtn = new ImgBtn();
    imgBtn->setIcon(icon);
    imgBtn->setText(text);
    imgBtn->setFixedSize(76, 100);
    imgBtn->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
    parent->addWidget(imgBtn);
    return imgBtn;
}

MainWin::MainWin() {
    setWindowTitle("LedSet Express");
    resize(860, 540);

    auto vBox = new QVBoxLayout(center);
    vBox->setContentsMargins(0,0,0,0);

    vBox->addLayout(addBtns(new QHBoxLayout()));

    QHBoxLayout *imgsBar = new QHBoxLayout();
    auto btnImg = addImg(imgsBar, QPixmap(":/imgs/fast.png").scaledToWidth(128, Qt::SmoothTransformation), "快速调屏");
    connect(btnImg, &ImgBtn::clicked, this, [=](){
        (new Fast(this))->show();
    });
    btnImg = addImg(imgsBar, QPixmap(":/imgs/expert.png").scaledToWidth(128, Qt::SmoothTransformation), tr("专家调屏"));
    connect(btnImg, &ImgBtn::clicked, this, [=](){
        (new ExpertWin(this))->show();
    });
    btnImg = addImg(imgsBar, QPixmap(":/imgs/bright.png").scaledToWidth(128, Qt::SmoothTransformation), tr("亮度控制"));
    connect(btnImg, &ImgBtn::clicked, this, [=](){
        (new BrightWin(this))->show();
    });
    btnImg = addImg(imgsBar, QPixmap(":/imgs/correct.png").scaledToWidth(128, Qt::SmoothTransformation), tr("相机矫正"));
    connect(btnImg, &ImgBtn::clicked, this, [=](){

    });
    btnImg = addImg(imgsBar, QPixmap(":/imgs/monitor.png").scaledToWidth(128, Qt::SmoothTransformation), tr("屏体监控"));
    connect(btnImg, &ImgBtn::clicked, this, [=](){

    });
    btnImg = addImg(imgsBar, QPixmap(":/imgs/multi.png").scaledToWidth(128, Qt::SmoothTransformation), tr("多功能卡"));
    connect(btnImg, &ImgBtn::clicked, this, [=](){
        //win->move(win->x()-1, win->y());
    });
    btnImg = addImg(imgsBar, QPixmap(":/imgs/video.png").scaledToWidth(128, Qt::SmoothTransformation), tr("协议调试"));
    connect(btnImg, &ImgBtn::clicked, this, [=](){
        auto ins = PcapWin::newIns(net_name, this);
        if(ins) ins->show();
    });
    btnImg = addImg(imgsBar, QPixmap(":/imgs/idea.png").scaledToWidth(128, Qt::SmoothTransformation), tr("模拟同步"));
    connect(btnImg, &ImgBtn::clicked, this, [=](){
        auto ins = VideoWin::newIns(net_name, this);
        if(ins) ins->show();
    });
    vBox->addLayout(imgsBar);
    vBox->addSpacing(9);
    vBox->addWidget(new QLabel("  硬件信息"));

    table = new Table{
        {"type", "发送卡型号"},
        {"name", "名称"},
        {"link", "连接方式"},
        {"vcs", "接收卡数量"},
        {"Pinfo", "网口统计P1~Pn"},
        {"Oinfo", "其他信息", QHeaderView::Stretch},
    };
    vBox->addWidget(table);

    auto hstatus = new QHBoxLayout;
    hstatus->addWidget(new QLabel(tr("版本:221114")));
    hstatus->addStretch();

    auto btnNetSelect = new QPushButton("通讯选择");
    btnNetSelect->setMinimumWidth(80);
    connect(btnNetSelect, &QPushButton::clicked, this, [this] {
        auto name = getNetDev(this, net_name, false);
        if(name.isEmpty()) return;
        //PCAP_OPENFLAG_DATATX_UDP：2，它定义了数据传输（假如是远程抓包）是否用UDP协议来处理。
        //PCAP_OPENFLAG_NOCAPTURE_RPCAP：4，它定义了远程探测器是否捕获它自己产生的数据包。
        char errbuf[PCAP_ERRBUF_SIZE]{'\0'};
        auto pcapR = pcap_open_live(name.data(), 65536, PCAP_OPENFLAG_PROMISCUOUS|4|8|16, 50, errbuf);
        if(pcapR == 0) {
            QMessageBox::critical(this, "Error", QString(tr("打开网卡失败"))+errbuf);
            return;
        }
        auto pcapS = pcap_open_live(name.data(), 65536, 0, 50, errbuf);
        if(pcapS == 0) {
            QMessageBox::critical(this, "Error", QString(tr("打开网卡失败"))+errbuf);
            return;
        }
        if(reThd) reThd->status = 2;
        if(pcapSend) pcap_close(pcapSend);
        pcapSend = pcapS;
        reThd = new PcapReThread(pcapR);
        reThd->start();
        QSettings config(QApplication::applicationDirPath()+"/ledset.config", QSettings::IniFormat);//QDir::currentPath()为exe位置
        config.beginGroup("GLOBAL");
        config.setValue("net_name", net_name = name);
        config.endGroup();
    });
    hstatus->addWidget(btnNetSelect);

    auto btnRefresh = new QPushButton(tr("刷新"));
    btnRefresh->setMinimumWidth(80);
    connect(btnRefresh, &QPushButton::clicked, this, &MainWin::getCard);
    hstatus->addWidget(btnRefresh);

    vBox->addLayout(hstatus);

    QSettings config(QApplication::applicationDirPath()+"/ledset.config", QSettings::IniFormat);
    config.beginGroup("GLOBAL");//保存数据
    auto name = config.value("net_name").toByteArray();
    name = getNetDev(this, name, true);
    if(! name.isEmpty()) {
        char errbuf[PCAP_ERRBUF_SIZE]{'\0'};
        auto pcapRe = pcap_open_live(name.data(), 65536, PCAP_OPENFLAG_PROMISCUOUS|4|8|16, 50, errbuf);
        if(pcapRe == 0) QMessageBox::critical(this, "Error", QString(tr("打开网卡失败"))+errbuf);
        else {
            pcapSend = pcap_open_live(name.data(), 65536, 0, 50, errbuf);
            if(pcapSend == 0) QMessageBox::critical(this, "Error", QString(tr("打开网卡失败"))+errbuf);
            else {
                config.setValue("net_name", net_name = name);
                reThd = new PcapReThread(pcapRe);
                reThd->start();
            }
        }
    }
    config.endGroup();

    getCard();
}

void MainWin::getCard() {
    auto msg = QByteArray::fromHex("55 55 01 0D 00 08 FF FF FF FF 00 00 AB CD  A0 00 00 00 00 00 38 CB 84 7E 00 00 00 00 00 00 AB CD CD 04 04 46");
    auto res = sendMsg(msg, {0x1E0, [=](const QByteArray data) {
        if(((u_char)data[10])==0xA0 && data[11]==0 && data[12]==0 && data[13]==0) {
            auto rr = 0;
            table->setRowCount(rr+1);
            uint32_t virtualVCM = data[6]<<8 | data[7] ;
            table->setText(rr, "type", tr("虚拟设备"));
            table->setText(rr, "name", tr("网口:")+QString::number(virtualVCM));
            table->setText(rr, "link", "千兆网直连");
            uint32_t vcsNum = data[20] << 24 | data[21] <<16 | data[22] <<8 | data[23] ;
            table->setText(rr, "vcs", QString::number(vcsNum));
            table->setText(rr, "Pinfo", "P:"+QString::number(virtualVCM));
            table->setText(rr, "Oinfo", "备注:可直接配屏，无需发送卡");
        }
    }});
    if(res) {
        QMessageBox::critical(this, "Error", QString(tr("发送失败: "))+pcap_geterr(pcapSend));
        return;
    }
}


