#include "MainWindow.h"
#include "ui_MainWindow.h"

#include <QDebug>
#include <QFileDialog>
#include <QDateTime>

static qint8 RESIDUAL_HALF_COUNT = 30;

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
}

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

void MainWindow::on_btnOpenClockLogFile_clicked()
{
    QString filename = QFileDialog::getOpenFileName(this, "选择日志", QDir::currentPath(), "Log File (*.log)");

    if (filename.isEmpty() == true) {
        return;
    }

    ui->labelFilename->setText(filename);
    readClockLog(filename);
}

void MainWindow::on_btnShowChart_clicked()
{
    ClockChartForm * chartFrame = new ClockChartForm();
    chartFrame->setWindowModality(Qt::NonModal);
    chartFrame->initDataChart(this->clockDataSecond);
    chartFrame->setTitleText(QString("原始数据"));
    chartFrame->show();
}

void MainWindow::on_btnResiMi_clicked()
{
    this->calcResidualMinute();

    ClockChartForm * chartFrame = new ClockChartForm();
    chartFrame->setWindowModality(Qt::NonModal);
    chartFrame->initDataChart(this->clockDataMinute);
    chartFrame->setTitleText(QString("拟合数据"));
    chartFrame->show();
}

void MainWindow::readClockLog(QString filename)
{
    QFile logFile(filename);
    logFile.open(QFile::ReadOnly);

    this->clockDataSecond.clear();

    while (!logFile.atEnd()) {
        QByteArray line = logFile.readLine();
        QStringList dataSec = QString::fromLocal8Bit(line).split(' ');

        QStringList item;
        item << QString::number(QDateTime::fromString(dataSec.at(0) + " " + dataSec.at(1), "yyyy-MM-dd HH:mm:ss.zzz").toMSecsSinceEpoch()) << dataSec.at(3);

        this->clockDataSecond.append(item);
    }
}

void MainWindow::calcResidualMinute()
{
    QVector<QString> times;
    for (int i = 0; i < this->clockDataSecond.size(); i++) {
        QString minute = QDateTime::fromMSecsSinceEpoch(((QString) this->clockDataSecond.at(i).at(0)).toULongLong()).toString("yyyy-MM-dd HH:mm");
        if (times.contains(minute) == false) {
            times.append(minute);

            qlonglong tm = ((QString) this->clockDataSecond.at(i).at(0)).toULongLong() / 1000;

            QVector<double> timeVec;
            QVector<double> dataVec;

            // 往前找N-1个数，往后找N个数
            if (i - RESIDUAL_HALF_COUNT + 1 >= 0) {
                for (int j = RESIDUAL_HALF_COUNT - 1; j > 0 ; j--)
                {
                    qlonglong tm1 = ((QString) this->clockDataSecond.at(i - j).at(0)).toULongLong() / 1000;
                    if (tm - tm1 <= RESIDUAL_HALF_COUNT) {
                        timeVec.append(tm1 - tm);
                        dataVec.append(((QString) this->clockDataSecond.at(i - j).at(1)).toDouble());
                    }
                }
            }

            if (i + RESIDUAL_HALF_COUNT + 1 < this->clockDataSecond.size()) {
                for (int j = 0; j <= RESIDUAL_HALF_COUNT ; j++)
                {
                    qlonglong tm2 = ((QString) this->clockDataSecond.at(i + j).at(0)).toULongLong() / 1000;
                    if (tm2 - tm <= RESIDUAL_HALF_COUNT) {
                        timeVec.append(tm2 - tm);
                        dataVec.append(((QString) this->clockDataSecond.at(i + j).at(1)).toDouble());
                    }
                }
            }

            LinearRegression lineReg;
            lineReg.xArray = timeVec.data();
            lineReg.yArray = dataVec.data();
            lineReg.calcLineRegParams(timeVec.size());
            double value = lineReg.slope * 0 + lineReg.intercept;

            QStringList item;
            item << QString::number(tm * 1000) << QString::number(value, 'f', 12);

            qDebug() << item;

            this->clockDataMinute.append(item);
        }
    }
}

void MainWindow::on_btnTimeFormat_clicked()
{
    QString tsStr = ui->iptTimestamp->text();
    qlonglong ts = tsStr.toLongLong();
    QDateTime dt;
    if (tsStr.length() >= 11)
    {
        dt = QDateTime::fromMSecsSinceEpoch(ts);
    } else {
        dt = QDateTime::fromSecsSinceEpoch(ts);
    }

    ui->labelDateTime->setText(dt.toString("yyyy-MM-dd HH:mm:ss.zzz"));
}
