public import includes;
import std.stdio;
import vulkan : Vulkan;
import std.conv;
import std.string;
import core.stdc.string : strlen;

extern(System) VkBool32
DebugCallback(
	VkDebugUtilsMessageSeverityFlagBitsEXT 			message_severity,
	VkDebugUtilsMessageTypeFlagsEXT				 			message_type,
	const VkDebugUtilsMessengerCallbackDataEXT* callback_data,
	void*																				user_data
)
{
	string ms, mt;

	switch (message_severity) {
	case VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT:
		ms = "VERBOSE";
		break;
	case VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT:
		ms = "INFO";
		break;
	case VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT:
		ms = "WARNING";
		break;
	case VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT:
		ms = "ERROR";
		break;
	default: 
		ms = "UNKNOWN";
		break;
	}

	switch (message_type) {
	case VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT:
		mt = "General";
		break;
	case VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT:
		mt = "Validation";
		break;
	case VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT:
		mt = "Validation | General";
		break;
	case VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT:
		mt = "Performance";
		break;
	case VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT:
		mt = "General | Performance";
		break;
	case VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT:
		mt = "Validation | Performance";
		break;
	case VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT:
		mt = "General | Validation | Performance";
		break;
	default:
		mt = "Unknown";
		break;
	}

	const char[] msg = callback_data.pMessage[0 .. strlen(callback_data.pMessage)];
	
	writefln("[%s: %s]\n%r\n", ms, mt, msg);

	return VK_FALSE;
}

string 
VkResultStr(VkResult result) 
{ 
	switch (result) 
	{ 
		case VK_SUCCESS: 
			return "VK_SUCCESS"; 
		case VK_NOT_READY: 
			return "VK_NOT_READY"; 
		case VK_TIMEOUT: 
			return "VK_TIMEOUT"; 
		case VK_EVENT_SET: 
			return "VK_EVENT_SET"; 
		case VK_EVENT_RESET: 
			return "VK_EVENT_RESET"; 
		case VK_INCOMPLETE: 
			return "VK_INCOMPLETE"; 
		case VK_ERROR_OUT_OF_HOST_MEMORY: 
			return "VK_ERROR_OUT_OF_HOST_MEMORY"; 
		case VK_ERROR_OUT_OF_DEVICE_MEMORY: 
			return "VK_ERROR_OUT_OF_DEVICE_MEMORY"; 
		case VK_ERROR_INITIALIZATION_FAILED: 
			return "VK_ERROR_INITIALIZATION_FAILED"; 
		case VK_ERROR_DEVICE_LOST: 
			return "VK_ERROR_DEVICE_LOST"; 
		case VK_ERROR_MEMORY_MAP_FAILED: 
			return "VK_ERROR_MEMORY_MAP_FAILED"; 
		case VK_ERROR_LAYER_NOT_PRESENT: 
			return "VK_ERROR_LAYER_NOT_PRESENT"; 
		case VK_ERROR_EXTENSION_NOT_PRESENT: 
			return "VK_ERROR_EXTENSION_NOT_PRESENT"; 
		case VK_ERROR_FEATURE_NOT_PRESENT: 
			return "VK_ERROR_FEATURE_NOT_PRESENT"; 
		case VK_ERROR_INCOMPATIBLE_DRIVER: 
			return "VK_ERROR_INCOMPATIBLE_DRIVER"; 
		case VK_ERROR_TOO_MANY_OBJECTS: 
			return "VK_ERROR_TOO_MANY_OBJECTS"; 
		case VK_ERROR_FORMAT_NOT_SUPPORTED: 
			return "VK_ERROR_FORMAT_NOT_SUPPORTED"; 
		case VK_ERROR_FRAGMENTED_POOL: 
			return "VK_ERROR_FRAGMENTED_POOL"; 
		case VK_ERROR_UNKNOWN: 
			return "VK_ERROR_UNKNOWN"; 
		case VK_ERROR_OUT_OF_POOL_MEMORY: 
			return "VK_ERROR_OUT_OF_POOL_MEMORY"; 
		case VK_ERROR_INVALID_EXTERNAL_HANDLE: 
			return "VK_ERROR_INVALID_EXTERNAL_HANDLE"; 
		case VK_ERROR_FRAGMENTATION: 
			return "VK_ERROR_FRAGMENTATION"; 
		case VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS: 
			return "VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS"; 
		case VK_PIPELINE_COMPILE_REQUIRED: 
			return "VK_PIPELINE_COMPILE_REQUIRED"; 
		case VK_ERROR_SURFACE_LOST_KHR: 
			return "VK_ERROR_SURFACE_LOST_KHR"; 
		case VK_ERROR_NATIVE_WINDOW_IN_USE_KHR: 
			return "VK_ERROR_NATIVE_WINDOW_IN_USE_KHR"; 
		case VK_SUBOPTIMAL_KHR: 
			return "VK_SUBOPTIMAL_KHR"; 
		case VK_ERROR_OUT_OF_DATE_KHR: 
			return "VK_ERROR_OUT_OF_DATE_KHR"; 
		case VK_ERROR_INCOMPATIBLE_DISPLAY_KHR: 
			return "VK_ERROR_INCOMPATIBLE_DISPLAY_KHR"; 
		case VK_ERROR_VALIDATION_FAILED_EXT: 
			return "VK_ERROR_VALIDATION_FAILED_EXT"; 
		case VK_ERROR_INVALID_SHADER_NV: 
			return "VK_ERROR_INVALID_SHADER_NV"; 
		case VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT: 
			return "VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT"; 
		case VK_ERROR_NOT_PERMITTED_KHR: 
			return "VK_ERROR_NOT_PERMITTED_KHR"; 
		case VK_ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT: 
			return "VK_ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT"; 
		case VK_THREAD_IDLE_KHR: 
			return "VK_THREAD_IDLE_KHR"; 
		case VK_THREAD_DONE_KHR: 
			return "VK_THREAD_DONE_KHR"; 
		case VK_OPERATION_DEFERRED_KHR: 
			return "VK_OPERATION_DEFERRED_KHR"; 
		case VK_OPERATION_NOT_DEFERRED_KHR: 
			return "VK_OPERATION_NOT_DEFERRED_KHR"; 
		case VK_ERROR_COMPRESSION_EXHAUSTED_EXT: 
			return "VK_ERROR_COMPRESSION_EXHAUSTED_EXT"; 
		case VK_RESULT_MAX_ENUM: 
			return "VK_RESULT_MAX_ENUM"; 
		default: 
			return "UNKNOWN"; 
	} 
}
