// myudp.cpp

#include "myudp.h"
#include <QTimer>
#include <QNetworkInterface>

MyUDP::MyUDP(QObject *parent) :
    QObject(parent)
{
    // create a QUDP socket
    socket = new QUdpSocket(this);

    // The most common way to use QUdpSocket class is
    // to bind to an address and port using bind()
    // bool QAbstractSocket::bind(const QHostAddress & address,
    //     quint16 port = 0, BindMode mode = DefaultForPlatform)
    socket->bind(QHostAddress::AnyIPv4, 1234,QUdpSocket::ShareAddress);

    connect(socket,SIGNAL(readyRead()),this,SLOT(readyRead()));

    QTimer::singleShot(200, this, &MyUDP::join);

}

void MyUDP::join()
{
    setMulticast(QHostAddress("224.1.2.3"));
}

void MyUDP::setMulticast(QHostAddress address)
{
    if (listen_address != address) {

        QList<QNetworkInterface> mListIfaces = QNetworkInterface::allInterfaces();

        for (int i = 0; i < mListIfaces.length(); ++i) {
            if (socket && socket->state() == QAbstractSocket::BoundState)
                socket->leaveMulticastGroup(listen_address, mListIfaces.at(i));
        }

        listen_address = address;

        for (int i = 0; i < mListIfaces.length(); ++i) {
            qDebug() << socket->joinMulticastGroup(address,mListIfaces.at(i));
        }


        qDebug() << "EMIT MULTICAST CHANGED";
        emit multicastChanged(address);
    }
}

void MyUDP::HelloUDP()
{
    QByteArray Data;
    Data.append("Hello from UDP");
    qDebug() << "Sending message";

    // Sends the datagram datagram
    // to the host address and at port.
    // qint64 QUdpSocket::writeDatagram(const QByteArray & datagram,
    //                      const QHostAddress & host, quint16 port)
    socket->writeDatagram(Data, QHostAddress::LocalHost, 1234);
}

void MyUDP::readyRead()
{
    // when data comes in
    QByteArray buffer;
    buffer.resize(socket->pendingDatagramSize());

    QHostAddress sender;
    quint16 senderPort;
    int bellNumber;
    QString header;
    QString msg;

    // qint64 QUdpSocket::readDatagram(char * data, qint64 maxSize,
    //                 QHostAddress * address = 0, quint16 * port = 0)
    // Receives a datagram no larger than maxSize bytes and stores it in data.
    // The sender's host address and port is stored in *address and *port
    // (unless the pointers are 0).

    socket->readDatagram(buffer.data(), buffer.size(),
                         &sender, &senderPort);


    msg = QString::fromLatin1(buffer);
    QStringList list1 = msg.split(QLatin1Char(':'));
    qDebug() << msg;
    qDebug() << "List Size: " << list1.size();
    if (list1.size() >= 2) {
        header = list1.at(0);
        qDebug() << "H: " << header;
        if (header == "BELL") {
            bellNumber = list1.at(1).toInt();
            emit packetArrived(bellNumber);
        }
    }

    qDebug() << "Message from: " << sender.toString();
    qDebug() << "Message port: " << senderPort;
    qDebug() << "Message: " << buffer;
}
