#pragma once

#include <psemek/wgpu/chained_struct.hpp>
#include <psemek/wgpu/surface.hpp>
#include <psemek/wgpu/adapter.hpp>
#include <psemek/wgpu/detail/object.hpp>

namespace psemek::wgpu
{

	struct instance
		: detail::object<instance>
	{
		using detail::object<instance>::object;

		// TODO: add WGPUFuture stuff when it's supported in wgpu-native

		enum class feature : std::uint32_t
		{
			timed_wait_any = 0x00000001,
			shader_source_spirv = 0x00000002,
			multiple_devices_per_adapter = 0x00000003,
		};

		struct limits
		{
			std::size_t timed_wait_any_max_count;
		};

		struct descriptor
		{
			std::vector<chained_struct> chain = {};
			std::vector<feature> required_features = {};
			std::optional<limits> required_limits = {};
		};

		static std::vector<feature> get_features();
		static limits get_limits();

		static instance create(descriptor const & desc);

		void process_events();
		surface create_surface(surface::descriptor const & desc);
		void request_adapter(callback_mode mode, adapter::request_options const & request_options, adapter::request_callback callback);

		static void reference(void * ptr);
		static void release(void * ptr);

	private:
		explicit instance(void * ptr)
			: detail::object<instance>(ptr)
		{}
	};

}
