// =====================================================================================================================
//  fennec, a free and open source game engine
//  Copyright © 2025  Medusa Slockbower
//
//  This program is free software: you can redistribute it and/or modify
//  it under the terms of the GNU General Public License as published by
//  the Free Software Foundation, either version 3 of the License, or
//  (at your option) any later version.
//
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU General Public License for more details.
//
//  You should have received a copy of the GNU General Public License
//  along with this program.  If not, see <https://www.gnu.org/licenses/>.
// =====================================================================================================================

#ifndef FENNEC_PLATFORM_INTERFACE_WINDOW_H
#define FENNEC_PLATFORM_INTERFACE_WINDOW_H

#include <fennec/containers/optional.h>
#include <fennec/langproc/strings/string.h>
#include <fennec/platform/interface/fwd.h>

namespace fennec
{

///
/// \brief interface for handling windows
/// \details the interface makes no guarantees about the bit-depth and is completely dependent on the implementation.
class window {
public:
	enum class fullscreen_mode {
		windowed = 0,
		borderless,
		fullscreen
	};

	enum flags_ : uint32_t {
		flags_none              = 0,
		flags_child             = 0x1 << 0,
		flags_modal             = 0x1 << 1,
		flags_grab_mouse        = 0x1 << 2,
		flags_grab_keyboard     = 0x1 << 3,
		flags_block_screensaver = 0x1 << 4,
	};

	struct config {
		string title;
		uint32_t flags;
		size_t width, height;
		fullscreen_mode fullscreen;
	};

	virtual bool running() = 0;
	virtual void configure(const config& config) = 0;
	virtual bool initialize(bool modal) = 0;
	virtual bool shutdown() = 0;

	virtual bool set_title(const cstring& title) = 0;
	virtual bool set_title(const string& title) = 0;

	virtual bool set_width(size_t w) = 0;
	virtual bool set_height(size_t h) = 0;
	virtual bool set_size(size_t w, size_t h) = 0;

	virtual bool set_fullscreen_mode(fullscreen_mode mode) = 0;

	virtual bool set_resizable(bool e) = 0;

	virtual bool grab_keyboard(bool e) = 0;
	virtual bool grab_mouse(bool e) = 0;
	virtual bool block_screensaver(bool e) = 0;

	bool is_child() const {
		if (not _config) return false;
		return _config->flags & flags_child;
	}

	bool is_modal() const {
		if (not _config) return false;
		return _config->flags & flags_modal;
	}

	display* get_display() {
		return _display;
	}

	const display* get_display() const {
		return _display;
	}


	const string& get_title() const {
		static const string _null = { "null" };
		if (not _config) return _null;
		return _config->title;
	}


	size_t get_width() const {
		if (not _config) return false;
		return _config->width;
	}

	size_t get_height() const {
		if (not _config) return false;
		return _config->height;
	}


	fullscreen_mode get_fullscreen_mode() const {
		if (not _config) return fullscreen_mode::windowed;
		return _config->fullscreen;
	}


	bool is_keyboard_grabbed() const {
		if (not _config) return false;
		return _config->flags & flags_grab_keyboard;
	}

	bool is_mouse_grabbed() const {
		if (not _config) return false;
		return _config->flags & flags_grab_mouse;
	}

	bool is_screensaver_blocked() const {
		if (not _config) return false;
		return _config->flags & flags_block_screensaver;
	}

	template<class DisplayT>
	DisplayT* get_display() {
		return static_cast<DisplayT*>(_display);
	}

protected:
	virtual ~window() = default;
	window(display* display, window* parent);

	display*         _display;
	window*          _parent;
	optional<config> _config;
	gfxsurface*      _context;

private:
};

}

#endif // FENNEC_PLATFORM_INTERFACE_WINDOW_H
