#pragma once

#include "Primitives.h"

#include <vector>
#include <vulkan/vulkan_core.h>

#define GLFW_INCLUDE_VULKAN
#include <GLFW/glfw3.h>

struct FVertexBufferConfig
{
	VkDevice		 Device;
	VkPhysicalDevice PhysicalDevice;
	VkCommandPool	 CommandPool;
	VkQueue			 GraphicsQueue;
};

class VulkanVertexBuffer
{
public:
	void Initialize(FVertexBufferConfig InConfig);

	void Cleanup(const uint32_t MAX_FRAMES_IN_FLIGHT);

	void CreateBuffer(VkDeviceSize Size, VkBufferUsageFlags Usage, VkMemoryPropertyFlags Properties, VkBuffer& Buffer, VkDeviceMemory& BufferMemory);

	void CopyBuffer(VkBuffer SrcBuffer, VkBuffer DstBuffer, VkDeviceSize Size);

	void CreateVertexBuffer(const std::vector<Vertex>& InVertices);

	void CreateIndexBuffer(const std::vector<uint16_t>& InIndices);

	void CreateUniformBuffers(const uint32_t MAX_FRAMES_IN_FLIGHT);

	uint32_t FindMemoryType(uint32_t TypeFilter, VkMemoryPropertyFlags Properties);

	VkBuffer			  GetVertexBuffer() { return VertexBuffer; }
	VkBuffer			  GetIndexBuffer() { return IndexBuffer; }
	std::vector<VkBuffer> GetUniformBuffers() { return UniformBuffers; }
	std::vector<void*>	  GetUniformBuffersMapped() { return UniformBuffersMapped; }

private:
	FVertexBufferConfig Config;

	VkBuffer	   VertexBuffer;
	VkDeviceMemory VertexBufferMemory;

	VkBuffer	   IndexBuffer;
	VkDeviceMemory IndexBufferMemory;

	std::vector<VkBuffer>		UniformBuffers;
	std::vector<VkDeviceMemory> UniformBuffersMemory;
	std::vector<void*>			UniformBuffersMapped;
};
