#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug.h>
#include <QMessageBox>
#include <drivers/log/logHandler.h>
#include <QMenuBar>
#include <QAction>
#include <QThread>

#if _MSC_VER >= 1600
#pragma execution_character_set("utf-8")
#endif

void MainWindow::mw_tableInit(void)
{
    // 初始化组和子组的下拉框
    this->ui->comboBox_icdSubGroup->addItems(this->m_APP_Icd->comboBox_subGroupInfo.value(this->ui->comboBox_icdGroup->currentIndex()));
    // 填充数据
    for (int row = 0; row < 16; ++row) {
        for (int col = 0; col < 16; ++col) {
//            int index = row * 16 + col;  // 计算一维数组索引
            QTableWidgetItem *item = new QTableWidgetItem(QString::number(this->m_APP_Icd->DAC256_10bit_data[row][col]));
            this->ui->tableWidget_volInput->setItem(row, col, item);
        }
    }
    // 在窗口构造函数中连接信号:当输入数据发生变化时，自动链接
    connect(this->ui->tableWidget_volInput, &QTableWidget::cellChanged, this, &MainWindow::mw_onCellChanged);
}

// 表格中的数据有变化时，触发该函数
void MainWindow::mw_onCellChanged(int row, int column) {
    uint8_t i = 0;
    uint8_t j = 0;

    QTableWidgetItem *item = this->ui->tableWidget_volInput->item(row, column);
    if (item) {
        bool ok;
        // 转换数据
        int newValue = item->text().toInt(&ok);
        if(!ok || (newValue > 1023)){
            /* 错误输入，设置为原来的值 */
            // 设置为原来的值
            QTableWidgetItem *item = new QTableWidgetItem(QString::number(this->m_APP_Icd->DAC256_10bit_data[row][column]));
            this->ui->tableWidget_volInput->setItem(row, column, item);
            // 提示警告
            QMessageBox::question(this,"错误","请输入0-1023的数字!",QMessageBox::Yes | QMessageBox::No,QMessageBox::Yes);
            return;
        }
        qDebug() << "Cell at (" << row << "," << column << ") changed to:" << newValue;
        // 设置DAC256 10bit数组的值
        if(!this->m_APP_Icd->ICD_setDAC256Data10bit(row, column, newValue)){
            qDebug() << "set newvalue:" << newValue << "failed!";
            return;
        }
        /* 如果是同值配置，则让页面和DAC256Data10bit数组的值赋值为同一个值*/
        if(this->ui->comboBox_icdCmd->currentIndex() == 1){
            for(i = 0; i < 16; i++){
                for(j = 0; j < 16; j++){
                    // 防止多次进入该程序
                    if(this->ui->tableWidget_volInput->item(i, j)->text().toInt() != newValue){
                        // 表格中显示输入的值
                        this->ui->tableWidget_volInput->item(i, j)->setText(QString::number(newValue));
                        // 设置DAC256_10bit_data数组中的值为输入的值
                        this->m_APP_Icd->ICD_setDAC256Data10bit(i, j, newValue);
                    }
                }
            }
        }
    }
}

void MainWindow::mw_showVersionInfo() {
    QMessageBox::information(
        this,
        tr("版本信息"),
        tr("上位机版本：%1\n").arg(VERSION) +
        tr("修改时间:%1\n").arg(MOD_TIME) +
        tr("ICD协议版本:%1\n").arg(ICD_VERSION)+
        tr("作者：罗林赖生\n")
        );
}

void MainWindow::mw_showUserManual() {
    QMessageBox::information(
        this,
        tr("使用说明"),
        tr("1. 打开设备:点击刷新设备列表,搜索串口/SPI设备,选择设备后，点击打开设备\n") +
        tr("2. 配置通信:配置串口/SPI通信协议相关的参数，点击初始化SPI/串口参数配置\n") +
        tr("3. 寄存器配置和电压配置(以下操作并非都需操作，视情况配置):\n") +
        tr("3.1 寄存器配置：\n") +
        tr("在寄存器配置以及回读区配置相关的属性后，点击寄存器配置按钮进行配置，如需查看是否配置成功，配置完后等待一秒，点击寄存器回读按钮，寄存器值将显示至文本框\n") +
        tr("3.2 电压配置:\n") +
        tr("3.2.1 命令选择:选择需要配置的方式 \n") +
        tr("3.2.2 分组和子分组选择:选择需要配置的分组和子分组，注:当命令选择异值配置时，分组只能选择单个DAC! \n") +
        tr("3.2.3 输入电压：在16X16的表格内输入所需要配置的电压对应的数字量，范围为0-1023，通道数按照从左到右，从上到下依次排布,注：当命令选择同值配置时，只需输入一个电压值，按回车后自动填充所有的数据  \n")+
        tr("3.2.4 设置电压：点击发送电压命令按钮，将把电压相关数据发送至下位机，此时日志输出窗口将输出相关日志信息  \n")
        );
}

// 菜单栏初始化
void MainWindow::mw_menuBarInit(void) {

    // 获取主窗口的菜单栏
    QMenuBar *menuBar = this->menuBar();

    // 1. 添加"主菜单"菜单
    QMenu *mainMenu = menuBar->addMenu(tr("菜单(&M)")); // &H 表示快捷键 Alt+H

    // 2. 添加"帮助"菜单（包含"版本信息"和"使用说明"）
    QMenu *helpMenu = menuBar->addMenu(tr("帮助(&H)")); // &H 表示快捷键 Alt+H

    // 1.1 添加"版本信息"动作
    QAction *versionAction = new QAction(tr("版本信息(&V)"), this);
    helpMenu->addAction(versionAction);
    connect(versionAction, &QAction::triggered, this, &MainWindow::mw_showVersionInfo);

    // 1.2 添加"使用说明"动作
    QAction *manualAction = new QAction(tr("使用说明(&M)"), this);
    helpMenu->addAction(manualAction);
    connect(manualAction, &QAction::triggered, this, &MainWindow::mw_showUserManual);
}

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    // 设置程序标题
    this->setWindowTitle(QString(tr("SP713控制软件 使用说明打开帮助->使用说明")).arg(VERSION).arg(MOD_TIME));
    // // 初始化日志处理器并绑定UI
    LogHandler::log_init(ui->plainTextEdit_logOutput);

    // 连接日志信号到UI更新
    connect(LogHandler::log_instance(),  &LogHandler::log_messageLogged,
            ui->plainTextEdit_logOutput, &QPlainTextEdit::appendPlainText,
            Qt::QueuedConnection);  // 确保跨线程安全
    // 例化DRV_Spi对象
    this->m_DRV_Spi = new DRV_Spi(this);
    // 查找Spi设备
    this->mw_findSpiDev();

    // 例化APP_ICD类
    this->m_APP_Icd = new APP_Icd(this);
    // 初始化
    this->m_APP_Icd->ICD_init();
    // 表格初始化：一定要在APP_ICD类初始化后！！！！
    this->mw_tableInit();
    // 初始化寄存器配置中DAC通道值
    for(int i = 0; i <= 256; i++)
    {
        this->ui->comboBox_icdDacCh->addItem(QString::number(i));
    }
    // 菜单栏初始化
    this->mw_menuBarInit();
    // 查找串口设备
    this->ui->pushButton_uartRefreshDev->click();
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::mw_findSpiDev(void)
{
    // 清空设备列表
    this->ui->comboBox_spiDevList->clear();
    // 枚举Spi设备
    if(this->m_DRV_Spi->spi_enumDevice()){
        this->ui->comboBox_spiDevList->addItem(this->m_DRV_Spi->m_DRV_Spi_Infors.bDeviceName);
    }else{
        //QMessageBox::question(NULL,"警告","未发现设备",QMessageBox::Yes | QMessageBox::No,QMessageBox::Yes);
    }
}

// void MainWindow::mw_findSpiDev(void)
// {
//     // 清除相关的变量
//     this->devices.clear();
//     this->ui->comboBox_spiDevList->clear();
//     // 获取 CH347 设备列表
//     try {
//         auto devList = this->spiApi.initUsbDevice();
//         this->devices = QVector<DevSimple>::fromStdVector(devList);
//     } catch (const std::exception &e) {
//         DbgPrint("init USB device failed!");
//     }

//     if (devices.isEmpty()) {
//         DbgPrint("not find CH347 device!");
//     }

//     /***********************输出设备信息****************************/

//     if(devices.length() != 0) {
//         DbgPrint("Find %d CH347 devices!", devices.length());

//         for(int i = 0; i < devices.length(); i++){
//             DbgPrint("Manufacturer:%s Product:%s.", devices[i].ManufacturerString, devices[i].ProductString);
//             this->ui->comboBox_spiDevList->addItem(devices[i].ProductString);
//         }
//     }
// }

// void MainWindow::mw_sendTestData(void)
// {
//     /***********************配置参数（示例：设置 DAC 组的异值电压）****************************/
//     SetCommandArg cmdArg;
//     cmdArg.cmd_ = SetCommandArg::SP_CMD_DIF_VALUE;
//     cmdArg.group_ = SetCommandArg::DAC;
//     cmdArg.childGroup_ = 1;  // 操作编号为 1 的 DAC

//     SetVotegeArg voltageArg;
//     for (int i = 0; i < 256; ++i) {
// //        voltageArg.votes_.push_back(i);  // 填充 256 个电压值（0-255）
//          voltageArg.votes_.push_back(1);  // 填充 256 个电压值（0-255）
//     }

//     this->spiApi.debug();

//     // 下发参数到第一个设备
//     bool success = spiApi.applyArg(devices[0], cmdArg, voltageArg);
//     if (success) {
//         DbgPrint("Parameters applied successfully!");
//     } else {
//         DbgPrint("Failed to apply parameters!");
//     }
// }

// 刷新设备回调函数
void MainWindow::on_pushButton_refreshDev_clicked()
{
    // 查找Spi设备
    this->mw_findSpiDev();
}

// 关闭设备回调函数
void MainWindow::on_pushButton_closeDev_clicked()
{
    // // 关闭设备
    // if(!this->m_DRV_Spi->spi_closeDevice()){
    //     // QMessageBox::question(NULL,"错误","关闭设备失败！",QMessageBox::Yes | QMessageBox::No,QMessageBox::Yes);
    // }
    // this->mw_sendTestData();
}

// 打开设备回调函数
void MainWindow::on_pushButton_openDev_clicked()
{
    // // 打开设备
    // if(!this->m_DRV_Spi->spi_openDevice(this->ui->comboBox_spiDevList->currentIndex())){
    //     // QMessageBox::question(NULL,"错误","打开设备失败！",QMessageBox::Yes | QMessageBox::No,QMessageBox::Yes);
    // }
}

// 查找串口设备
void MainWindow::on_pushButton_uartRefreshDev_clicked()
{
    // 清空comboBox_uartDevList
    if(this->ui->comboBox_uartDevList->count())
        this->ui->comboBox_uartDevList->clear();
    // 刷新UART设备
    if(this->m_APP_Icd->m_uartDriver->Uart_enumDevice()){
        // 将串口设备的名称添加至列表中
        for(int i = 0; i < this->m_APP_Icd->m_uartDriver->m_DRV_Uart_Infors.ulDevCnt; i++)
            this->ui->comboBox_uartDevList->addItem(this->m_APP_Icd->m_uartDriver->m_DRV_Uart_Infors.bDeviceName[i]);
    }else{
        QMessageBox::question(this,"提示","没有发现串口设备!",QMessageBox::Yes | QMessageBox::No,QMessageBox::Yes);
    }
}

// 打开串口设备
void MainWindow::on_pushButton_uartOpenDev_clicked()
{
    // 读取当前的设备索引号
    ULONG index = this->ui->comboBox_uartDevList->currentIndex();
    // 调用串口打开函数
    BOOL  status = this->m_APP_Icd->m_uartDriver->Uart_openDevice(index);

    // 判断打开串口设备是否成功
    if(status == TRUE){
        // 打开成功. 则关闭或开启一些组件
        this->ui->comboBox_uartDevList->setDisabled(true);
        this->ui->pushButton_uartCloseDev->setEnabled(true);
        this->ui->pushButton_uartOpenDev->setDisabled(true);
        this->ui->pushButton_uartSetPara->setEnabled(true);
        // 新建数据记录日志txt文件
        if(!this->m_APP_Icd->ICD_newDataRecordingFile()){
            QMessageBox::question(this,"错误","新建通信记录文件失败!",QMessageBox::Yes | QMessageBox::No,QMessageBox::Yes);
        }
        // 配置默认的串口配置
        this->ui->pushButton_uartSetPara->click();
    }
}
//  关闭串口函数
void MainWindow::on_pushButton_uartCloseDev_clicked()
{
    // 调用串口关闭函数
    BOOL  status = this->m_APP_Icd->m_uartDriver->Uart_closeDevice();

    // 判断打开串口设备是否成功
    if(status == TRUE){
        // 打开成功. 则关闭或开启一些组件
        this->ui->comboBox_uartDevList->setEnabled(true);
        this->ui->pushButton_uartCloseDev->setDisabled(true);
        this->ui->pushButton_uartOpenDev->setEnabled(true);
        this->ui->pushButton_uartSetPara->setDisabled(true);
    }
}

// 串口设置参数函数
void MainWindow::on_pushButton_uartSetPara_clicked()
{
    // 读取组件中配置参数的值
    ULONG Baudrate  = this->ui->comboBox_uartBps->currentText().toUInt();
    UCHAR StopBits  = this->ui->comboBox_uartStop->currentIndex();
    UCHAR Parity    = this->ui->comboBox_uartVerify->currentIndex();
    UCHAR DataSize  = this->ui->comboBox_uartData->currentText().toUInt();
    UCHAR Timeout   = this->ui->lineEdit_uartTimeOut->text().toUInt();
    // 调用配置参数函数进行配置
    if(this->m_APP_Icd->m_uartDriver->Uart_setPara(Baudrate, StopBits, Parity, DataSize, Timeout) == FALSE){
        QMessageBox::question(this,"错误","设置串口参数失败!",QMessageBox::Yes | QMessageBox::No,QMessageBox::Yes);
    }
}

// 当分组的序号发生变化时
void MainWindow::on_comboBox_icdGroup_currentIndexChanged(int index)
{
    // 清除子分组的列表
    this->ui->comboBox_icdSubGroup->clear();
    // 设置子分组对应的列表
    this->ui->comboBox_icdSubGroup->addItems(this->m_APP_Icd->comboBox_subGroupInfo.value(index));
}

// 发送设置电压相关命令
void MainWindow::on_pushButton_icdSendVolCMD_clicked()
{
    // 获取页面的命令、分组、子分组
    uint8_t CMD     = this->ui->comboBox_icdCmd->currentIndex() + 1;
    uint8_t group   = this->ui->comboBox_icdGroup->currentIndex();
    if(group == 0)
        group = 0xAA;
    uint8_t subGroup   = this->ui->comboBox_icdSubGroup->currentIndex();
    if((subGroup == 0) && (group == 0xAA))
        subGroup = 0xAA;
    else
        subGroup += 1;
    // 调用设置电压命令编码函数
    this->m_APP_Icd->ICD_volCMDProtoEncode(CMD, group, subGroup);
}

// 写寄存器配置指令
void MainWindow::on_pushButton_icdRegConfig_clicked()
{
    // 读取dac的编号值
    uint8_t dacID = this->ui->comboBox_icdDacId->currentIndex()+1;
    // 读取dac通道值
    uint16_t dacCH = this->ui->comboBox_icdDacCh->currentIndex();
    // 判断是否为第256通道
    if(dacCH == 256){
        dacCH = 0;
        dacID += 128;
    }
    // 读取funcEN值，将各个选项的使能值按照协议的报文格式叠加到funcEN数据中
    uint8_t funcEN = 0x00;
    if(this->ui->checkBox_icdEN_TADC->isChecked()){
        funcEN += 1;
    }
    if(this->ui->checkBox_icdFBK_EN->isChecked()){
        funcEN += 2;
    }
    if(this->ui->checkBox_icdTEMPTEST->isChecked()){
        funcEN += 4;
    }
    if(this->ui->checkBox_icdTEST_EN->isChecked()){
        funcEN += 8;
    }
    if(this->ui->checkBox_icdTRIG_TADC->isChecked()){
        funcEN += 16;
    }
    // 读取adcCurrConfig值
    uint8_t adcCurrConfig = this->ui->comboBox_icdRefCurr->currentIndex();
    adcCurrConfig = adcCurrConfig*16 + this->ui->comboBox_icdADCClkPrs->currentIndex();

    // 调用写寄存器编码函数
    if(!this->m_APP_Icd->ICD_regWCMDProtoEncode(dacID, dacCH, funcEN, adcCurrConfig)){
        QMessageBox::question(this,"错误","设置寄存器失败!",QMessageBox::Yes | QMessageBox::No,QMessageBox::Yes);
    }
}

// 寄存器回读命令
void MainWindow::on_pushButton_icdRegRead_clicked()
{
    // 清楚
    this->revData.clear();
    // 读取dac的编号值
    uint8_t dacID = this->ui->comboBox_icdDacId->currentIndex()+1;
    // 读取寄存器的值
    if(!this->m_APP_Icd->ICD_regRCMDProtoEncode(dacID)){
        QMessageBox::question(this,"错误","回读寄存器失败!",QMessageBox::Yes | QMessageBox::No,QMessageBox::Yes);
    }
    // 读取串口接收区的数据
    QThread::msleep(50); // 延时10毫秒
    if(!this->m_APP_Icd->m_uartDriver->Uart_Read(this->revData)){
        QMessageBox::question(this,"错误","串口返回数据失败!",QMessageBox::Yes | QMessageBox::No,QMessageBox::Yes);
    }
    // 将返回的寄存器值显示到label界面
    this->ui->label_icdRegRead->setText(this->revData.toHex(' ')); // 用空格分隔每个字节
    // 记录读的数据
    this->m_APP_Icd->ICD_addContextToDataRecordingFile(false, this->revData);
    // 解析数据
    this->regParsedData = this->m_APP_Icd->ICD_parseRegisterData(this->revData);
    qDebug() << "CH_TEST:" << this->regParsedData.CH_TEST                                                    \
             << ",EN_TADC:" << this->regParsedData.EN_TADC                                                   \
             << ",FBK_EN:" << this->regParsedData.FBK_EN                                                     \
             << ",TEMPTEST_EN:" << this->regParsedData.TEMPTEST_EN                                           \
             << ",TEST_EN:" << this->regParsedData.TEST_TADC                                                 \
             << ",TRIG_TADC:" << this->regParsedData.TRIG_TADC                                               \
             << ",N_CLKDIV18:" << QString::number(this->regParsedData.N_CLKDIV18, 2).rightJustified(2, '0')  \
             << ",ICON18:" << QString::number(this->regParsedData.ICON18, 2).rightJustified(4, '0')          \
             << ",VCON:" << QString::number(this->regParsedData.VCON, 2).rightJustified(2, '0')              \
             << ",EOC:" << this->regParsedData.EOC                                                           \
             << ",ADC_OUT:" << this->regParsedData.ADC_OUT                                                   \
             << ",D_FB:" << this->regParsedData.D_FB;
    // 添加记录至txt文件
    this->m_APP_Icd->ICD_addContextToVolRecordingFile(this->regParsedData.EOC, this->regParsedData.CH_TEST, this->regParsedData.ADC_OUT);
}

// 一键回读当前电压值
void MainWindow::on_pushButton_icdReadCurrVol_clicked()
{
    uint16_t ch_index = 1;
    // 新建回读电压txt文件
    if(!this->m_APP_Icd->ICD_newVolRecordingFile(this->ui->comboBox_icdDacId->currentIndex()+1)){
        QMessageBox::question(this,"错误","新建回读电压记录文件失败!",QMessageBox::Yes | QMessageBox::No,QMessageBox::Yes);
    }

    // 设置寄存器的DAC编号为当前设置电压的DAC编号
    // this->ui->comboBox_icdDacId->setCurrentIndex();

    // 从1至256通道依次读取电压值
    for(ch_index = 1; ch_index <= 256; ch_index++)
    {
        // 设置配置项
        this->ui->comboBox_icdDacCh->setCurrentIndex(0);                // 设置通道值为全0
        this->ui->checkBox_icdTRIG_TADC->setCheckState(Qt::Unchecked);  // 关闭TADC
        this->ui->pushButton_icdRegConfig->click();                     // 触发配置寄存器按钮
        QThread::msleep(50); // 延时50毫秒
        this->ui->checkBox_icdTRIG_TADC->setCheckState(Qt::Checked);    // 开启TADC
        this->ui->comboBox_icdDacCh->setCurrentIndex(ch_index);         //设置当前通道
        this->ui->pushButton_icdRegConfig->click();                     // 触发配置寄存器按钮
        QThread::msleep(50); // 延时50毫秒
        this->ui->pushButton_icdRegConfig->click();                     // 再次触发配置寄存器按钮
        QThread::msleep(50); // 延时50毫秒
        this->ui->pushButton_icdRegRead->click();                     // 读取寄存器值
        QThread::msleep(50); // 延时50毫秒
    }
    // 清空电压记录文件的名称
    this->m_APP_Icd->volRecordingFile.clear();
    this->ui->comboBox_icdDacCh->setCurrentIndex(0);                // 设置通道值为全0
    this->ui->checkBox_icdTRIG_TADC->setCheckState(Qt::Unchecked);  // 关闭TADC
    this->ui->pushButton_icdRegConfig->click();                     // 触发配置寄存器按钮
    QThread::msleep(50); // 延时50毫秒
    QMessageBox::question(this,"成功","成功读取该DAC下的所有的电压值！",QMessageBox::Yes | QMessageBox::No,QMessageBox::Yes);
}

