#pragma once
#include "../vulkan.h"

namespace vulkanapi {
	class Device;
	class Instance;
	class DeviceCreator {
		friend class Device;
	private:
		class DesiredQueue final
		{
		public:
			const string& name;
			VkQueueFlags flag;
			float prioritie;
			int queueFamilyIndex;
			DesiredQueue(const string& name, VkQueueFlags flag, float prioritie)
				: name(name), flag(flag), prioritie(prioritie), queueFamilyIndex(0){}
		};
	public:
		VkPhysicalDeviceFeatures desiredPhysicalDeviceFeatures;
		VkPhysicalDeviceType desiredPhysicalDeviceType;
		vector<string> desiredExtensions;
		vector<DesiredQueue> desiredQueues;
	public:
		Instance& instance;

	public:
		DeviceCreator(Instance& instance);
		void AddQueue(const string& name, VkQueueFlags flag, float prioritie);
		void AddExtension(string extensionName);
		void AddWindowExtension();
		bool CheckProperty(const VkPhysicalDevice device);
		bool CheckExtension(const VkPhysicalDevice device);
		bool FindDevice(VkPhysicalDevice& device);
		vector<char const*> EnabledExtensionNames();
		void QueueCreateInfos(vector<VkDeviceQueueCreateInfo>& queue_create_infos,
			vector<vector<float>>& queue_prioritie,
			vector<VkQueueFamilyProperties>& queue_families);
		void EnableDeviceFeatures();
		VkPhysicalDeviceFeatures2 GetDeviceFeature2();
		VkPhysicalDeviceVulkan12Features GetVulkan12Features();
#ifdef Z_USE_GRAPHIC_DEBUG
	public:
		vector<string> desiredLayers;
		void AddLayer(string layerName);
		bool CheckLayer(const VkPhysicalDevice device);
		vector<char const*> EnabledLayerNames();
#endif
	private:
		static bool CheckAvailableQueueFamilies(VkPhysicalDevice physical_device, vector<VkQueueFamilyProperties>& queue_families);
	};
};