// 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
//
// This class is based in part on the Qt Bluetooth chat example distributed under the BSD license copyrighted to The Qt Company Ltd.
// available at the following link: http://doc.qt.io/qt-5/qtbluetooth-chat-example.html
//
// Additionally, these links may be useful in implementing Bluetooth interaction
// http://doc.qt.io/qt-5/qtbluetooth-overview.html
// http://stackoverflow.com/questions/27229813/real-time-bluetooth-spp-data-streaming-on-android-only-works-for-5-seconds
//
// 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.



// This class is based in part on the Qt Bluetooth chat example
#ifndef BLUETOOTHSPP_H
#define BLUETOOTHSPP_H

// Need to write code to read in a steam of Bluetooth data
#include <QObject>
#include <QBluetoothAddress>
#include <QBluetoothLocalDevice>
#include <QBluetoothServiceDiscoveryAgent>
#include "chatserver.h"
#include "chatclient.h"
#include "bluetoothdiscoverdevices.h"

class BluetoothSpp : public QObject
{
    Q_OBJECT

public:

    explicit BluetoothSpp(QObject *parent = nullptr);
    // Maybe need to add a destructor here as well (meed to read more on this if this is a must)

    // Method to get a reference to the Bluetooth discovery object
    BluetoothDiscoverDevices *getBluetoothDevicesDiscover();

    // Methods to enable and disable bluetooth
    void enableBluetooth();
    void disableBluetooth();

    // Method to connect to the currently selected device
    void connectToSelectedDevice();

    // Method to disconnect from all currently connected devices
    void disconnectFromAllDevices();

    // Method to determine if any remote Bluetooth devices are connected (as a client or a server)
    bool getRemoteDeviceIsConnected();

    // Method to get the local bluetooth device name
    QString getLocalDeviceName();

    // Method to get the number of available connected devices
    int getNumAvailableDevices();

    // Getting and setting the device index
    int getDeviceIndex();
    void setDeviceIndex(int newDeviceIndex);

    // Method to send data to the bluetooth COM port emulator
    void sendMessage(const QString &message);

private:

    // Method to connect to a bluetooth device
    void discoverServicesForSelectedDevice();
    void discoverServices(QBluetoothDeviceInfo device);

signals:

    // Emited once the service discovery for a device is complete
    void servicesDiscovered();

    // Signal is emitted when the device is connected or disconnected
    void connected();
    void disconnected();

    // Signal is emitted when a device is connected to the bytran bluetooth server or disconnected from it
    void connectedToServer(const QString &name);
    void disconnectedFromServer(const QString &name);

    // Signal is emitted when a command is received over the websockets protocol
    void commandReceived(const QString &message);

public slots:

private slots:

    // Slots for service discovery
    void appendServiceDiscovered(const QBluetoothServiceInfo &bluetoothServiceInfo);
    void servicesDiscoveryFinished();

    // These are the responsible to client connections to the server including the retrieval of the invoming data and sending responses
    void clientConnected(const QString &name);
    void clientDisconnected(const QString &name);
    void clientDisconnected();
    void showMessage(const QString &sender, const QString &message);

private:

    // On implementing the bluetooth data exchange
    // http://doc.qt.io/qt-5/qtbluetooth-overview.html
    // http://doc.qt.io/qt-5/qbluetoothserver.html
    // http://doc.qt.io/qt-5/qbluetoothsocket.html

    QBluetoothLocalDevice *localDevice;  // Bluetooth local device object
    QBluetoothServiceDiscoveryAgent *servicesDiscoveryAgent;  // Object to discover available services for a bluetooth device

    // Object to discover bluetooth devices
    BluetoothDiscoverDevices *devicesDiscover;

    // List of discovered bluetooth services for a selected device
    QVector<QBluetoothServiceInfo> services;

    ChatServer *bluetoothServer;  // Bluetooth server object to accept incoming data from another bluetooth device using the SPP protocol
    QList<ChatClient *> clients;  // List of connected bluetooth clients

};

#endif // BLUETOOTHSPP_H
