#pragma once

#include "BaseWindow.h"

#include <wayland-client.h>
#include "xdg-shell-client-protocol.h"
#include "xdg-decoration.h"

namespace ehs
{
	class EHS_LIB_IO Window : public BaseWindow
	{
	protected:
		wl_display *display;
		wl_registry *registry;
		wl_compositor *compositor;
		wl_surface *wlSurface;
		xdg_wm_base *xdgShell;
		xdg_surface *xdgSurface;
		xdg_toplevel *xdgToplevel;
		zxdg_decoration_manager_v1 *decManager;
		zxdg_toplevel_decoration_v1 *dec;
		wl_seat *seat;
		wl_pointer *pointer;
		Vec2_u32 scale;

		static void SurfaceConfigEvent(void *data, xdg_surface *xdg_surface, UInt_32 serial);

		static void ShellPing(void *data, xdg_wm_base *shell, UInt_32 serial);

		static void RegistryHandler(void *data, wl_registry *registry, UInt_32 id, const char *interface, UInt_32 version);

		static void RegistryRemoved(void *data, wl_registry *registry, UInt_32 id);

		static void ResizeEvent(void *data, xdg_toplevel *xdg_toplevel, Int_32 width, Int_32 height, wl_array *states);

		static void CloseEvent(void *data, xdg_toplevel *xdg_toplevel);

		static void SeatCapabilitiesEvent(void *data, wl_seat *seat, UInt_32 capabilities);

		static void PointerMotionEvent(void *data, wl_pointer *pointer, UInt_32 time, wl_fixed_t sx, wl_fixed_t sy);

	public:
		~Window() override;

		Window();

		Window(Window &&win) noexcept;

		Window(const Window &win);

		Window &operator=(Window &&win) noexcept;

		Window &operator=(const Window &win);

		void Create_32(const Str_32& title, const Vec2_s32& pos, Vec2_u32 scale) override;

		void Create_16(const Str_16& title, const Vec2_s32& pos, Vec2_u32 scale) override;

		void Create_8(const Str_8& title, const Vec2_s32& pos, Vec2_u32 scale) override;

		void OnCreated() override;

		void Close() override;

		void Show() override;

		void Hide() override;

		bool Poll() override;

		void ShowCursor(bool toggle) override;

		void ConstrainCursor(const bool constrain) override;

		void SetTitle_32(const Str_32& newTitle) override;

		Str_32 GetTitle_32() const override;

		void SetTitle_16(const Str_16& newTitle) override;

		Str_16 GetTitle_16() const override;

		void SetTitle_8(const Str_8& newTitle) override;

		Str_8 GetTitle_8() const override;

		void SetPos(const Vec2_s32& newPos) override;

		Vec2_s32 GetPos() const override;

		void SetScale(const Vec2_u32& newScale) override;

		Vec2_u32 GetScale() const override;

		Serializer<UInt_64> GetClipboard() override;

		void SetClipboard(Serializer<UInt_64> data) override;

		void SetCursorImg(const CursorImg img) override;
	};
}