#include "CounterSettingForm.h"
#include "ui_CounterSettingForm.h"

#include <iostream>

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

    this->setWindowFlags(Qt::FramelessWindowHint);
    resize(1020, 680);
    this->move(450, 200);

    ui->btnSetDialog->button(QDialogButtonBox::Ok)->setText("确定");
    ui->btnSetDialog->button(QDialogButtonBox::Cancel)->setText("取消");

    ui->btnChanelSetDialog->button(QDialogButtonBox::Ok)->setText("确定");
    ui->btnChanelSetDialog->button(QDialogButtonBox::Cancel)->setText("取消");

    flagGroup = new QButtonGroup();
    flagGroup->addButton(ui->radioDispA, 1);
    flagGroup->addButton(ui->radioDispB, 0);

    countGroup = new QButtonGroup();
    countGroup->addButton(ui->radioDispFour, 4);
    countGroup->addButton(ui->radioDispSix, 6);
    countGroup->addButton(ui->radioDispEight, 8);

    this->initDefaultSettings();
    this->initChannelSettingTable();
    this->clearChannelSettingValue();
}

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

void CounterSettingForm::initCounterSelect()
{
    ui->selectCounter->clear();
    ui->selectCounter->addItem("== 请选择 ==", "-1");
    QList<QString> devIds = SettingConfig::getInstance().MASTER == 1 ? ConstCache::getInstance().deviceIdLoopA : ConstCache::getInstance().deviceIdLoopB;
    for (int i = 0; i < devIds.size(); i++)
    {
        ui->selectCounter->addItem(ConstCache::getInstance().deviceMap.value(devIds.at(i))->getDeviceName(), devIds.at(i));
    }
}

int CounterSettingForm::getDisplayGroupFlag()
{
    return flagGroup->checkedId();
}

void CounterSettingForm::initDefaultSettings()
{
    ui->iptApiUrl->setText(SettingConfig::getInstance().BASE_URL);
    ui->iptLogPath->setText(SettingConfig::getInstance().BASE_LOG_PATH);

    if (flagGroup->button(SettingConfig::getInstance().MASTER) != nullptr)
    {
        flagGroup->button(SettingConfig::getInstance().MASTER)->setChecked(true);
    }
    if (countGroup->button(SettingConfig::getInstance().DISPLAY_COUNT) != nullptr)
    {
        countGroup->button(SettingConfig::getInstance().DISPLAY_COUNT)->setChecked(true);
    }
}

void CounterSettingForm::initChannelSettingTable()
{
    QGridLayout * leftLayout = new QGridLayout();
    QGridLayout * rightLayout = new QGridLayout();
    QHBoxLayout * channelTableLayout = new QHBoxLayout(ui->widgetChannel);
    ui->widgetChannel->setLayout(channelTableLayout);
    channelTableLayout->addLayout(leftLayout);
    channelTableLayout->addLayout(rightLayout);
    leftLayout->setSpacing(0);
    rightLayout->setSpacing(0);

    QLabel * headerLeftNo = new QLabel(ui->widgetChannel);
    QLabel * headerLeftActive = new QLabel(ui->widgetChannel);
    QLabel * headerLeftClock = new QLabel(ui->widgetChannel);
    QLabel * headerLeftDelay = new QLabel(ui->widgetChannel);
    headerLeftNo->setText("通道号");
    headerLeftActive->setText("是否启用");
    headerLeftClock->setText("钟编号");
    headerLeftDelay->setText("时延(ns)");
    headerLeftNo->setProperty("table", "header");
    headerLeftActive->setProperty("table", "header");
    headerLeftClock->setProperty("table", "header");
    headerLeftDelay->setProperty("table", "header");

    headerLeftActive->setMaximumSize(100, 50);
    headerLeftActive->setMinimumSize(100, 50);
    headerLeftNo->setMaximumSize(100, 50);
    headerLeftNo->setMinimumSize(100, 50);
    headerLeftClock->setMinimumSize(100, 50);
    headerLeftClock->setMaximumSize(100, 50);
    headerLeftDelay->setMinimumSize(160, 50);
    headerLeftDelay->setMaximumSize(160, 50);

    headerLeftNo->setAlignment(Qt::AlignCenter);
    headerLeftActive->setAlignment(Qt::AlignCenter);
    headerLeftClock->setAlignment(Qt::AlignCenter);
    headerLeftDelay->setAlignment(Qt::AlignCenter);
    leftLayout->addWidget(headerLeftActive, 0, 0);
    leftLayout->addWidget(headerLeftNo, 0, 1);
    leftLayout->addWidget(headerLeftClock, 0, 2);
    leftLayout->addWidget(headerLeftDelay, 0, 3);

    QLabel * headerRightNo = new QLabel(ui->widgetChannel);
    QLabel * headerRightActive = new QLabel(ui->widgetChannel);
    QLabel * headerRightClock = new QLabel(ui->widgetChannel);
    QLabel * headerRightDelay = new QLabel(ui->widgetChannel);
    headerRightNo->setText("通道号");
    headerRightActive->setText("是否启用");
    headerRightClock->setText("钟编号");
    headerRightDelay->setText("时延(ns)");
    headerRightNo->setProperty("table", "header");
    headerRightActive->setProperty("table", "header");
    headerRightClock->setProperty("table", "header");
    headerRightDelay->setProperty("table", "header");

    headerRightActive->setMaximumSize(100, 50);
    headerRightActive->setMinimumSize(100, 50);
    headerRightNo->setMaximumSize(100, 50);
    headerRightNo->setMinimumSize(100, 50);
    headerRightClock->setMinimumSize(100, 50);
    headerRightClock->setMaximumSize(100, 50);
    headerRightDelay->setMinimumSize(160, 50);
    headerRightDelay->setMaximumSize(160, 50);

    headerRightNo->setAlignment(Qt::AlignCenter);
    headerRightActive->setAlignment(Qt::AlignCenter);
    headerRightClock->setAlignment(Qt::AlignCenter);
    headerRightDelay->setAlignment(Qt::AlignCenter);

    rightLayout->addWidget(headerRightActive, 0, 0);
    rightLayout->addWidget(headerRightNo, 0, 1);
    rightLayout->addWidget(headerRightClock, 0, 2);
    rightLayout->addWidget(headerRightDelay, 0, 3);

    for ( int i = 0; i < 8; i++ )
    {
        QCheckBox * tdLeftActive = new QCheckBox(ui->widgetChannel);
        QCheckBox * tdRightActive = new QCheckBox(ui->widgetChannel);
        tdLeftActive->setText("启用");
        tdLeftActive->setMinimumSize(100, 40);
        tdLeftActive->setMaximumSize(100, 40);
        tdRightActive->setText("启用");
        tdRightActive->setMinimumSize(100, 40);
        tdRightActive->setMaximumSize(100, 40);
        leftLayout->addWidget(tdLeftActive, i + 1, 0);
        rightLayout->addWidget(tdRightActive, i + 1 , 0);

        tdLeftActive->setProperty("channelIndex", QString::number(i));
        tdRightActive->setProperty("channelIndex", QString::number(i + 8));

        connect(tdLeftActive, &QCheckBox::stateChanged, this, &CounterSettingForm::onActiveStateChanged);
        connect(tdRightActive, &QCheckBox::stateChanged, this, &CounterSettingForm::onActiveStateChanged);

        activeListLeft.append(tdLeftActive);
        activeListRight.append(tdRightActive);

        QLabel * tdLeftNo = new QLabel(ui->widgetChannel);
        QLabel * tdRightNo = new QLabel(ui->widgetChannel);
        tdLeftNo->setText(QString("CH%1").arg(i + 1));
        tdLeftNo->setAlignment(Qt::AlignCenter);
        tdRightNo->setText(QString("CH%1").arg(i + 8 + 1));
        tdRightNo->setAlignment(Qt::AlignCenter);
        leftLayout->addWidget(tdLeftNo, i + 1, 1);
        rightLayout->addWidget(tdRightNo, i + 1 , 1);

        QLineEdit * tdLeftClock = new QLineEdit(ui->widgetChannel);
        QLineEdit * tdRightClock = new QLineEdit(ui->widgetChannel);
        tdLeftClock->setMinimumSize(100, 40);
        tdLeftClock->setMaximumSize(100, 40);
        tdRightClock->setMinimumSize(100, 40);
        tdRightClock->setMaximumSize(100, 40);
        leftLayout->addWidget(tdLeftClock, i + 1, 2);
        rightLayout->addWidget(tdRightClock, i + 1 , 2);

        clockListLeft.append(tdLeftClock);
        clockListRight.append(tdRightClock);

        QDoubleSpinBox * tdLeftDelay = new QDoubleSpinBox(ui->widgetChannel);
        QDoubleSpinBox * tdRightDelay = new QDoubleSpinBox(ui->widgetChannel);
        tdLeftDelay->setRange(-1E9, 1E9);
        tdLeftDelay->setSingleStep(0.001);
        tdLeftDelay->setDecimals(3);
        tdLeftDelay->setMinimumSize(160, 40);
        tdLeftDelay->setMaximumSize(160, 40);
        tdRightDelay->setRange(-1E9, 1E9);
        tdRightDelay->setSingleStep(0.001);
        tdRightDelay->setDecimals(3);
        tdRightDelay->setMinimumSize(160, 40);
        tdRightDelay->setMaximumSize(160, 40);
        leftLayout->addWidget(tdLeftDelay, i + 1, 3);
        rightLayout->addWidget(tdRightDelay, i + 1 , 3);

        delayListLeft.append(tdLeftDelay);
        delayListRight.append(tdRightDelay);

        if (i % 2 == 0)
        {
            tdLeftNo->setProperty("table", "trOdd");
            tdRightNo->setProperty("table", "trOdd");
            tdLeftClock->setProperty("table", "trOdd");
            tdRightClock->setProperty("table", "trOdd");
            tdLeftDelay->setProperty("table", "trOdd");
            tdRightDelay->setProperty("table", "trOdd");
            tdLeftActive->setProperty("table", "trOdd");
            tdRightActive->setProperty("table", "trOdd");
        } else {
            tdLeftNo->setProperty("table", "trEven");
            tdRightNo->setProperty("table", "trEven");
            tdLeftClock->setProperty("table", "trEven");
            tdRightClock->setProperty("table", "trEven");
            tdLeftDelay->setProperty("table", "trEven");
            tdRightDelay->setProperty("table", "trEven");
            tdLeftActive->setProperty("table", "trEven");
            tdRightActive->setProperty("table", "trEven");
        }
    }
}

void CounterSettingForm::clearChannelSettingValue()
{
    for (int i = 0; i < 8; i++)
    {
        activeListLeft.at(i)->setCheckable(false);
        activeListLeft.at(i)->setChecked(false);
        activeListLeft.at(i)->setText("未启用");
        clockListLeft.at(i)->setText("-");
        clockListLeft.at(i)->setReadOnly(true);
        delayListLeft.at(i)->setValue(0.000);
        delayListLeft.at(i)->setReadOnly(true);

        activeListRight.at(i)->setCheckable(false);
        activeListRight.at(i)->setChecked(false);
        activeListRight.at(i)->setText("未启用");
        clockListRight.at(i)->setText("-");
        clockListRight.at(i)->setReadOnly(true);
        delayListRight.at(i)->setValue(0.000);
        delayListRight.at(i)->setReadOnly(true);
    }
}

void CounterSettingForm::on_btnSettingClose_clicked()
{
    this->close();
}

void CounterSettingForm::on_btnSetDialog_accepted()
{
    if (SettingConfig::getInstance().MASTER != flagGroup->checkedId())
    {
        SettingConfig::getInstance().MASTER = flagGroup->checkedId();
        emit swiftDisplayLoop();
    }

    if (SettingConfig::getInstance().DISPLAY_COUNT != countGroup->checkedId())
    {
        SettingConfig::getInstance().DISPLAY_COUNT = countGroup->checkedId();
        SettingConfig::getInstance().setProperty("client", "displayCount", QString::number(countGroup->checkedId()));
        emit swiftDisplayCount();
        emit swiftDisplayLoop();
    }

    SettingConfig::getInstance().BASE_URL = ui->iptApiUrl->text();
    SettingConfig::getInstance().BASE_LOG_PATH = ui->iptLogPath->text();

    SettingConfig::getInstance().setProperty("http", "baseUrl", ui->iptApiUrl->text());
    SettingConfig::getInstance().setProperty("log", "basePath", ui->iptLogPath->text());

    this->close();
}

void CounterSettingForm::on_btnSetDialog_rejected()
{
    this->close();
}

void CounterSettingForm::on_btnChanelSetDialog_accepted()
{
    QString deviceId = ui->selectCounter->currentData().toString();

    QJsonArray channelSettingUpdated;

    for (int i = 0; i < 16; i++)
    {
        QString channelCode;
        double delay;
        bool active;
        if (i < 8) {
            channelCode = clockListLeft.at(i)->text();
            delay = delayListLeft.at(i)->value();
            active = activeListLeft.at(i)->isChecked();
        } else if (i < 16) {
            channelCode = clockListRight.at(i - 8)->text();
            delay = delayListRight.at(i - 8)->value();
            active = activeListRight.at(i - 8)->isChecked();
        }

        CounterChannel * channelPrt = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(i+1));
        if (channelPrt != nullptr)
        {
            bool isUpdated = isChannelSettingUpdated(i, channelPrt);
            if (isUpdated == true) {
                channelPrt->setChannelCode(channelCode);
                channelPrt->setDelays(QString::number(delay));
                channelPrt->setActive(active);

                QJsonObject channelObj;
                channelObj.insert("id", channelPrt->getChannelId());
                channelObj.insert("deviceId", deviceId);
                channelObj.insert("channelNo", channelPrt->getChannelNo());
                channelObj.insert("isUse", channelPrt->getIsUse());
                channelObj.insert("name", channelPrt->getName());

                channelObj.insert("delays", QString::number(delay));
                channelObj.insert("isActive", active == true ? "1" : "0");
                channelObj.insert("channelCode", channelCode);
                channelSettingUpdated.append(channelObj);
            }
        } else if (active == true) {
            CounterChannel * newChannel = new CounterChannel();
            newChannel->setActive(true);
            newChannel->setChannelCode(channelCode);
            newChannel->setDelays(QString::number(delay));

            ConstCache::getInstance().channelMap.insert(QString("%1-%2").arg(deviceId).arg(i+1), newChannel);

            QJsonObject channelObj;
            channelObj.insert("id", "");
            channelObj.insert("deviceId", deviceId);
            channelObj.insert("channelNo", QString::number(i + 1));
            channelObj.insert("isUse", SettingConfig::getInstance().MASTER);
            channelObj.insert("name", QString("钟%1-1PPS").arg(channelCode));

            channelObj.insert("delays", QString::number(delay));
            channelObj.insert("isActive", active == true ? "1" : "0");
            channelObj.insert("channelCode", channelCode);
            channelSettingUpdated.append(channelObj);
        }
    }

    if (channelSettingUpdated.size() > 0) {
        emit this->channelSettingSubmit(channelSettingUpdated);
    }

    this->close();
}

void CounterSettingForm::on_btnChanelSetDialog_rejected()
{
    this->close();
}

void CounterSettingForm::on_btnSelectDir_clicked()
{
    QString selectDir = QFileDialog::getExistingDirectory(this, "选择日志保存根目录", QDir::currentPath(), QFileDialog::ShowDirsOnly);
    if (selectDir.isEmpty() == false)
    {
        ui->iptLogPath->setText(selectDir + "/");
    }
}

void CounterSettingForm::on_selectCounter_currentIndexChanged(int index)
{
    clearChannelSettingValue();

    if (index > 0)
    {
        QString deviceId = ui->selectCounter->currentData().toString();

        for (int i = 0; i < 8; i++)
        {
            activeListLeft.at(i)->setCheckable(true);
            activeListRight.at(i)->setCheckable(true);

            CounterChannel * channelPrt = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(i+1));
            if (channelPrt != nullptr)
            {
                QString channelCode = channelPrt->getChannelCode(); // 通道钟号
                QString delays = channelPrt->getDelays(); // 通道时延值

                clockListLeft.at(i)->setText(channelCode);
                delayListLeft.at(i)->setValue(delays.toDouble());

                if (channelPrt->isActive() == true) {
                    activeListLeft.at(i)->setChecked(true);
                    activeListLeft.at(i)->setText("启用");
                    clockListLeft.at(i)->setReadOnly(false);
                    delayListLeft.at(i)->setReadOnly(false);
                }
            }

            CounterChannel * channelRightPrt = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(i+1+8));
            if (channelRightPrt != nullptr)
            {
                QString channelCode = channelRightPrt->getChannelCode(); // 通道钟号
                QString delays = channelRightPrt->getDelays(); // 通道时延值

                clockListRight.at(i)->setText(channelCode);
                delayListRight.at(i)->setValue(delays.toDouble());

                if (channelRightPrt->isActive() == true) {
                    activeListRight.at(i)->setChecked(true);
                    activeListRight.at(i)->setText("启用");
                    clockListRight.at(i)->setReadOnly(false);
                    delayListRight.at(i)->setReadOnly(false);
                }
            }
        }
    }
}

void CounterSettingForm::onActiveStateChanged()
{
    QCheckBox * obj = (QCheckBox *) sender();

    QString channelIndex = obj->property("channelIndex").toString();

    if (obj->isChecked() == true) {
        obj->setText("启用");
        enableChannel(channelIndex.toInt(), true);
    } else {
        obj->setText("未启用");
        enableChannel(channelIndex.toInt(), false);
    }
}

void CounterSettingForm::enableChannel(int index, bool enable)
{
    if (index < 8)
    {
        clockListLeft.at(index)->setReadOnly(!enable);
        delayListLeft.at(index)->setReadOnly(!enable);
    } else if (index >= 8 && index < 16) {
        clockListRight.at(index - 8)->setReadOnly(!enable);
        delayListRight.at(index - 8)->setReadOnly(!enable);
    }
}

bool CounterSettingForm::isChannelSettingUpdated(int index, CounterChannel *channelPtr)
{
    QString channelCode = ""; // 通道钟号
    double delay = 0.0; // 通道时延值
    bool active = false;

    if (index < 8) {
        channelCode = clockListLeft.at(index)->text(); // 通道钟号
        delay = delayListLeft.at(index)->value(); // 通道时延值
        active = activeListLeft.at(index)->isChecked();
    } else if (index < 16) {
        index = index - 8;
        channelCode = clockListRight.at(index)->text(); // 通道钟号
        delay = delayListRight.at(index)->value(); // 通道时延值
        active = activeListRight.at(index)->isChecked();
    }

    if (channelCode != channelPtr->getChannelCode()) {
        return true;
    }

    if (active != channelPtr->isActive()) {
        return true;
    }

    if (delay - channelPtr->getDelays().toDouble() != 0) {
        return true;
    }

    return false;
}
