// SPDX-FileCopyrightText: 2024 KylinSoft Co., Ltd.
//
// SPDX-License-Identifier: GPL-1.0-or-later

#include "ukuishell.h"
#include "logging.h"
#include "ukuiblur.h"
#include "kde-slide.h"
#include "ukuishellsurface.h"
#include "ukuishellsurfacev1.h"
#include "xdgactivationv1.h"
#include "xdgdialogv1.h"
#include "xdgtopleveliconv1.h"

#include <QtWaylandClient/private/qwaylanddisplay_p.h>
#include <QtWaylandClient/private/qwaylandwindow_p.h>

#include <QGuiApplication>
#include <cstdint>

namespace QtWaylandClient
{

UkuiShell::UkuiShell(QWaylandDisplay *display, uint32_t id, uint32_t availableVersion)
    : xdg_wm_base(display->wl_registry(), id, qMin(availableVersion, 5u))
    , m_display(display)
{
    display->addRegistryListener(&UkuiShell::handleRegistryGlobal, this);
}

UkuiShell::~UkuiShell()
{
    m_display->removeListener(&UkuiShell::handleRegistryGlobal, this);
    destroy();
}

XdgDecorationManagerV1 *UkuiShell::decorationManager()
{
    return m_xdgDecorationManager.get();
}

XdgDialogWmV1 *UkuiShell::xdgDialogWm()
{
    return m_xdgDialogWm.get();
}

XdgActivationV1 *UkuiShell::xdgActivation()
{
    return m_xdgActivation.get();
}

UkuiBlurManager *UkuiShell::blurManager()
{
    return m_blurManager.get();
}

KdeSlideManager *UkuiShell::slideManager()
{
    return m_slideManager.get();
}

QtWayland::ukui_shell *UkuiShell::QtwaylandUkuiShell()
{
    return m_ukuiShell.get();
}

QtWayland::ukui_shell_v1 *UkuiShell::QtwaylandUkuiShellV1()
{
    return m_ukuiShellV1.get();
}

XdgToplevelIconManagerV1 *UkuiShell::xdgToplevelIconManager()
{
    return m_topLevelIconManager.get();
}

QWaylandShellSurface *UkuiShell::getUkuiShellSurface(QWaylandWindow *window)
{
    if (m_ukuiShellV1) {
        return new UkuiShellSurfaceV1(this, get_xdg_surface(window->wlSurface()), m_ukuiShellV1->create_surface(window->wlSurface()), m_ukuiShellV1->create_decoration(window->wlSurface()), window);
    } else if (m_ukuiShell) {
        return new UkuiShellSurface(this, get_xdg_surface(window->wlSurface()), m_ukuiShell->create_surface(window->wlSurface()), window);
    }

    return nullptr;
}

void UkuiShell::xdg_wm_base_ping(uint32_t serial)
{
    pong(serial);
}

void UkuiShell::handleRegistryGlobal(void *data, wl_registry *registry, uint id, const QString &interface, uint version)
{
    UkuiShell *ukuiShell = static_cast<UkuiShell *>(data);
    if (interface == QLatin1String(QtWayland::ukui_shell::interface()->name)) {
        ukuiShell->m_ukuiShell.reset(new QtWayland::ukui_shell(registry, id, qMin(version, 4u)));
    } else if (interface == QLatin1String(QtWayland::ukui_shell_v1::interface()->name)) {
        ukuiShell->m_ukuiShellV1.reset(new QtWayland::ukui_shell_v1(registry, id, qMin<uint32_t>(version, QtWayland::ukui_shell_v1::interface()->version)));
    }  else if (interface == QLatin1String(XdgDecorationManagerV1::interface()->name)) {
        ukuiShell->m_xdgDecorationManager.reset(new XdgDecorationManagerV1(registry, id, qMin(version, 1u)));
    } else if (interface == QLatin1String(XdgDialogWmV1::interface()->name)) {
        ukuiShell->m_xdgDialogWm.reset(new XdgDialogWmV1(registry, id, qMin(version, 1u)));
    } else if (interface == QLatin1String(XdgActivationV1::interface()->name)) {
        ukuiShell->m_xdgActivation.reset(new XdgActivationV1(registry, id, qMin(version, 1u)));
    } else if (interface == QLatin1String(QtWayland::ukui_blur_manager_v1::interface()->name)) {
        ukuiShell->m_blurManager.reset(new UkuiBlurManager(registry, id, qMin(version, 1u)));
    } else if (interface == QLatin1String(QtWayland::org_kde_kwin_slide_manager::interface()->name)) {
        ukuiShell->m_slideManager.reset(new KdeSlideManager(registry, id, qMin(version, 1u)));
    } else if (interface == QLatin1String(XdgToplevelIconManagerV1::interface()->name)) {
        ukuiShell->m_topLevelIconManager.reset(new XdgToplevelIconManagerV1(ukuiShell->m_display, registry, id, qMin<uint32_t>(version, XdgToplevelIconManagerV1::interface()->version)));
    }
}
}