#include <qmessagebox.h>

#include "logger/logger.h"
#include "lowesssmoother.h"
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "global.h"
#include "serialport.h"
#include "dataparser.h"
#include "filemanager.h"
#include "logger.h"
#include "xlsxhandler.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent),
      ui(new Ui::MainWindow),
      _centralWidget(new CentralWidget(this)),
      _leftWidget(new LeftWidget(this)),
      _expertmentSettingForm(new ExperimentSettingForm(this)),
      _realTimeDataForm(new RealTimeDataForm(this)),
      _rightWidget(new QDockWidget(this)),
      _analysisSettingWidget(new AnalysisSettingForm(this)),
      _contextMenu(new QMenu(this)),
      _specificHeatComparisonMethodForm(new SpecificHeatComparisonMethodForm(this)),
      _instrumentCoefficientForm(new InstrumentCoefficientForm(this)),
      _degreeOfCureForm(new DegreeOfCureForm(this)),
      _OITAutoAnalysisParamForm(new OITAutoAnalysisParamForm(this)),
      _degreeOfCrystallinityForm(new DegreeOfCrystallinityForm(this)),
      _aboutForm(new AboutForm(this)),
      _enthalpyDataCorrectionForm(new EnthalpyDataCorrectionForm(this)),
      _coefficientSelectionForm(new CoefficientSelectionForm(this)),
      _printPreviewForm(new PrintPreviewForm(this)),
      _axisSettingForm(new AxisSettingForm(this)),
      _manuallyStopTheExperimentFlag(false) {
    ui->setupUi(this);
    ui->actionOITAutoAnalysisMode->setVisible(false);
    ui->toolBar->setWindowTitle("工具栏");

    this->setToolTip(".....");

    ui->actionSaveas->setVisible(false);
    // 隐藏仪器系数设置窗口。
    ui->actionInstrumentParameter->setVisible(false);

    setCentralWidget(_centralWidget);
    addDockWidget(Qt::LeftDockWidgetArea, _leftWidget);
    addDockWidget(Qt::RightDockWidgetArea, _rightWidget);

    _rightWidget->setWindowTitle("分析设置");
    _rightWidget->setWidget(_analysisSettingWidget);
    _rightWidget->hide();

    //
    ui->statusbar->showMessage("showMessage show temp message!");

    // permenent show
    QLabel *permenentLabel = new QLabel(this);
    permenentLabel->setText("Software Ver:" + qApp->applicationVersion());
    ui->statusbar->addPermanentWidget(permenentLabel);

    ui->actionTimeAxisAnalysisPCTMode->setCheckable(true);

    //
    setSubWidgetAttribute(_expertmentSettingForm);
    setSubWidgetAttribute(_specificHeatComparisonMethodForm);
    setSubWidgetAttribute(_realTimeDataForm);
    setSubWidgetAttribute(_degreeOfCureForm);
    setSubWidgetAttribute(_instrumentCoefficientForm);
    setSubWidgetAttribute(_OITAutoAnalysisParamForm);
    setSubWidgetAttribute(_degreeOfCrystallinityForm);
    setSubWidgetAttribute(_aboutForm);
    setSubWidgetAttribute(_enthalpyDataCorrectionForm);
    setSubWidgetAttribute(_coefficientSelectionForm);
    setSubWidgetAttribute(_printPreviewForm);
    setSubWidgetAttribute(_axisSettingForm);

    //
    setActionEnable(true);

    _eventHandler = _centralWidget->getEvnetHandler();
    //
    connections();
    //
    //    ui->actionStop->setEnabled(false);
}

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

void MainWindow::slotContextMenuShow(const QPoint point) {
    _contextMenu->exec(point);
}

void MainWindow::slotUpdateStatusbarMsg(const QString msg) {
    ui->statusbar->showMessage(msg);
}

void MainWindow::slotOITAutoAnalysis(const double x1, const double x2) {
    on_actionStop_triggered();
    _centralWidget->setAnalysisMode(CentralWidget::AnalysisMode::OIT);
    _centralWidget->setVerticalLineRange(x1, x2);
}

void MainWindow::slotStartExperiment() {
    startExperimentByDeviceInfo();
}

void MainWindow::closeEvent(QCloseEvent *event) {
    // 弹出确认对话框
    QMessageBox::StandardButton reply;
    reply = QMessageBox::question(this, "确认退出", "你确定要退出吗？",
                                  QMessageBox::Yes | QMessageBox::No);
    if (reply == QMessageBox::Yes) {
        event->accept();    // 接受关闭事件，关闭窗口
    } else {
        event->ignore();    // 忽略关闭事件，不关闭窗口
    }
}

void MainWindow::connections() {
    // ui
    connect(_expertmentSettingForm, &ExperimentSettingForm::sigDeliverData,
            SerialPort::instance(), &SerialPort::slotDeliverData);
#if 1
    // SerialPort.
    connect(SerialPort::instance(), &SerialPort::sigSendCommonData,
            _centralWidget, &CentralWidget::slotRecvCommonData);
    connect(SerialPort::instance(), &SerialPort::sigSendCommonData,
            _realTimeDataForm, &RealTimeDataForm::slotRevCommonData);

    connect(SerialPort::instance(), &SerialPort::sigSendCommonDataToRealDataForm,
            _realTimeDataForm, &RealTimeDataForm::slotRevCommonData);

    connect(SerialPort::instance(), &SerialPort::sigSendPhaseInfo,
            _expertmentSettingForm, &ExperimentSettingForm::slotRecvPhaseInfo);

    connect(SerialPort::instance(), &SerialPort::sigAxisModify,
            _centralWidget, &CentralWidget::slotAxisModify);

    connect(SerialPort::instance(), &SerialPort::sigUpdateStatusbarMsg,
            this, &MainWindow::slotUpdateStatusbarMsg);

    connect(SerialPort::instance(), &SerialPort::sigSaveExperimentalDataMsgBox,
            this, &MainWindow::slotSaveExperimentalDataMsgBox);

    connect(SerialPort::instance(), &SerialPort::sigStartExperiment,
            this, &MainWindow::slotStartExperiment);

    connect(SerialPort::instance(), &SerialPort::sigDeviceDisconnected,
            this, &MainWindow::slotDeviceDisconnected);
#endif

    // mode

    //    connect(Global::instance(), &Global::sigModeModify,
    //            _centralWidget, &CentralWidget::slotModeModify);

    // analysis
    connect(_leftWidget, &LeftWidget::sigSendAnalysisFileName,
            _centralWidget, &CentralWidget::slotRecvAnalysisFileName);
    connect(_centralWidget, &CentralWidget::sigSendLineXCoord,
            _analysisSettingWidget, &AnalysisSettingForm::slotRecvLineXCoord);

    connect(_analysisSettingWidget, &AnalysisSettingForm::sigApply,
            _centralWidget, &CentralWidget::slotAnalysisSettingApply);
    connect(_analysisSettingWidget, &AnalysisSettingForm::sigUndo,
            _centralWidget, &CentralWidget::slotAnalysisSettingUndo);
    connect(_analysisSettingWidget, &AnalysisSettingForm::sigConfirm,
            _centralWidget, &CentralWidget::slotAnalysisSettingConfirm);
    connect(_analysisSettingWidget, &AnalysisSettingForm::sigCancel,
            _centralWidget, &CentralWidget::slotAnalysisSettingCancel);

    connect(_centralWidget, &CentralWidget::sigRightDockWidgetHide,
            [&]() { _rightWidget->hide(); });

    connect(_degreeOfCrystallinityForm, &DegreeOfCrystallinityForm::sigDrawCustomText,
            _centralWidget, &CentralWidget::slotDrawCustomText);
    connect(_specificHeatComparisonMethodForm, &SpecificHeatComparisonMethodForm::sigDrawCustomText,
            _centralWidget, &CentralWidget::slotDrawCustomText);

    // SpecificHeatComparisonMethodForm
    connect(_eventHandler, &EventHandler::sigSetCurve,
            _specificHeatComparisonMethodForm,
            &SpecificHeatComparisonMethodForm::slotSetCurve);

    // Axis settings.
    connect(_axisSettingForm, &AxisSettingForm::sigGetAxisInfo,
            _centralWidget, &CentralWidget::slotGetAxisInfo);
    connect(_centralWidget, &CentralWidget::sigGetAxisInfoWithData,
            _axisSettingForm, &AxisSettingForm::slotGetAxisInfoWithData);
    connect(_axisSettingForm, &AxisSettingForm::sigSetAxisSettings,
            _centralWidget, &CentralWidget::slotSetAxisSettings);
    // OIT
    connect(OITAutoAnalysis::getInstance(), &OITAutoAnalysis::sigExperimentStop,
            this, &MainWindow::slotOITAutoAnalysis);
}

void MainWindow::setActionEnable(const bool flag) {
    if (flag) {
        ui->actionNew->setEnabled(true);
        ui->actionStart->setEnabled(true);
        ui->actionStop->setEnabled(true);
        ui->actionRealTimeWidget->setEnabled(true);
    } else {
        ui->actionNew->setEnabled(false);
        ui->actionStart->setEnabled(false);
        ui->actionStop->setEnabled(false);
        ui->actionRealTimeWidget->setEnabled(false);
    }
}

void MainWindow::setSubWidgetAttribute(QWidget *widget) {
    widget->setWindowModality(Qt::ApplicationModal);
    widget->setWindowFlags(Qt::Dialog);

    widget->setFixedSize(widget->geometry().width(), widget->geometry().height());
}

#if 0
bool MainWindow::saveExperimentFile(const QString fileName)
{
    QString localFileName = fileName;
    if(fileName.isEmpty()){
        localFileName = "new";
    }
    QString xlsxfilePath = Global::SampleDataFloder + "/" + localFileName + ".xlsx";
    QString filePath = QFileDialog::getSaveFileName(nullptr, "Save experiment file",
                                                    xlsxfilePath, "Excel Files (*.xlsx)");
    logde<<"filePath:"<<filePath.toStdString();

    if (filePath.isEmpty()) {
        qDebug() << "User cancel the operation.";
        return false;
    }

    XlsxHandler::writeFile(filePath);

    return true;
}

bool MainWindow::saveAnalysisFile(const QString fileName)
{
    QString localFileName = fileName;
    if(fileName.isEmpty()){
        localFileName = "new";
    }
    QString xlsxfilePath = Global::AnalysisStateFolder + "/" + localFileName + ".xlsx";
    QString filePath = QFileDialog::getSaveFileName(nullptr, "Save experiment file",
                                                    xlsxfilePath, "Excel Files (*.xlsx)");
    logde<<"filePath:"<<filePath.toStdString();

    if (filePath.isEmpty()) {
        qDebug() << "User cancel the operation.";
        return false;
    }

    XlsxHandler::writeAnalysisOperation(filePath);

    return true;
}
#endif

bool MainWindow::saveFile(const QString fileName, const Global::Mode mode,
                          QString &finalFileName, const bool autoSaveFlag) {
    logde << "save file...";

    QString localFileName = fileName;
    if (fileName.isEmpty()) {
        localFileName = "new";
    }

    QString folder;
    if (mode == Global::Mode::None) {
        folder = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation);
    } else if (mode == Global::Mode::Analysis) {
        folder = Global::AnalysisStateFolder;
    } else if (mode == Global::Mode::Experiment) {
        folder = Global::SampleDataFloder;
    }

    QString filePath;
    if (autoSaveFlag) {
        localFileName = _leftWidget->filePathCheck(fileName, folder);
        filePath      = folder + "/" + localFileName + ".xlsx";
    } else {
        QString xlsxfilePath = folder + "/" + localFileName + ".xlsx";
        filePath             = QFileDialog::getSaveFileName(nullptr, "Save experiment file",
                                                            xlsxfilePath, "Excel Files (*.xlsx)");
    }
    //
    finalFileName = localFileName + ".xlsx";

    logde << "filePath:" << filePath.toStdString();

    if (filePath.isEmpty()) {
        qDebug() << "User cancel the operation.";
        return false;
    }

    // Save file.
    if (mode == Global::Mode::Analysis) {
        if (Global::_curveFileDataVtr.empty()) {
            // 分析模式下，但是文件数据为空，说明做完实验没有保存数据。
            XlsxHandler::writeExperimentFile(filePath);
        } else {
            // 分析模式下，存在文件数据，将文件数据写入文件。
            XlsxHandler::writeXlsxFile(filePath);
#if 0
            // 分析模式下，直接保存从文件读取来的数据。
            if(Global::_smoothnessFlag){
                XlsxHandler::writeSmoothnessFile(filePath);
            }else{
                // 直接在xlsx文件的基础上添加分析数据。
                XlsxHandler::xlsxFileAppendAnalysisOperation(filePath);
            }
#endif
        }
    } else if (mode == Global::Mode::Experiment) {
        XlsxHandler::writeExperimentFile(filePath);
    }

    return true;
}

void MainWindow::smoothness(const int level) {
    logde << "smoothness...";
    slotUpdateStatusbarMsg("数据平滑计算中...");

    if (!Global::_curveExperimentDataVtr.empty()) {
        // 当前数据为实验数据时，需要把所有的当前实验数据都进行平滑处理。

        // 删除所有objectName为experiment的curve.
        _centralWidget->deleteCurveByObjectName(Global::ObjectNameExperiemnt);
        // 添加所有平滑后的curve.
        for (auto &item : Global::_curveExperimentDataVtr) {
            item.smoothDataVtr = smoothnessDetail(level, item.dataVtr);
            item.curve         = _centralWidget->addCurveData(item.smoothDataVtr,
                                                              Global::ObjectNameExperiemnt);
        }
    } else {
        // 当前数据为文件分析数据时，需要把当前文件下的所有数据都进行平滑处理。
        QString selectedCurveObjectName = _centralWidget->getCurrentCurve()->objectName();
        _centralWidget->deleteCurveByObjectName(selectedCurveObjectName);

        for (Global::CurveFileData &cfd : Global::_curveFileDataVtr) {
            if (selectedCurveObjectName.contains(cfd.filePath)) {
                for (Global::PhaseTotalInfo &pti : cfd.phaseTotalVtr) {
                    pti.smoothDataVtr = smoothnessDetail(level, pti.dataVtr);
                    pti.curve         = _centralWidget->addCurveData(pti.smoothDataVtr,
                                                                     cfd.filePath);
                }
            }
        }
    }
}

QVector<Global::ExperimentData> MainWindow::smoothnessDetail(const int level, const QVector<Global::ExperimentData> &dataVtr) {
    Lowess::Config config;
    config.smoothingFactor      = level * 0.01;
    config.robustnessIterations = 3;

    std::vector<double> x;
    std::vector<double> y;

    for (const Global::ExperimentData &ed : dataVtr) {
        if (Global::_axisMode == Global::AxisMode::SingleY) {
            x.push_back(ed.sampleTemp);
        } else {
            x.push_back(ed.runTime);
        }

        y.push_back(ed.dsc);
    }

    slotUpdateStatusbarMsg("数据平滑计算中...");

    QVector<Global::ExperimentData> resultVtr;
    logde << "smooth start...";
    logde << "x,y size:" << x.size() << "," << y.size();

    ui->statusbar->showMessage("数据平滑计算中...");
    ui->statusbar->showMessage("数据平滑计算中...");
    ui->statusbar->showMessage("数据平滑计算中...");
    ui->statusbar->showMessage("数据平滑计算中...");

    std::vector<double> yest = Lowess::smooth(x, y, config);
    if (yest.empty()) {
        slotUpdateStatusbarMsg("数据平滑完成.");
        return resultVtr;
    }

    slotUpdateStatusbarMsg("数据平滑完成.");

    logde << "smooth end...";

    // result data vector.

    for (int i = 0; i < x.size(); i++) {
        Global::ExperimentData ed;
        if (Global::_axisMode == Global::AxisMode::SingleY) {
            ed.sampleTemp = x.at(i);
            ed.runTime    = dataVtr.at(i).runTime;
        } else {
            ed.runTime    = x.at(i);
            ed.sampleTemp = dataVtr.at(i).sampleTemp;
        }

        ed.dsc              = yest.at(i);
        ed.constantTempTime = dataVtr.at(i).constantTempTime;

        resultVtr.push_back(ed);
    }

    return resultVtr;
}

void MainWindow::smoothnessExperimentData(const int level) {
#if 0
    for(int i = 0;i < Global::_curveExperimentDataVtr.size();i++){
        Global::CurveExperimentData ced = Global::_curveExperimentDataVtr.at(i);
        smoothnessDetail()
    }
#endif

    for (auto &item : Global::_curveExperimentDataVtr) {
        smoothnessDetail(level, item.dataVtr);
    }
}

void MainWindow::startExperiment() {
    QByteArray ba = DataParser::setDeviceStartStop(DeviceStartMode::Start);

    QString hexData = ba.toHex(' ');

    SerialPort::instance()->slotSendData(ba);

    Global::_mode                  = Global::Mode::Experiment;
    _manuallyStopTheExperimentFlag = false;
    _centralWidget->startExperiment();

    // 清除数据action变灰
    ui->actionClearAllData->setEnabled(false);
    // 分析menu变灰
    ui->menu_4->menuAction()->setEnabled(false);
}

void MainWindow::startExperimentByDeviceInfo() {
    Global::_mode                  = Global::Mode::Experiment;
    _manuallyStopTheExperimentFlag = false;
    _centralWidget->startExperiment();

    // 实验开始，清除上一个实验所有数据。
    Global::clearExperimentData();
}
// 停止实验
void MainWindow::on_actionStop_triggered() {
    logde << " Stop experiment ...++++++++++++++++++";

    if (!SerialPort::instance()->isOpen()) {
        showMesgBox("设备未连接，请先连接设备。");
        return;
    }

    if (Global::_mode == Global::Mode::Experiment) {
        QByteArray ba = DataParser::setDeviceStartStop(DeviceStartMode::Stop);
        SerialPort::instance()->slotSendData(ba);

        // Set software mode to analysis.
        _manuallyStopTheExperimentFlag = true;
        logde << "_manuallyStopTheExperimentFlag:" << _manuallyStopTheExperimentFlag;

        Global::_mode = Global::Mode::Analysis;

        // Save data.
#if 1
        logde << "on_actionStop_triggered saveFile ...";

        QString finalFileName;
        if (saveFile(Global::_experimentInfo.sampleName, Global::Mode::Experiment, finalFileName, true)) {
            _leftWidget->reloadFileName();

            QString str = QString("%1 文件保存成功。").arg(finalFileName);
            QMessageBox::information(this, "文件保存", str, QMessageBox::Yes);
        }
#endif
    }

    // 清除数据action恢复功能
    ui->actionClearAllData->setEnabled(true);
    // 分析menu恢复功能
    ui->menu_4->menuAction()->setEnabled(true);
}

void MainWindow::on_actionNew_triggered() {
    if (!SerialPort::instance()->isOpen()) {
        showMesgBox("设备未连接，请先连接设备。");
        return;
    }
    _expertmentSettingForm->show();
}

void MainWindow::on_actionStart_triggered() {
    logde << "start experiment,set soft into experiment mode.";
    logde << "```````````````````````````````";

    if (!SerialPort::instance()->isOpen()) {
        showMesgBox("设备未连接，请先连接设备。");
        return;
    }

    on_actionClearAllData_triggered();

    startExperiment();
}

void MainWindow::on_actionReadOnly_triggered() {
    Global::_mode = Global::Mode::Experiment;
    SerialPort::instance()->openSp();
}

void MainWindow::on_actionRealTimeWidget_triggered() {
    _realTimeDataForm->show();
}

void MainWindow::slotSaveExperimentalDataMsgBox() {
    logde << "_manuallyStopTheExperimentFlag:" << _manuallyStopTheExperimentFlag;

    if (_manuallyStopTheExperimentFlag) {
        logde << "_manuallyStopTheExperimentFlag...";
        return;
    }

    // auto save file.
    logde << "slotSaveExperimentalDataMsgBox saveFile ...";
    QString finalFileName;
    if (saveFile(Global::_experimentInfo.sampleName,
                 Global::Mode::Experiment,
                 finalFileName,
                 true)) {
        _leftWidget->reloadFileName();

        QString str = QString("%1 文件保存成功。").arg(finalFileName);
        QMessageBox::information(this, "文件保存", str, QMessageBox::Yes);
    }

    // 清除数据action恢复功能
    ui->actionClearAllData->setEnabled(true);
    // 分析menu恢复功能
    ui->menu_4->menuAction()->setEnabled(true);

#if 0
    QMessageBox::StandardButton reply;
    reply = QMessageBox::question(this, "数据保存提示", "是否保存实验数据？",
                                  QMessageBox::Yes | QMessageBox::No);
    if (reply == QMessageBox::Yes) {
        QString finaleFileName;

        saveFile(Global::_experimentInfo.sampleName,Global::Mode::Experiment,finaleFileName);
        _leftWidget->reloadFileName();
    } else {
        on_actionClearAllData_triggered();
    }
#endif
}

void MainWindow::on_actionConnectToDev_triggered() {
    logde << "connect to device...";

    if (SerialPort::instance()->isOpen()) {
        logde << "close device.";

        SerialPort::instance()->closeSp();

        ui->actionConnectToDev->setIcon(QIcon(":/images/connect.png"));
        ui->actionConnectToDev->setText("连接设备");

        logde << "close serial port.";
        //
        QString str("设备已断开。");
        slotUpdateStatusbarMsg(str);
        showMesgBox(str);
    } else {
        logde << "open device.";

        if (SerialPort::instance()->openSp()) {
            setActionEnable(true);
            //        Global::instance()->setMode(Global::Mode::ConnectedToDev);
            Global::_mode = Global::Mode::ConnectedToDev;

            QByteArray ba = DataParser::inquirePhaseInfo();
            SerialPort::instance()->sendData(ba);

            ui->actionConnectToDev->setIcon(QIcon(":/images/disconnect.png"));
            ui->actionConnectToDev->setText("断开连接");

            //
            QString str("设备已连接。");
            slotUpdateStatusbarMsg(str);
            showMesgBox(str);

            logde << "open serial port success. ";
        } else {
            //            QMessageBox::warning(this, "warnning", "Serial Port open failed.");
            showMesgBox("设备打开失败。");
        }
    }
}

void MainWindow::on_actionStartPoint_triggered() {
    logde << "start experiment...";

    _rightWidget->show();
    _centralWidget->setAnalysisMode(CentralWidget::AnalysisMode::StartPoint);
}

void MainWindow::on_actionStopPoint_triggered() {
    _rightWidget->show();
    _centralWidget->setAnalysisMode(CentralWidget::AnalysisMode::StopPoint);
}

void MainWindow::on_actionNumericalLabel_triggered() {
    _rightWidget->show();
    _centralWidget->setAnalysisMode(CentralWidget::AnalysisMode::NumericalLabel);
}

void MainWindow::on_actionPeakSynthesisAnalysis_triggered() {
    _rightWidget->show();
    _centralWidget->setAnalysisMode(CentralWidget::AnalysisMode::PeakSynthesisAnalysis);
}

void MainWindow::on_actionClearAllData_triggered() {
    // 实验过程中，不允许清除数据。
    if (Global::_mode == Global::Mode::Experiment) {
        return;
    }

    slotUpdateStatusbarMsg("");

    _rightWidget->hide();
    _centralWidget->clearAllData();
}

void MainWindow::on_actionGlassTransition_triggered() {
    _rightWidget->show();
    _centralWidget->setAnalysisMode(CentralWidget::AnalysisMode::GlassTransition);
}

void MainWindow::on_actionOIT_triggered() {
    _rightWidget->show();
    _centralWidget->setAnalysisMode(CentralWidget::AnalysisMode::OIT);
}

void MainWindow::on_actionSpecificHeatCompMethod_triggered() {
    _specificHeatComparisonMethodForm->show();
}

void MainWindow::on_actionDegreeOfCrystallinity_triggered() {
    //    QMessageBox::warning(this, "warnning", "结晶度.");
    _degreeOfCrystallinityForm->show();
}

void MainWindow::on_actionInstrumentParameter_triggered() {
    _instrumentCoefficientForm->show();
}


void MainWindow::on_actionOITAutoAnalysisParam_triggered() {
    _OITAutoAnalysisParamForm->show();
}

void MainWindow::on_actionOITAutoAnalysisMode_triggered() {
}

void MainWindow::on_actionTimeAxisAnalysisPCTMode_triggered() {
    Global::_displayTimeValue = ui->actionTimeAxisAnalysisPCTMode->isChecked();
}

void MainWindow::on_actionDegreeOfCuring_triggered() {
    //
    _degreeOfCureForm->show();
}

void MainWindow::on_actionAbout_triggered() {
    _aboutForm->show();
}

void MainWindow::on_actionEnthalpyCorrectionEdit_triggered() {
    _enthalpyDataCorrectionForm->show();
}

void MainWindow::on_actionEnthalpyCorrectionSelection_triggered() {
    _coefficientSelectionForm->show();
}

void MainWindow::on_actionPrintPreview_triggered() {
    logde << "print preview...";

    if (Global::_curveFileDataVtr.empty()) {
        showMesgBox("请先打开数据。");
        return;
    }

    _printPreviewForm->setPixmap(_centralWidget->getPixMap());
    // _printPreviewForm->_customPrintPreviewDialog->showMaximized();
    //    _printPreviewForm->setOrientation();

    _printPreviewForm->_customPrintPreviewDialog->exec();
    _printPreviewForm->_customPrintPreviewDialog->update();    // 可选，强制刷新
}

void MainWindow::on_actionOnsetTemperaturePoint_triggered() {
    _rightWidget->show();
    _centralWidget->setAnalysisMode(CentralWidget::AnalysisMode::OnsetTemperaturePoint);
}

void MainWindow::on_actionEndsetTemperaturePoint_triggered() {
    _rightWidget->show();
    _centralWidget->setAnalysisMode(CentralWidget::AnalysisMode::EndsetTemperaturePoint);
}

void MainWindow::on_actionYAxis_triggered() {
    _centralWidget->switchAxisMode();
}

void MainWindow::on_actionAxisSetting_triggered() {
    _axisSettingForm->show();
}

void MainWindow::on_actionSaveData_triggered() {
    QString finaleFileName;
    saveFile(Global::_experimentInfo.sampleName, Global::_mode, finaleFileName);
    _leftWidget->reloadFileName();
}

void MainWindow::on_actionSaveas_triggered() {
    QString finaleFileName;
    saveFile(Global::_experimentInfo.sampleName, Global::Mode::None, finaleFileName);
    _leftWidget->reloadFileName();
}

void MainWindow::on_actionLanguage_triggered() {
    if (Global::_languageType == Global::LanguageType::Chinese) {
        Global::_languageType = Global::LanguageType::English;
        ui->actionLanguage->setText(Global::EnglishStr);
    } else {
        Global::_languageType = Global::LanguageType::Chinese;
        ui->actionLanguage->setText(Global::ChineseStr);
    }
}

void MainWindow::on_actionSmoothness1_triggered() {
    smoothness(1);
}

void MainWindow::on_actionSmoothness2_triggered() {
    smoothness(2);
}
void MainWindow::on_actionSmoothness3_triggered() {
    smoothness(3);
}
void MainWindow::on_actionSmoothness4_triggered() {
    smoothness(4);
}
void MainWindow::on_actionSmoothness5_triggered() {
    smoothness(5);
}
void MainWindow::on_actionSmoothness6_triggered() {
    smoothness(6);
}
void MainWindow::on_actionSmoothness7_triggered() {
    smoothness(7);
}
void MainWindow::on_actionSmoothness8_triggered() {
    smoothness(8);
}
void MainWindow::on_actionSmoothness9_triggered() {
    smoothness(9);
}
void MainWindow::on_actionSmoothness10_triggered() {
    smoothness(10);
}

// 原始数据
void MainWindow::on_actionOriginalData_triggered() {
    if (!Global::_curveExperimentDataVtr.empty()) {
        // 删除所有objectName为experiment的curve.
        _centralWidget->deleteCurveByObjectName(Global::ObjectNameExperiemnt);

        for (auto &item : Global::_curveExperimentDataVtr) {
            item.smoothDataVtr.clear();
            item.curve = _centralWidget->addCurveData(item.dataVtr, Global::ObjectNameExperiemnt);
        }
    } else {
        // 当前数据为文件分析数据时，需要把当前文件下的所有数据都进行平滑处理。
        if(_centralWidget->getCurrentCurve() == nullptr){
            return;
        }

        QString selectedCurveObjectName = _centralWidget->getCurrentCurve()->objectName();
        _centralWidget->deleteCurveByObjectName(selectedCurveObjectName);

        for (Global::CurveFileData &cfd : Global::_curveFileDataVtr) {
            if (selectedCurveObjectName.contains(cfd.filePath)) {
                for (Global::PhaseTotalInfo &pti : cfd.phaseTotalVtr) {
                    pti.smoothDataVtr.clear();
                    pti.curve = _centralWidget->addCurveData(pti.dataVtr,
                                                             cfd.filePath);
                }
            }
        }
    }

#if 0
    // process data.
    QVector<Global::ExperimentData> targetDataVtr;
    QString objectName;
    QCPCurve ** curvePtrPtr;

    if(!Global::_curveExperimentDataVtr.empty()){
        for(auto & item:Global::_curveExperimentDataVtr){
            if(_centralWidget->isCurrentCurve(item.curve)){
                targetDataVtr = item.dataVtr;

                objectName = Global::ObjectNameExperiemnt;
                curvePtrPtr = &item.curve;
            }
        }
    }else{
        for(Global::CurveFileData &cfd :Global::_curveFileDataVtr){
            for(Global::PhaseTotalInfo& pti:cfd.phaseTotalVtr){
                if(_centralWidget->isCurrentCurve(pti.curve)){
                    targetDataVtr = pti.dataVtr;

                    objectName = cfd.filePath;
                    curvePtrPtr = &pti.curve;
                }
            }
        }
    }
    //
    _centralWidget->deleteCurveByObjectName(_centralWidget->getCurrentCurve()->objectName());

    _centralWidget->addCurveData(targetDataVtr,objectName);

    *curvePtrPtr = _centralWidget->getCurrentCurve();
#endif
}

void MainWindow::showMesgBox(const QString str) {
    static bool isShow = false;
    if (!isShow) {
        isShow = true;
        QMessageBox::information(this, "提示", str);
        isShow = false;
    }
}

void MainWindow::slotDeviceDisconnected() {
    //   logde<<"slotDeviceDisconnected...1";
    // 如果当前是实验模式时，需要先停止实验。
    if (SerialPort::instance()->isOpen()) {
        //      logde<<"slotDeviceDisconnected...2";
        // ui更新，断开连接
        ui->actionConnectToDev->setIcon(QIcon(":/images/connect.png"));
        ui->actionConnectToDev->setText("连接设备");
        // 停止实验
        on_actionStop_triggered();

        SerialPort::instance()->closeSp();
    }
}
