#include "ukuikeystate.h"
#include "ukuidisplay_p.h"

#include "keystate.h"

#include <QDebug>

class UkuiKeyStatePrivate
{
public:
    UkuiKeyStatePrivate();
    ~UkuiKeyStatePrivate();

    std::function<void(UkuiKeyState::Key, UkuiKeyState::State)> stateChanged;
    wayland::org_kde_kwin_keystate_t m_keystate;
};

UkuiKeyStatePrivate::UkuiKeyStatePrivate()
{
    m_keystate = static_cast<wayland::org_kde_kwin_keystate_t>(ukuiDisplay()->bind(wayland::detail::org_kde_kwin_keystate_interface.name, m_keystate, wayland::detail::org_kde_kwin_keystate_interface.version));
    if (!m_keystate) {
        qWarning() << "Failed to bind org_kde_kwin_keystate";
        return;
    }

    m_keystate.on_stateChanged() = [this](uint32_t key, uint32_t state) {
        if (stateChanged) {
            stateChanged(static_cast<UkuiKeyState::Key>(key), static_cast<UkuiKeyState::State>(state));
        }
    };
}

UkuiKeyStatePrivate::~UkuiKeyStatePrivate()
{
}

UkuiKeyState *ukuiKeyState()
{
    static UkuiKeyState *instance = nullptr;
    if (!instance) {
        instance = new UkuiKeyState();
    }
    return instance;
}

UkuiKeyState::UkuiKeyState()
    : m_ukuiKeyStatePrivate(new UkuiKeyStatePrivate())
{
}

UkuiKeyState::~UkuiKeyState()
{
    delete m_ukuiKeyStatePrivate;
    m_ukuiKeyStatePrivate = nullptr;
}

void UkuiKeyState::fetchStates()
{
    if (m_ukuiKeyStatePrivate && m_ukuiKeyStatePrivate->m_keystate) {
        m_ukuiKeyStatePrivate->m_keystate.fetchStates();
    }
}

std::function<void(UkuiKeyState::Key, UkuiKeyState::State)> &UkuiKeyState::on_state_changed()
{
    return m_ukuiKeyStatePrivate->stateChanged;
}
