#pragma once
#include <filesystem>
#include <string>
#include <vector>

#include "Deer/Path.h"

#define DEER_SCENE_PATH "scenes"
#define DEER_SCRIPT_PATH "scripts"
#define DEER_SHADER_PATH "shaders"
#define DEER_VOXEL_PATH "voxels"
#define DEER_VOXEL_DATA_PATH "voxels/data"
#define DEER_VOXEL_ASPECT_PATH "voxels/aspect"
#define DEER_VOXEL_TEXTURE_PATH "voxels/textures"
#define DEER_VOXEL_SHADER_PATH "voxels/shaders"
#define DEER_EDITOR_PATH "Editor"
#define DEER_MESH_PATH "meshes"

#define DEER_MESH_EXTENSION ".dmesh"
#define DEER_SHADER_EXTENSION ".glsl"
#define DEER_SCRIPT_EXTENSION ".as"

#define DEER_BIN_PATH "bin"
#define DEER_TEMP_PATH "tmp"
#define DEER_NULL_PATH "null"

namespace Deer {
	struct DirectoryData {
		std::vector<Path> dirs;
		std::vector<Path> elements;
	};

	// Namespace to manage memory interactions
	namespace DataStore {
		// Clears the cache of dir data
		void clearCache();

		// Rerturns a directory data with the elements relative to the id
		const DirectoryData& getDirData(const Path& id, const Path& dir, const char* extension);

		// TODO: Add safety
		// Returns the data of the specified file path
		bool loadFileData(const Path& id, const Path& name, uint8_t** data, uint32_t* size);
		// Returns the data of the specified file path avoiding extension
		bool loadGlobalFileData(const Path& id, const Path& name, uint8_t** data, uint32_t* size);
		void freeFileData(uint8_t*);
		
		void createFolder(const Path& path);

		void saveFile(const Path&, uint8_t* data, uint32_t size);
		uint8_t* readFile(const Path&, uint32_t* size);
		void deleteFile(const Path&);

		// Refactor----
		void compressFiles(std::vector<Path> files, const Path& path);
		std::vector<Path> getFiles(const Path& path,
		                           const std::string& extension);
		// Refactor----

		extern Path rootPath;
	}  // namespace DataStore
}  // namespace Deer