#pragma once

#include "Window.h"
#include "SharedMemory.h"
#include "AbstractUiInterface.h"

#include "wayland-client.h"
#include "xdg-shell-client-protocol.h"

#include <vector>
#include <memory>

class WaylandSurface;
class WaylandBuffer;
class WaylandSeatInterface;
class WaylandEglInterface;
class DesktopManager;

class WaylandInterface : public AbstractUIInterface
{

public:
    WaylandInterface(DesktopManager* desktopManager);

    ~WaylandInterface();

    void loop() override;

    void addWindow(mt::Window* window) override;

    void showWindow(mt::Window* window) override;

    void initialize() override;

    void shutDown() override;

private:
    static void registryHandleGlobalEvent(void *data, struct wl_registry *registry, uint32_t name, const char *interface, uint32_t version);
    static void registryHandleGlobalRemoveEvent(void *data, struct wl_registry *registry, uint32_t name);

    void doXdgPong(uint32_t serial);

    void setCompositor(wl_compositor* compositor);

    void setSharedMemory(wl_shm* shared_memory);

    void setSeat(wl_seat* seat);

    void setXdgBase(xdg_wm_base* xdg_base);

    DesktopManager* mDesktopManager{nullptr};

    wl_display* mDisplay{nullptr};
    wl_compositor* mCompositor{nullptr};
    wl_registry_listener mRegistryListener;

    xdg_wm_base* mXdgBase{nullptr};
    xdg_wm_base_listener mXdgBaseListener;

    std::vector<std::unique_ptr<WaylandSurface> > mSurfaces;
    std::shared_ptr<WaylandBuffer> mBuffer;
    std::unique_ptr<WaylandSeatInterface> mSeatInterface;
    std::unique_ptr<WaylandEglInterface> mEglInterface;
};
