#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_->source()->description().c_str());
    }

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

    uint8_t priority() const
    {
        return universe_->source()->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_->source()->setDescription(desc);
    }
    void setOptions(uint8_t o)
    {
        universe_->source()->setOptions(o);
    }
    void setPriority(uint8_t p)
    {
        universe_->source()->setPriority(p);
    }
    void setSyncAddress(uint16_t a)
    {
        universe_->source()->setSyncAddress(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_;
};
