// bytran -|- spectral calculations for portable devices using the HITRAN database
//
// Developed by Dzianis Pliutau (Denis Plutov) and Kostya Roslyakov
// www.bytran.org | bytran@bytran.org
// Copyright (c) 2016 Dzianis Pliutau
// Distributed under the MIT license
//
// The MIT License (MIT)
// Copyright (c) 2016 Dzianis Pliutau
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy,
// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software
// is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
// IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.



// Object to communicate with the QML program interface for remote control components
#include "remotecontrolqml.h"
#include <QDesktopServices>

RemoteControlQml::RemoteControlQml(QObject *parent, RemoteControl *inRemoteControl) : QObject(parent)
{
    // Transfering a pointer to the core data object into the internal variable
    remoteControl = inRemoteControl;

    // Ssaving remote contol related variables to the local variables
    m_communicationMode = remoteControl->getCommunicationMode();
    m_broadcastManualInput = remoteControl->getBroadcastManualInput();
    m_portNumber = QString::number(remoteControl->getWebSockets()->getPortNumber());
    m_selectedBluetoothDeviceIndex = 0;
    m_connectedString = "00001101-0000-1000-8000-00805f9b34fb";

    // Linking connections
    connect(this->remoteControl->getWebSockets(), SIGNAL(connectedStateChanged()), this, SLOT(setConnectedState()));
    connect(this->remoteControl->getBluetooth()->getBluetoothDevicesDiscover(), SIGNAL(connected()), this, SIGNAL(connectButtonTextChanged()));
    connect(this->remoteControl->getBluetooth()->getBluetoothDevicesDiscover(), SIGNAL(disconnected()), this, SIGNAL(connectButtonTextChanged()));
    connect(this->remoteControl->getBluetooth(), SIGNAL(connectedToServer(QString)), this, SLOT(setConnectedToBluetoothServer(QString)));
    connect(this->remoteControl->getBluetooth(), SIGNAL(disconnectedFromServer(QString)), this, SLOT(setDisconnectedFromBluetoothServer(QString)));
}

// Signal is emitted when the connected state is changed (regardless of the connection type, i.e. WebSockets, Bluetooth, Serial Port)
void RemoteControlQml::setConnectedState()
{
    emit remoteDeviceIpAddressChanged();
    emit connectButtonTextChanged();
}

int RemoteControlQml::communicationMode() const { return remoteControl->getCommunicationMode(); }
void RemoteControlQml::setCommunicationMode(const int communicationMode)
{
    if (communicationMode != m_communicationMode)
    {
        m_communicationMode = communicationMode;
        remoteControl->setCommunicationMode(m_communicationMode);
        emit communicationModeChanged();
    }
}

bool RemoteControlQml::broadcastManualInput() const { return remoteControl->getBroadcastManualInput(); }
void RemoteControlQml::setBroadcastManualInput(const bool broadcastManualInput)
{
    if (broadcastManualInput != m_broadcastManualInput)
    {
        m_broadcastManualInput = broadcastManualInput;
        remoteControl->setBroadcastManualInput(m_broadcastManualInput);
        emit broadcastManualInputChanged();
    }
}

QString RemoteControlQml::portNumber() const { return QString::number(remoteControl->getWebSockets()->getPortNumber()); }
void RemoteControlQml::setPortNumber(const QString portNumber)
{
    if ((portNumber != m_portNumber) && (portNumber > 0))
    {
        m_portNumber = portNumber;
        remoteControl->getWebSockets()->setPortNumber(loc.toUShort(m_portNumber));
        emit portNumberChanged();
    }
}

quint8 RemoteControlQml::selectedBluetoothDeviceIndex() const { return remoteControl->getBluetooth()->getBluetoothDevicesDiscover()->getSelectedDeviceIndex(); }
void RemoteControlQml::setSelectedBluetoothDeviceIndex(const quint8 &selectedBluetoothDeviceIndex)
{
    if (selectedBluetoothDeviceIndex != m_selectedBluetoothDeviceIndex)
    {
        m_selectedBluetoothDeviceIndex = selectedBluetoothDeviceIndex;
        remoteControl->getBluetooth()->getBluetoothDevicesDiscover()->setSelectedDeviceIndex(m_selectedBluetoothDeviceIndex);
        emit selectedBluetoothDeviceIndexChanged();
    }
}

QString RemoteControlQml::bytranDeviceIpAddress() const { return remoteControl->getWebSockets()->getSelfDeviceIpAddresses(); }
QString RemoteControlQml::remoteDeviceIpAddress() const { return remoteControl->getWebSockets()->getConnectedDeviceIpAddress(); }

void RemoteControlQml::openUrl(QString webAddress) { bool result = QDesktopServices::openUrl(QUrl(webAddress, QUrl::TolerantMode)); }
void RemoteControlQml::discoverDevices() { this->remoteControl->getBluetooth()->getBluetoothDevicesDiscover()->discoverDevices(false); }
void RemoteControlQml::connectBluetooth()
{
    qDebug() << "Connected device index: " << this->remoteControl->getBluetooth()->getBluetoothDevicesDiscover()->getConnectedDeviceIndex();
    if (this->remoteControl->getBluetooth()->getBluetoothDevicesDiscover()->getConnectedDeviceIndex() == -1) {
        this->remoteControl->getBluetooth()->connectToSelectedDevice();
    }
    else {
        this->remoteControl->getBluetooth()->disconnectFromAllDevices();
    }
}
// Broadcasting a command corresponding to the variable change or sending a custom message to a remote device performing the control of bytran
void RemoteControlQml::broadcastCommand(QString command, int index) { this->remoteControl->broadcastCommand(command, index); }
void RemoteControlQml::sendMessage(QString message) { this->remoteControl->sendMessage(message); }

// Text of the bluetooth low energy connect button
QString RemoteControlQml::connectButtonText() const
{
    if (this->remoteControl->getBluetooth()->getBluetoothDevicesDiscover()->getConnectedDeviceIndex() == -1) {
        return "  Connect  ";
    }
    else {
        return " Disconnect ";
    }
}

// Text to indicate the UUID value or the connected state (if connected)
QString RemoteControlQml::connectedString() const { return m_connectedString; }
// Slots are called when a remote client is connected or disconnected from the bluetooth server
void RemoteControlQml::setConnectedToBluetoothServer(const QString &name)
{
    m_connectedString = "Connected device: " + name;
    emit connectedStringChanged();
}
void RemoteControlQml::setDisconnectedFromBluetoothServer(const QString &name)
{
    m_connectedString = "00001101-0000-1000-8000-00805f9b34fb";
    emit connectedStringChanged();
}
