#include "ctrltestpanel.h"
#include "tools.h"
#include "gutil/qgui.h"
#include "gutil/qnetwork.h"
#include "base/waitingdlg.h"
#include <QFileDialog>
#include <QLineEdit>
#include <QJsonObject>
#include <QJsonDocument>
#include "globaldefine.h"
#include <QButtonGroup>
#include <QMessageBox>
#include <QHostAddress>

CtrlTestPanel::CtrlTestPanel() {
    auto vBox = new VBox(this);

    labelTestScreen = new QLabel;
    labelTestScreen->setAlignment(Qt::AlignCenter);
    vBox->addWidget(labelTestScreen);

    auto hBox = new HBox(vBox);
    auto vv = new VBox(hBox);

    groupBox = new QGroupBox;
    auto vvv = new VBox(groupBox);
    auto hhh = new HBox(vvv);
    hhh->addStretch();

    radioButtonRed = new QRadioButton;
    hhh->addWidget(radioButtonRed);

    radioButtonGreen = new QRadioButton;
    hhh->addWidget(radioButtonGreen);

    radioButtonBlue = new QRadioButton;
    hhh->addWidget(radioButtonBlue);

    radioButtonWhite = new QRadioButton;
    hhh->addWidget(radioButtonWhite);
    hhh->addStretch();


    hhh = new HBox(vvv);
    hhh->addStretch();

    checkBoxVertical = new QCheckBox;
    hhh->addWidget(checkBoxVertical);

    checkBoxSlash = new QCheckBox;
    hhh->addWidget(checkBoxSlash);

    checkBoxHorizontal = new QCheckBox;
    hhh->addWidget(checkBoxHorizontal);
    hhh->addStretch();


    hhh = new HBox(vvv);
    hhh->addStretch();

    label = new QLabel;
    hhh->addWidget(label);

    spinBoxLineSpeed = new QSpinBox;
    spinBoxLineSpeed->setMaximum(99999);
    hhh->addWidget(spinBoxLineSpeed);

    label_5 = new QLabel;
    hhh->addWidget(label_5);
    hhh->addSpacing(20);

    label_2 = new QLabel;
    hhh->addWidget(label_2);

    spinBoxLineDistance = new QSpinBox;
    spinBoxLineDistance->setMaximum(128);
    hhh->addWidget(spinBoxLineDistance);

    label_6 = new QLabel;
    hhh->addWidget(label_6);
    hhh->addStretch();

    pushButtonStartLine = new QPushButton;
    pushButtonStartLine->setMinimumSize(QSize(60, 30));
    pushButtonStartLine->setMaximumSize(QSize(80, 16777215));
    vvv->addWidget(pushButtonStartLine, 0, Qt::AlignHCenter);

    vv->addWidget(groupBox);

    groupBox_2 = new QGroupBox;
    vvv = new VBox(groupBox_2);
    checkBoxShowInfo = new QCheckBox;

    vvv->addWidget(checkBoxShowInfo, 0, Qt::AlignLeft);

    hhh = new HBox(vvv);
    hhh->addStretch();

    checkBox_red = new QCheckBox;
    hhh->addWidget(checkBox_red);

    checkBox_green = new QCheckBox;
    hhh->addWidget(checkBox_green);

    checkBox_blue = new QCheckBox;
    hhh->addWidget(checkBox_blue);

    checkBox_white = new QCheckBox;
    hhh->addWidget(checkBox_white);
    hhh->addStretch();

    hhh = new HBox(vvv);
    hhh->addStretch();

    label_3 = new QLabel;
    hhh->addWidget(label_3);

    spinBoxGraySpeed = new QSpinBox;
    spinBoxGraySpeed->setMinimumSize(QSize(60, 0));
    spinBoxGraySpeed->setMinimum(10);
    spinBoxGraySpeed->setMaximum(99999);

    hhh->addWidget(spinBoxGraySpeed);

    label_8 = new QLabel;
    hhh->addWidget(label_8);

    label_4 = new QLabel;
    hhh->addWidget(label_4);

    spinBoxGrayValue = new QSpinBox;
    spinBoxGrayValue->setMaximum(255);
    hhh->addWidget(spinBoxGrayValue);

    label_7 = new QLabel;
    hhh->addWidget(label_7);
    hhh->addStretch();


    pushButtonStartGray = new QPushButton;
    pushButtonStartGray->setMinimumSize(QSize(60, 30));
    pushButtonStartGray->setMaximumSize(QSize(80, 16777215));
    vvv->addWidget(pushButtonStartGray, 0, Qt::AlignHCenter);

    vv->addWidget(groupBox_2);

    groupBox_3 = new QGroupBox;
    vvv = new VBox(groupBox_3);

    checkBoxGradient = new QCheckBox;
    vvv->addWidget(checkBoxGradient);

    hhh = new HBox(vvv);
    hhh->addStretch();

    radioButton_red = new QRadioButton;
    hhh->addWidget(radioButton_red);

    radioButton_Green = new QRadioButton;
    hhh->addWidget(radioButton_Green);

    radioButton_Blue = new QRadioButton;
    hhh->addWidget(radioButton_Blue);

    radioButton_White = new QRadioButton;
    hhh->addWidget(radioButton_White);
    hhh->addStretch();

    pushButtonStartColor = new QPushButton;
    pushButtonStartColor->setMinimumSize(QSize(60, 30));
    pushButtonStartColor->setMaximumSize(QSize(80, 16777215));

    vvv->addWidget(pushButtonStartColor, 0, Qt::AlignHCenter);

    vv->addWidget(groupBox_3);

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

    pushButtonStopTest = new QPushButton;
    pushButtonStopTest->setMinimumSize(QSize(60, 30));
    hhh->addWidget(pushButtonStopTest);
    hhh->addStretch();

    vv->addStretch();

    auto line = new QFrame;
    line->setFrameShape(QFrame::VLine);
    line->setFrameShadow(QFrame::Sunken);
    hBox->addWidget(line);
    hBox->addStretch();

    vv = new VBox(hBox);

    lineEdit = new QLineEdit;
    lineEdit->setMinimumSize(QSize(0, 36));
    lineEdit->setMaximumSize(QSize(194, 16777215));
    lineEdit->setAutoFillBackground(false);
    lineEdit->setStyleSheet(QString::fromUtf8("color: rgb(0, 255, 0);\n"
                                              "background-color: rgb(0, 0, 0);"));
    lineEdit->setAlignment(Qt::AlignCenter);
    vv->addWidget(lineEdit);

    auto gridLayout = new Grid(vv);

    auto btngrp = new QButtonGroup(this);
    for(int i=0; i<10; ++i) {
        auto btn = new QPushButton(QString::number(i));
        btn->setFixedSize(60, 30);
        btn->setProperty("ssType", "progManageTool");
        btngrp->addButton(btn, i);
    }
    gridLayout->addWidget(btngrp->button(1), 0, 0);
    gridLayout->addWidget(btngrp->button(2), 0, 1);
    gridLayout->addWidget(btngrp->button(3), 0, 2);
    gridLayout->addWidget(btngrp->button(4), 1, 0);
    gridLayout->addWidget(btngrp->button(5), 1, 1);
    gridLayout->addWidget(btngrp->button(6), 1, 2);
    gridLayout->addWidget(btngrp->button(7), 2, 0);
    gridLayout->addWidget(btngrp->button(8), 2, 1);
    gridLayout->addWidget(btngrp->button(9), 2, 2);
    gridLayout->addWidget(btngrp->button(0), 3, 0);
    connect(btngrp, &QButtonGroup::idClicked, this, [=](int id) {
        if(lineEdit->text().contains("-")) lineEdit->clear();
        lineEdit->setText(lineEdit->text() + QString::number(id));
        btnAnycast->setEnabled(true);
    });

    pushButton_11 = new QPushButton;
    pushButton_11->setFixedSize(QSize(60, 30));
    gridLayout->addWidget(pushButton_11, 3, 1, 1, 1);

    pushButton_12 = new QPushButton;
    pushButton_12->setFixedSize(QSize(60, 30));
    gridLayout->addWidget(pushButton_12, 3, 2, 1, 1);

    btnAnycast = new QPushButton;
    vv->addWidget(btnAnycast);
    vv->addStretch();

    hBox->addStretch();
    vBox->addStretch();

    pushButtonStartLine->setProperty("ssType", "progManageTool");
    pushButtonStartGray->setProperty("ssType", "progManageTool");
    pushButtonStartColor->setProperty("ssType", "progManageTool");
    pushButtonStopTest->setProperty("ssType", "progManageTool");
    pushButton_11->setProperty("ssType", "progManageTool");
    pushButton_12->setProperty("ssType", "progManageTool");
    btnAnycast->setProperty("ssType", "progManageTool");

    spinBoxLineSpeed->setValue(10);
    spinBoxLineDistance->setValue(15);
    spinBoxGraySpeed->setValue(10);
    spinBoxGrayValue->setValue(0);
    radioButtonWhite->setChecked(true);
    radioButton_White->setChecked(true);
    checkBoxHorizontal->setChecked(true);
    checkBoxVertical->setChecked(true);
    checkBoxSlash->setChecked(true);
    checkBox_red->setChecked(true);
    checkBox_green->setChecked(true);
    checkBox_blue->setChecked(true);
    checkBox_white->setChecked(true);

    connect(pushButtonStartLine, &QPushButton::clicked, this, [this] {
        if(gSelCards.isEmpty()) {
            QMessageBox::information(this, tr("Tip"), tr("NoSelectedController"));
            return;
        }
        QJsonObject json;
        json.insert("_id", "TestScreen");
        json.insert("_type", "TestScreen");
        json.insert("mode", 1);// 0:停止; 1:斜线; 2:灰度; 3:颜色;4:渐变
        json.insert("speed", spinBoxLineSpeed->value());
        if(radioButtonRed->isChecked()) json.insert("color", "#FFFF0000");
        else if(radioButtonGreen->isChecked()) json.insert("color", "#FF00FF00");
        else if(radioButtonBlue->isChecked()) json.insert("color", "#FF0000FF");
        else json.insert("color", "#FFFFFFFF");
        json.insert("interval", spinBoxLineDistance->value());
        json.insert("horizonalLine", checkBoxHorizontal->isChecked());
        json.insert("verticalLine", checkBoxVertical->isChecked());
        json.insert("slantLine", checkBoxSlash->isChecked());
        json.insert("runLimit", spinBoxGrayValue->value());
        json.insert("showInfo", !checkBoxShowInfo->isChecked());
        json.insert("red", checkBox_red->isChecked());
        json.insert("green", checkBox_green->isChecked());
        json.insert("blue", checkBox_blue->isChecked());
        json.insert("white", checkBox_white->isChecked());
        if(gSelCards.count() == 1) {
            auto waitingDlg = new WaitingDlg(this, tr("StartTest")+" ...");
            Def_CtrlReqPre
                connect(reply, &QNetworkReply::finished, this, [=] {
                    Def_CtrlSetReqAfter
                });
        } else {
            foreach(auto card, gSelCards) {
                Def_CtrlSetMulti(tr("StartTest"))
            }
        }
    });
    connect(pushButtonStartGray, &QPushButton::clicked, this, [this] {
        if(gSelCards.isEmpty()) {
            QMessageBox::information(this, tr("Tip"), tr("NoSelectedController"));
            return;
        }
        QJsonObject json;
        json.insert("_id", "TestScreen");
        json.insert("_type", "TestScreen");
        json.insert("mode", 2);// 0:停止; 1:斜线; 2:灰度; 3:颜色;4:渐变
        json.insert("speed", spinBoxGraySpeed->value());
        if(radioButtonRed->isChecked()) json.insert("color", "#FFFF0000");
        else if(radioButtonGreen->isChecked()) json.insert("color", "#FF00FF00");
        else if(radioButtonBlue->isChecked()) json.insert("color", "#FF0000FF");
        else json.insert("color", "#FFFFFFFF");
        json.insert("interval", spinBoxLineDistance->value());
        json.insert("horizonalLine", checkBoxHorizontal->isChecked());
        json.insert("verticalLine", checkBoxVertical->isChecked());
        json.insert("slantLine", checkBoxSlash->isChecked());
        json.insert("runLimit", spinBoxGrayValue->value());
        json.insert("showInfo", !checkBoxShowInfo->isChecked());
        json.insert("red", checkBox_red->isChecked());
        json.insert("green", checkBox_green->isChecked());
        json.insert("blue", checkBox_blue->isChecked());
        json.insert("white", checkBox_white->isChecked());
        if(gSelCards.count() == 1) {
            auto waitingDlg = new WaitingDlg(this, tr("StartTest")+" ...");
            Def_CtrlReqPre
            connect(reply, &QNetworkReply::finished, this, [=] {
                Def_CtrlSetReqAfter
            });
        } else {
            foreach(auto card, gSelCards) {
                Def_CtrlSetMulti(tr("StartTest"))
            }
        }
    });
    connect(pushButtonStartColor, &QPushButton::clicked, this, [this] {
        if(gSelCards.isEmpty()) {
            QMessageBox::information(this, tr("Tip"), tr("NoSelectedController"));
            return;
        }
        QJsonObject json;
        json.insert("_id", "TestScreen");
        json.insert("_type", "TestScreen");
        json.insert("mode", checkBoxGradient->isChecked() ? 4 : 3);// 0:停止; 1:斜线; 2:灰度; 3:颜色;4:渐变
        json.insert("speed", spinBoxLineSpeed->value());
        if(radioButton_red->isChecked()) json.insert("color", "#FFFF0000");
        else if(radioButton_Green->isChecked()) json.insert("color", "#FF00FF00");
        else if(radioButton_Blue->isChecked()) json.insert("color", "#FF0000FF");
        else json.insert("color", "#FFFFFFFF");
        json.insert("interval", spinBoxLineDistance->value());
        json.insert("horizonalLine", checkBoxHorizontal->isChecked());
        json.insert("verticalLine", checkBoxVertical->isChecked());
        json.insert("slantLine", checkBoxSlash->isChecked());
        json.insert("runLimit", spinBoxGrayValue->value());
        json.insert("showInfo", !checkBoxShowInfo->isChecked());
        json.insert("red", checkBox_red->isChecked());
        json.insert("green", checkBox_green->isChecked());
        json.insert("blue", checkBox_blue->isChecked());
        json.insert("white", checkBox_white->isChecked());
        if(gSelCards.count() == 1) {
            auto waitingDlg = new WaitingDlg(this, tr("StartTest")+" ...");
            Def_CtrlReqPre
                connect(reply, &QNetworkReply::finished, this, [=] {
                    Def_CtrlSetReqAfter
                });
        } else {
            foreach(auto card, gSelCards) {
                Def_CtrlSetMulti(tr("StartTest"))
            }
        }
    });
    connect(pushButtonStopTest, &QPushButton::clicked, this, [this] {
        if(gSelCards.isEmpty()) {
            QMessageBox::information(this, tr("Tip"), tr("NoSelectedController"));
            return;
        }
        QJsonObject json;
        json.insert("_id", "TestScreen");
        json.insert("_type", "TestScreen");
        json.insert("mode", 0);
        if(gSelCards.count() == 1) {
            auto waitingDlg = new WaitingDlg(this, tr("StopTest")+" ...");
            Def_CtrlReqPre
                connect(reply, &QNetworkReply::finished, this, [=] {
                    Def_CtrlSetReqAfter
                });
        } else {
            foreach(auto card, gSelCards) {
                Def_CtrlSetMulti(tr("StopTest"))
            }
        }
    });
    connect(pushButton_11, &QPushButton::clicked, this, [=] {
        lineEdit->clear();
        btnAnycast->setEnabled(false);
    });
    connect(pushButton_12, &QPushButton::clicked, this, [=] {
        if(gSelCards.isEmpty()) {
            QMessageBox::information(this, tr("Tip"), tr("NoSelectedController"));
            return;
        }
        int iIndex = lineEdit->text().toInt();
        if(gSelCards.count()==1) SendAnycastCmd(gSelCards[0], 0, true);
        else {
            foreach(auto card, gSelCards) SendAnycastCmd(card, iIndex, false);
        }
        lineEdit->setText("-"+tr("loopback mode")+"-");
        btnAnycast->setEnabled(false);
    });
    connect(btnAnycast, &QPushButton::clicked, this, [=] {
        if(gSelCards.isEmpty()) {
            QMessageBox::information(this, tr("Tip"), tr("NoSelectedController"));
            return;
        }
        int iIndex = lineEdit->text().toInt();
        if(gSelCards.count()==1) SendAnycastCmd(gSelCards[0], iIndex, true);
        else foreach(auto card, gSelCards) SendAnycastCmd(card, iIndex, false);
        lineEdit->setText(tr("Anycast")+" - "+lineEdit->text());
        btnAnycast->setEnabled(false);
    });

    btnAnycast->setEnabled(false);

    lineEdit->setValidator(new QIntValidator(0, 100, this));

    transUi();
}

void CtrlTestPanel::changeEvent(QEvent *event) {
    QWidget::changeEvent(event);
    if(event->type() == QEvent::LanguageChange) transUi();
}
void CtrlTestPanel::transUi() {
    labelTestScreen->setText(tr("Test Screen"));
    groupBox->setTitle(tr("Line test"));
    radioButtonRed->setText(tr("Red"));
    radioButtonGreen->setText(tr("Green"));
    radioButtonBlue->setText(tr("Blue"));
    radioButtonWhite->setText(tr("White"));
    radioButton_red->setText(tr("Red"));
    radioButton_Green->setText(tr("Green"));
    radioButton_Blue->setText(tr("Blue"));
    radioButton_White->setText(tr("White"));
    checkBoxVertical->setText(tr("Vertical"));
    checkBoxHorizontal->setText(tr("Horizontal"));
    checkBoxSlash->setText(tr("Slash"));
    label->setText(tr("Speed"));
    label_5->setText(tr("ms(>10)"));
    checkBoxHorizontal->setText(tr("Horizontal"));
    label_2->setText(tr("Line Distance"));
    pushButtonStartLine->setText(tr("Test"));
    groupBox_2->setTitle(tr("Gradation test"));
    checkBoxShowInfo->setText(tr("Only the gray value is displayed"));
    checkBox_red->setText(tr("Red"));
    checkBox_green->setText(tr("Green"));
    checkBox_blue->setText(tr("Blue"));
    checkBox_white->setText(tr("White"));
    label_3->setText(tr("Speed"));
    label_4->setText(tr("GrayValue"));
    pushButtonStartGray->setText(tr("Test"));
    pushButtonStartColor->setText(tr("Test"));
    groupBox_3->setTitle(tr("Color test"));
    checkBoxGradient->setText(tr("Gradient"));
    radioButton_red->setText(tr("Red"));
    radioButton_Green->setText(tr("Green"));
    radioButton_Blue->setText(tr("Blue"));
    radioButton_White->setText(tr("White"));
    pushButtonStopTest->setText(tr("Stop"));
    pushButton_11->setText(tr("Clear"));
    pushButton_12->setText(tr("Reset"));
    btnAnycast->setText(tr("Anycast"));
}

void CtrlTestPanel::SendAnycastCmd(LedCard card, int iProgramIndex, bool isSingle) {
    QTcpSocket *send = new QTcpSocket();
    connect(send, SIGNAL(connected()), this, SLOT(connect_sucessful()));
    connect(send, SIGNAL(error(QAbstractSocket::SocketError)),this, SLOT(show_error(QAbstractSocket::SocketError)));
    send->connectToHost(QHostAddress(card.ip),31299);

    ST_ANSY_PROGRAM_PACKET tempStreadPakcet;
    tempStreadPakcet.ucCommType=0x97;
    tempStreadPakcet.iBaoLiu=0;
    tempStreadPakcet.iLength=4;
    unsigned char uctemp[4]={0};
    uctemp[0]=iProgramIndex;

    memcpy(tempStreadPakcet.pDataBuffer,uctemp,4);
    tempStreadPakcet.pDataBuffer[tempStreadPakcet.iLength]=GetCheckCodeIn8(&tempStreadPakcet.ucCommType,tempStreadPakcet.iLength+sizeof(tempStreadPakcet.iBaoLiu)+sizeof(tempStreadPakcet.ucCommType)+sizeof(tempStreadPakcet.iLength));
    int iLenPacket=3*sizeof(unsigned char)+sizeof(char)+sizeof(int)+sizeof(int)+tempStreadPakcet.iLength+sizeof(char);/////除正文外的协议结构大小;
    QByteArray databuf = QByteArray(reinterpret_cast<char*>(&tempStreadPakcet), iLenPacket);
    if(!send->waitForConnected(10000))              //等待连接返回
    {
        if(isSingle) QMessageBox::information(this, tr("Tip"), tr("Connect timeout"));
        else gFdResInfo->append(card.id+":"+tr("receive")+"<-"+tr("Connect")+":"+tr("timeout"));
        send->close();
        delete send;
        return;
    }
    send->write(databuf);
    if(send->waitForBytesWritten(3000)) {
        send->read(send->bytesAvailable());
        if(isSingle) QMessageBox::information(this, tr("Tip"), (iProgramIndex==0 ? tr("Reset loop mode") : tr("Anycast"))+":"+tr("success"));
        else gFdResInfo->append(card.id+":"+tr("receive")+"<-"+tr("Anycast")+":"+tr("success"));
    }
    send->close();
    delete send;
}