#pragma once

#include <QObject>

#include "qsacnnode_global.h"
#include "sacn/universe.h"

/**
 * @brief The QSacnUniverse class
 */
class QT_EXPORT QSacnUniverse
        : public QObject
{
    Q_OBJECT
public:
    friend DMX::Universe;  // permit callback to access the private notifier
    /**
     * @brief QSacnUniverse
     * @param parent
     * @param universe
     */
    explicit QSacnUniverse(QObject *parent = nullptr,
                           sACN::Universe *universe = nullptr)
        : QObject(parent)
        , universe_(universe)
    {
        universe_->onData(std::bind(&QSacnUniverse::dataChangedNotifier,
                                    this, std::placeholders::_1));
    };

    const QString description() const
    {
        return QString::fromUtf8(universe_->provenance()->source_name.c_str());
    }

    uint16_t number() const
    {
        return universe_->provenance()->universe;
    }

    uint8_t priority() const
    {
        return universe_->provenance()->priority;
    }

    double rxRate() const
    {
        return universe_->rxRate();
    }

    uint8_t slot(const u_int16_t slot) const
    {
        return universe_->slot(slot);
    }

public slots:
    void setDescription(std::string desc)
    {
        universe_->provenance()->source_name = desc;
    }
    void setOptions(sACN::DATA::data_options o)
    {
        universe_->provenance()->options = o;
    }
    void setPriority(uint8_t p)
    {
        universe_->provenance()->priority = p;
    }
    void setSyncAddress(uint16_t a)
    {
        universe_->provenance()->sync_address = a;
    }
    void setValue (const uint16_t addr, const uint8_t level)
    {
        universe_->DMX::Universe::setValue(addr, level);
    }
    void setValue (const uint16_t addr, const uint16_t size,
                   const uint8_t* profile)
    {
        universe_->DMX::Universe::setValue(addr, size, profile);
    }


signals:
    void changed(sACN::Universe*);

protected:
    void dataChangedNotifier(DMX::Universe* universe = nullptr)
    {
        Q_UNUSED(universe)
        emit changed(universe_);
    };

private:
    sACN::Universe *universe_;
};
