#include "expertsmartpointsetwin.h"
#include <QStackedLayout>
#include <QLabel>
#include <QRadioButton>
#include <QPushButton>
#include <QButtonGroup>
#include <QHeaderView>
#include <QMessageBox>
#include <QLineEdit>
#include <QApplication>
#include <QFileDialog>
#include <QJsonObject>
#include <QJsonArray>
#include <QJsonDocument>

ExpertSmartPointSetWin::ExpertSmartPointSetWin(ExpertWin *expertWin) : BaseWin{expertWin}, expertWin(expertWin) {
    setWindowModality(Qt::WindowModal);
    setAttribute(Qt::WA_DeleteOnClose);
    setWindowTitle(tr("智能走点参数配置"));
    resize(900, 600);

    ModuleWidth = expertWin->mModule["ModuleWidth"].toInt();
    ModuleHeight = expertWin->mModule["ModuleHeight"].toInt();
    GroupNum = expertWin->mModule["GroupNum"].toInt();
    ScanNum = expertWin->mModule["ScanNum"].toInt();
    ChipType = expertWin->mModule["ChipType"].toString();
    DecodeMode = expertWin->mModule["DecodeMode"].toString();
    GroupMode = expertWin->mModule["GroupMode"].toString();

    auto vBox = new QVBoxLayout(center);
    vBox->setContentsMargins(0,0,0,0);
    vBox->setSpacing(3);
    vBox->addLayout(addBtns(new QHBoxLayout()));

    auto stack = new QStackedLayout;
    vBox->addLayout(stack);

    auto page = new QWidget;
    stack->addWidget(page);
    QPalette bkBlue;
    {
        auto vBox = new QVBoxLayout(page);
        vBox->setContentsMargins(50, 50, 6, 6);

        auto lb = new QLabel(tr("基本参数"));
        bkBlue = lb->palette();
        bkBlue.setColor(QPalette::WindowText, QColor(0x5599ff));
        lb->setPalette(bkBlue);
        vBox->addWidget(lb);
        vBox->addSpacing(50);

        auto hBox = new QHBoxLayout;
        hBox->addStretch();
        {
            auto vvv = new QVBoxLayout;
            auto hhhh = new QHBoxLayout;

            lb = new QLabel(tr("模组宽度: "));
            hhhh->addWidget(lb);

            fdModuleWidth = new QSpinBox;
            fdModuleWidth->setRange(0, 9999);
            fdModuleWidth->setValue(ModuleWidth);
            hhhh->addWidget(fdModuleWidth);

            vvv->addLayout(hhhh);
            vvv->addSpacing(30);
            hhhh = new QHBoxLayout;

            lb = new QLabel(tr("模组高度: "));
            hhhh->addWidget(lb);

            fdModuleHeight = new QSpinBox;
            fdModuleHeight->setRange(0, 9999);
            fdModuleHeight->setValue(ModuleHeight);
            hhhh->addWidget(fdModuleHeight);

            vvv->addLayout(hhhh);
            vvv->addSpacing(30);
            hhhh = new QHBoxLayout;

            lb = new QLabel(tr("数据组数: "));
            hhhh->addWidget(lb);

            fdGroupNum = new QSpinBox;
            fdGroupNum->setRange(0, 9999);
            fdGroupNum->setValue(GroupNum);
            hhhh->addWidget(fdGroupNum);

            vvv->addLayout(hhhh);
            vvv->addStretch();

            hBox->addLayout(vvv);
        }
        hBox->addStretch();
        {
            auto vvv = new QVBoxLayout;
            auto hhhh = new QHBoxLayout;

            lb = new QLabel(tr("驱动芯片: "));
            hhhh->addWidget(lb);

            fdChipType = new QComboBox;
            fdChipType->addItem("ICND2153");
            hhhh->addWidget(fdChipType);

            vvv->addLayout(hhhh);
            vvv->addSpacing(30);
            hhhh = new QHBoxLayout;

            lb = new QLabel(tr("译码方式: "));
            hhhh->addWidget(lb);

            fdDecodeMode = new QComboBox;
            fdDecodeMode->addItem(tr("138译码"));
            hhhh->addWidget(fdDecodeMode);

            vvv->addLayout(hhhh);
            vvv->addSpacing(30);
            hhhh = new QHBoxLayout;

            lb = new QLabel(tr("分组方式: "));
            hhhh->addWidget(lb);

            fdGroupMode = new QComboBox;
            fdGroupMode->addItem(tr("三线并行"));
            fdGroupMode->addItem(tr("三色1点串"));
            fdGroupMode->addItem(tr("三色8点串"));
            fdGroupMode->addItem(tr("三色16点串"));
            hhhh->addWidget(fdGroupMode);

            vvv->addLayout(hhhh);
            vvv->addStretch();

            hBox->addLayout(vvv);
        }
        hBox->addStretch();
        vBox->addLayout(hBox);
    }

    page = new QWidget;
    stack->addWidget(page);
    {
        auto vBox = new QVBoxLayout(page);
        vBox->setContentsMargins(50, 50, 6, 6);

        auto lb = new QLabel(tr("扫描行数"));
        lb->setPalette(bkBlue);
        vBox->addWidget(lb);
        vBox->addSpacing(50);

        auto hBox = new QHBoxLayout;
        vBox->addLayout(hBox);
        hBox->addStretch();

        auto vvv = new QVBoxLayout;
        hBox->addLayout(vvv);

        lb = new QLabel(tr("根据亮线的行/列数确定扫描行/列数: "));
        vvv->addWidget(lb);
        vvv->addSpacing(30);

        auto hhhh = new QHBoxLayout;
        hhhh->addStretch();
        auto fdRow = new QRadioButton(tr("行"));
        hhhh->addWidget(fdRow);
        hhhh->addStretch();
        auto fdCol = new QRadioButton(tr("列"));
        hhhh->addWidget(fdCol);
        hhhh->addStretch();
        vvv->addLayout(hhhh);
        vvv->addSpacing(20);

        hhhh = new QHBoxLayout;
        hhhh->addStretch();

        lb = new QLabel(tr("亮线的行/列数: "));
        hhhh->addWidget(lb);

        auto fdNum = new QSpinBox;
        fdNum->setRange(0, 9999);
        fdNum->setValue(1);
        hhhh->addWidget(fdNum);

        hhhh->addStretch();
        vvv->addLayout(hhhh);

        vvv->addStretch();

        hBox->addStretch();

        vvv = new QVBoxLayout;
        hBox->addLayout(vvv);

        lb = new QLabel(tr("芯片245版本: "));
        vvv->addWidget(lb);
        vvv->addSpacing(30);

        hhhh = new QHBoxLayout;
        hhhh->addStretch();
        auto fdA = new QRadioButton("A");
        hhhh->addWidget(fdA);
        hhhh->addStretch();
        auto fdD = new QRadioButton("D");
        hhhh->addWidget(fdD);
        hhhh->addStretch();
        vvv->addLayout(hhhh);

        vvv->addStretch();
        hBox->addStretch();
    }

    page = new QWidget;
    stack->addWidget(page);
    {
        auto vBox = new QVBoxLayout(page);
        vBox->setContentsMargins(50, 50, 6, 6);

        auto lb = new QLabel(tr("数据线颜色"));
        lb->setPalette(bkBlue);
        vBox->addWidget(lb);
        vBox->addSpacing(50);

        lb = new QLabel(tr("依次点击以下状态, 根据模组颜色选择对应颜色"));
        vBox->addWidget(lb, 0, Qt::AlignCenter);
        vBox->addSpacing(30);

        auto hhhh = new QHBoxLayout;
        hhhh->addStretch();
        auto fdSta1 = new QRadioButton(tr("状态1"));
        fdSta1->setChecked(true);
        hhhh->addWidget(fdSta1);
        hhhh->addStretch();

        auto fdR1 = new QRadioButton(tr("红"));
        fdR1->setChecked(true);
        hhhh->addWidget(fdR1);
        hhhh->addSpacing(20);

        auto fdG1 = new QRadioButton(tr("绿"));
        hhhh->addWidget(fdG1);
        hhhh->addSpacing(20);

        auto fdB1 = new QRadioButton(tr("蓝"));
        hhhh->addWidget(fdB1);
        hhhh->addSpacing(20);

        auto fdNo1 = new QRadioButton(tr("黑"));
        hhhh->addWidget(fdNo1);
        hhhh->addStretch();

        vBox->addLayout(hhhh);
        vBox->addSpacing(20);

        hhhh = new QHBoxLayout;
        hhhh->addStretch();
        auto fdSta2 = new QRadioButton(tr("状态2"));
        hhhh->addWidget(fdSta2);
        hhhh->addStretch();

        auto fdR2 = new QRadioButton(tr("红"));
        hhhh->addWidget(fdR2);
        hhhh->addSpacing(20);

        auto fdG2 = new QRadioButton(tr("绿"));
        fdG2->setChecked(true);
        hhhh->addWidget(fdG2);
        hhhh->addSpacing(20);

        auto fdB2 = new QRadioButton(tr("蓝"));
        hhhh->addWidget(fdB2);
        hhhh->addSpacing(20);

        auto fdNo2 = new QRadioButton(tr("黑"));
        hhhh->addWidget(fdNo2);
        hhhh->addStretch();

        vBox->addLayout(hhhh);
        vBox->addSpacing(20);

        hhhh = new QHBoxLayout;
        hhhh->addStretch();
        auto fdSta3 = new QRadioButton(tr("状态3"));
        hhhh->addWidget(fdSta3);
        hhhh->addStretch();

        auto fdR3 = new QRadioButton(tr("红"));
        hhhh->addWidget(fdR3);
        hhhh->addSpacing(20);

        auto fdG3 = new QRadioButton(tr("绿"));
        hhhh->addWidget(fdG3);
        hhhh->addSpacing(20);

        auto fdB3 = new QRadioButton(tr("蓝"));
        fdB3->setChecked(true);
        hhhh->addWidget(fdB3);
        hhhh->addSpacing(20);

        auto fdNo3 = new QRadioButton(tr("黑"));
        hhhh->addWidget(fdNo3);
        hhhh->addStretch();

        vBox->addLayout(hhhh);
        vBox->addStretch();

        auto btnGrp = new QButtonGroup(page);
        btnGrp->addButton(fdR1);
        btnGrp->addButton(fdG1);
        btnGrp->addButton(fdB1);
        btnGrp->addButton(fdNo1);
        btnGrp = new QButtonGroup(page);
        btnGrp->addButton(fdR2);
        btnGrp->addButton(fdG2);
        btnGrp->addButton(fdB2);
        btnGrp->addButton(fdNo2);
        btnGrp = new QButtonGroup(page);
        btnGrp->addButton(fdR3);
        btnGrp->addButton(fdG3);
        btnGrp->addButton(fdB3);
        btnGrp->addButton(fdNo3);
    }

    page = new QWidget;
    stack->addWidget(page);
    {
        auto vBox = new QVBoxLayout(page);
        vBox->setContentsMargins(0,0,0,0);

        auto hhh = new QHBoxLayout;

        auto btnUndo = new QPushButton("回撤");
        btnUndo->setMinimumSize(90, 30);
        connect(btnUndo, &QPushButton::clicked, this, [this] {
            auto lastIdx = tableRow->columnCount()-1;
            if(lastIdx==-1) return;
            auto last = tableRow->item(1, lastIdx);
            if(last->text()=="×") virtualCnt--;
            else {
                auto point = last->data(Qt::UserRole).toPoint();
                table->setText(point.y(), point.x(), "");
                if(lastIdx==virtualCnt) table->selectionModel()->clearCurrentIndex();
                else {
                    for(int i=lastIdx-1; i>-1; i--) {
                        if(tableRow->text(1, i)=="×") continue;
                        auto point = tableRow->data(1, i).toPoint();
                        table->setCurrentCell(point.y(), point.x());
                        break;
                    }
                }
            }
            tableRow->setColumnCount(lastIdx);
        });
        hhh->addWidget(btnUndo);

        auto btnAddVoid = new QPushButton(tr("插入虚点"));
        btnAddVoid->setMinimumSize(90, 30);
        connect(btnAddVoid, &QPushButton::clicked, this, [this] {
            virtualCnt++;
            auto cnt = tableRow->columnCount();
            tableRow->setColumnCount(cnt+1);
            tableRow->setText(0, cnt, QString::number(cnt+1))->setTextAlignment(Qt::AlignCenter);
            tableRow->setText(1, cnt, "×")->setTextAlignment(Qt::AlignCenter);
        });
        hhh->addWidget(btnAddVoid);

        auto btnReset = new QPushButton(tr("重新走点"));
        btnReset->setMinimumSize(90, 30);
        connect(btnReset, &QPushButton::clicked, this, [this] {
            table->clearContents();
            tableRow->setColumnCount(0);
            virtualCnt = 0;
        });
        hhh->addWidget(btnReset);

        auto btnOK = new QPushButton(tr("完成"));
        btnOK->setMinimumSize(90, 30);
        connect(btnOK, &QPushButton::clicked, this, &ExpertSmartPointSetWin::save);
        hhh->addWidget(btnOK);

        hhh->addStretch();
        vBox->addLayout(hhh);

        table = new NumTable;
        table->setNoEdit();
        table->setSelectionMode(QTableWidget::SingleSelection);
        table->setColWidth(40);
        table->horizontalHeader()->setDefaultAlignment(Qt::AlignCenter);
        table->verticalHeader()->setMinimumWidth(40);
        table->verticalHeader()->setDefaultAlignment(Qt::AlignCenter);
        connect(table, &QTableWidget::currentCellChanged, this, [=](int row, int col) {
            if(row < 0) return;
            auto text = table->text(row, col);
            if(! text.isEmpty()) return;
            if(scans.isEmpty()) {
                auto cnt = tableRow->columnCount() + 1;
                tableRow->setColumnCount(cnt);
                tableRow->setText(0, cnt-1, QString::number(cnt))->setTextAlignment(Qt::AlignCenter);
                tableRow->setText(1, cnt-1, "√")->setTextAlignment(Qt::AlignCenter);
                tableRow->setData(1, cnt-1, QPoint{col, row});
                auto realCnt = cnt - virtualCnt;
                table->setText(row, col, QString::number(realCnt))->setTextAlignment(Qt::AlignCenter);
                if(realCnt==ModuleWidth) {
                    scans.append({col, row});
                    QMessageBox::information(this, tr("提示"), tr("列走完"));
                }
            } else if(scans.size() < ScanNum) {
                scans.append({col, row});
                auto size = scans.size();
                table->setText(row, col, "S"+QString::number(size))->setTextAlignment(Qt::AlignCenter);
                if(size==ScanNum) {
                    QMessageBox::information(this, tr("提示"), tr("行走完"));
                    save();
                }
            }
        });


        vBox->addWidget(table);

        tableRow = new NumTable(2, 0);
        tableRow->setNoEdit();
        tableRow->setSelectionMode(QTableWidget::NoSelection);
        tableRow->horizontalHeader()->setDefaultSectionSize(40);
        tableRow->horizontalHeader()->setVisible(false);
        tableRow->verticalHeader()->setSectionResizeMode(QHeaderView::Fixed);
        tableRow->verticalHeader()->setMinimumWidth(120);
        tableRow->setMaximumHeight(80);
        auto item = tableRow->verticalHeaderItem(0);
        if(item==0) tableRow->setVerticalHeaderItem(0, item = new QTableWidgetItem());
        item->setText(tr("第一扫灯数:"));
        item = tableRow->verticalHeaderItem(1);
        if(item==0) tableRow->setVerticalHeaderItem(1, item = new QTableWidgetItem());
        item->setText(tr("实: 虚:"));
        vBox->addWidget(tableRow);
    }

    auto hBox = new QHBoxLayout;
    vBox->addLayout(hBox);

    hBox->addStretch();

    auto btnPrev = new QPushButton(tr("上一步"));
    btnPrev->setMinimumSize(90, 30);
    hBox->addWidget(btnPrev);

    auto btnNext = new QPushButton(tr("下一步"));
    btnNext->setMinimumSize(90, 30);
    hBox->addWidget(btnNext);

    connect(btnPrev, &QPushButton::clicked, this, [stack, btnPrev, btnNext] {
        auto idx = stack->currentIndex();
        stack->setCurrentIndex(--idx);
        btnPrev->setEnabled(idx > 0);
        btnNext->setEnabled(idx < stack->count()-1);
    });
    connect(btnNext, &QPushButton::clicked, this, [=] {
        auto idx = stack->currentIndex();
        if(idx==0) {
            ModuleWidth = fdModuleWidth->value();
            ModuleHeight = fdModuleHeight->value();
            GroupNum = fdGroupNum->value();
            ScanNum = (ModuleHeight + 1) / GroupNum;
            ChipType = fdChipType->currentText();
            DecodeMode = fdDecodeMode->currentText();
            GroupMode = fdGroupMode->currentText();
        } else if(idx==2) {
            table->setColumnCount(ModuleWidth);
            table->setRowCount(ModuleHeight);
            QColor altColor(0x445566);
            for(int r=0; r<ModuleHeight; r++) {
                if((r&7)!=7) for(int c=7; c<ModuleWidth; c+=8) table->itemValid(r, c)->setBackground(altColor);
                else for(int c=0; c<ModuleWidth; c++) table->itemValid(r, c)->setBackground(altColor);
            }
        }
        stack->setCurrentIndex(++idx);
        btnPrev->setEnabled(idx > 0);
        btnNext->setEnabled(idx < stack->count()-1);
    });

    auto btnCcl = new QPushButton("取消");
    btnCcl->setMinimumSize(90, 30);
    hBox->addWidget(btnCcl);

    hBox->addSpacing(30);
}

void ExpertSmartPointSetWin::save() {
    auto file = QApplication::applicationDirPath()+"/temp.module";
    QFile qFile(file);
    if(! qFile.open(QFile::WriteOnly)) {
        QMessageBox::critical(this, tr("失败"), QString(tr("准备写入 %1 文件失败")).arg(file));
        return;
    }
    QJsonObject obj;
    obj.insert("ModuleWidth", ModuleWidth);
    obj.insert("ModuleHeight", ModuleHeight);
    obj.insert("GroupNum", GroupNum);
    obj.insert("ScanNum", ScanNum);
    obj.insert("ChipType", ChipType);
    obj.insert("DecodeMode", DecodeMode);
    obj.insert("GroupMode", GroupMode);
    QJsonArray points;
    auto cnt = tableRow->columnCount();
    if(cnt > ModuleWidth) {
        auto add = (cnt+ModuleWidth-1) / ModuleWidth * ModuleWidth - cnt;
        for(int i=0; i<add; i++) points.append(-1);
    }
    for(int i=cnt-1; i>=0; i--) {
        auto data = tableRow->data(1, i);
        points.append(data.isValid() ? data.toPoint().x() : -1);
    }
    obj.insert("Points", points);
    QJsonArray Scans;
    foreach(QPoint scan, scans) Scans.append(scan.y());
    obj.insert("Scans", Scans);
    auto data = QJsonDocument(obj).toJson(QJsonDocument::Indented);
    auto res = qFile.write(data);
    qFile.close();
    if(res < 0) {
        QMessageBox::critical(this, tr("失败"), QString(tr("写入 %1 文件失败")).arg(file));
        return;
    }
    expertWin->mModule = obj;

    expertWin->fdModuleWidth->setText(QString::number(ModuleWidth));
    expertWin->fdModuleHeight->setText(QString::number(ModuleHeight));
    expertWin->fdGroupNum->setText(QString::number(GroupNum));
    expertWin->fdScanNum->setText(QString::number(ScanNum));
    expertWin->fdChipType->setText(ChipType);
    expertWin->fdDecodeMode->setText(DecodeMode);

    expertWin->fdCardWidth->setValue(ModuleWidth);
    expertWin->fdCardHeight->setValue(ModuleHeight);

    auto appDir = QApplication::applicationDirPath();
    QDir(appDir).mkdir("ModuleFiles");
    file = QFileDialog::getSaveFileName(this, tr("保存文件"), appDir+QString("/ModuleFiles/%1X%2_%3扫.module").arg(ModuleWidth).arg(ModuleHeight).arg(ScanNum), tr("Module file (*.module)"));
    if(file.isEmpty()) return;
    QFile qFile2(file);
    if(! qFile2.open(QFile::WriteOnly)) {
        QMessageBox::critical(this, tr("失败"), QString(tr("准备写入 %1 文件失败")).arg(file));
        return;
    }
    res = qFile2.write(data);
    qFile2.close();
    if(res < 0) {
        QMessageBox::critical(this, tr("失败"), QString(tr("写入 %1 文件失败")).arg(file));
        return;
    }
    QMessageBox::information(this, tr("保存成功"), tr("保存成功"));
    close();
}