/****************************************************************************
**
** Copyright (C) 2017 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the examples of the QtSerialBus module.
**
** $QT_BEGIN_LICENSE:BSD$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** BSD License Usage
** Alternatively, you may use this file under the terms of the BSD license
** as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
**   * Redistributions of source code must retain the above copyright
**     notice, this list of conditions and the following disclaimer.
**   * Redistributions in binary form must reproduce the above copyright
**     notice, this list of conditions and the following disclaimer in
**     the documentation and/or other materials provided with the
**     distribution.
**   * Neither the name of The Qt Company Ltd nor the names of its
**     contributors may be used to endorse or promote products derived
**     from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "mainwindow.h"
#include "modbustcpclient.h"

#include <QLoggingCategory>
#include <QModbusPdu>
#include <QModbusRtuSerialMaster>
#include <QSerialPortInfo>

#ifndef QT_STATIC
 QT_BEGIN_NAMESPACE
 Q_LOGGING_CATEGORY(QT_MODBUS, "qt.modbus")
 Q_LOGGING_CATEGORY(QT_MODBUS_LOW, "qt.modbus.lowlevel")
 QT_END_NAMESPACE
#endif

QT_USE_NAMESPACE

MainWindow *s_instance = nullptr;

static void HandlerFunction(QtMsgType, const QMessageLogContext &, const QString &msg)
{
    if (auto instance = MainWindow::instance())
        instance->appendToLog(msg);
}

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , m_debugHandler(HandlerFunction)
{
    setupUi(this);
    s_instance = this;

    const auto ports = QSerialPortInfo::availablePorts();
    for (const QSerialPortInfo &info : ports)
        serialPortCombo->addItem(info.portName(), false);
    serialPortCombo->insertSeparator(serialPortCombo->count());
    serialPortCombo->addItem(tr("Add port..."), true);
    serialPortCombo->setInsertPolicy(QComboBox::InsertAtTop);

    connect(tcpRadio, &QRadioButton::toggled, this, [this](bool toggled) {
        stackedWidget->setCurrentIndex(toggled);
    });
    connect(actionExit, &QAction::triggered, this, &QMainWindow::close);

    QLoggingCategory::setFilterRules(QStringLiteral("qt.modbus* = true"));
}

MainWindow::~MainWindow()
{
    disconnectAndDelete();
    s_instance = nullptr;
}

MainWindow *MainWindow::instance()
{
    return s_instance;
}

void MainWindow::on_sendButton_clicked()
{
    const bool isSerial = serialRadio->isChecked();
    const bool isCustom = (isSerial ? fcSerialDrop : fcTcpDrop)->currentIndex() == 0;
    const QByteArray pduData = QByteArray::fromHex((isSerial ? pduSerialLine : pduTcpLine)->text()
        .toLatin1());

    QModbusReply *reply = nullptr;
    if (isCustom && pduData.isEmpty()) {
        qDebug() << "Error: Cannot send custom PDU without any data.";
        return;
    }

    const quint8 address = quint8((isSerial ? addressSpin : ui1Spin)->value());
    if (isCustom) {
        qDebug() << "Send: Sending custom PDU.";
        reply = m_device->sendRawRequest(QModbusRequest(QModbusRequest::FunctionCode(
            pduData[0]), pduData.mid(1)), address);
    } else {
        qDebug() << "Send: Sending PDU with predefined function code.";
        quint16 fc = (isSerial ? fcSerialDrop : fcTcpDrop)->currentText().left(4).toUShort(0, 16);
        reply = m_device->sendRawRequest(QModbusRequest(QModbusRequest::FunctionCode(fc), pduData),
            address);
    }

    if (reply) {
        sendButton->setDisabled(true);
        if (!reply->isFinished()) {
            connect(reply, &QModbusReply::finished, [reply, this]() {
                sendButton->setEnabled(true);
                qDebug() << "Receive: Asynchronous response PDU: " << reply->rawResult() << Qt::endl;
            });
        } else {
            sendButton->setEnabled(true);
            qDebug() << "Receive: Synchronous response pdu: " << reply->rawResult() << Qt::endl;
        }
    }
}

void MainWindow::on_connectButton_clicked()
{
    if (tcpRadio->isChecked()) {
        auto device = new ModbusTcpClient;
        connect(ti1Spin, QOverload<int>::of(&QSpinBox::valueChanged),
                device, &ModbusTcpClient::valueChanged);
        connect(ti2Spin, QOverload<int>::of(&QSpinBox::valueChanged),
                device, &ModbusTcpClient::valueChanged);

        connect(pi1Spin, QOverload<int>::of(&QSpinBox::valueChanged),
                device, &ModbusTcpClient::valueChanged);
        connect(pi2Spin, QOverload<int>::of(&QSpinBox::valueChanged),
                device, &ModbusTcpClient::valueChanged);

        connect(l1Spin, QOverload<int>::of(&QSpinBox::valueChanged),
                device, &ModbusTcpClient::valueChanged);
        connect(l2Spin, QOverload<int>::of(&QSpinBox::valueChanged),
                device, &ModbusTcpClient::valueChanged);

        connect(ui1Spin, QOverload<int>::of(&QSpinBox::valueChanged),
                device, &ModbusTcpClient::valueChanged);

        m_device = device;
        device->valueChanged(0);    // trigger update
        m_device->setConnectionParameter(QModbusDevice::NetworkAddressParameter,
            tcpAddressEdit->text());
        m_device->setConnectionParameter(QModbusDevice::NetworkPortParameter,
            tcpPortEdit->text());
    } else {
        m_device = new QModbusRtuSerialMaster;
        m_device->setConnectionParameter(QModbusDevice::SerialPortNameParameter,
            serialPortCombo->currentText());

        int parity = parityCombo->currentIndex();
        if (parity > 0)
            parity++;
        m_device->setConnectionParameter(QModbusDevice::SerialParityParameter, parity);
        m_device->setConnectionParameter(QModbusDevice::SerialDataBitsParameter,
            dataBitsCombo->currentText().toInt());
        m_device->setConnectionParameter(QModbusDevice::SerialStopBitsParameter,
            stopBitsCombo->currentText().toInt());
        m_device->setConnectionParameter(QModbusDevice::SerialBaudRateParameter,
            baudRateCombo->currentText().toInt());
    }
    m_device->setTimeout(timeoutSpin->value());
    m_device->setNumberOfRetries(retriesSpin->value());

    connect(m_device, &QModbusDevice::errorOccurred, this, [this](QModbusDevice::Error) {
        qDebug().noquote() << QStringLiteral("Error: %1").arg(m_device->errorString());
        emit disconnectButton->clicked();
    }, Qt::QueuedConnection);

    connect(m_device, &QModbusDevice::stateChanged, [](QModbusDevice::State state) {
        switch (state) {
        case QModbusDevice::UnconnectedState:
            qDebug().noquote() << QStringLiteral("State: Entered unconnected state.");
            break;
        case QModbusDevice::ConnectingState:
            qDebug().noquote() << QStringLiteral("State: Entered connecting state.");
            break;
        case QModbusDevice::ConnectedState:
            qDebug().noquote() << QStringLiteral("State: Entered connected state.");
            break;
        case QModbusDevice::ClosingState:
            qDebug().noquote() << QStringLiteral("State: Entered closing state.");
            break;
        }
    });
    m_device->connectDevice();
}

void MainWindow::on_disconnectButton_clicked()
{
    disconnectAndDelete();
}

void MainWindow::on_serialPortCombo_currentIndexChanged(int index)
{
    const bool custom = serialPortCombo->itemData(index, Qt::UserRole).toBool();
    serialPortCombo->setEditable(custom);
    if (custom) {
        serialPortCombo->clearEditText();
        serialPortCombo->lineEdit()->setPlaceholderText(QStringLiteral("Type here..."));
    }
}

void MainWindow::disconnectAndDelete()
{
    if (!m_device)
        return;
    m_device->disconnectDevice();
    m_device->disconnect();
    delete m_device;
    m_device = nullptr;
}
