#ifndef _H_FTFONT_H
#define _H_FTFONT_H

#include <ft2build.h>
#include FT_FREETYPE_H

#include <thirdparty/glad/glad.h>
#include <filesystem>
#include <format>
#include <glm/glm.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <map>
#include <mutex>
#include <unordered_map>

#define DEBUG_TEXT(pos_vec2, col_vec4, scale, text, ...) DebugText::getInstance()->DrawDebugText(pos_vec2, col_vec4, scale, text, __VA_ARGS__)

class Text {
protected:
	struct Font {
		struct Character {
			unsigned int TextureID;
			glm::ivec2 Size;
			glm::ivec2 Bearing;
			unsigned int Advance;
		};
		std::map<char, Character> characters;
	};

	std::unordered_map<std::string, Font> fonts;
	unsigned int programID = 0;
	unsigned int VAO = 0, VBO = 0;
	unsigned int colorPos = 0;

public:
	Text();
	bool loadFonts(const std::string& font_folder);

	void DrawText(
		const std::string& fontName, 
		const std::string& text, 
		const glm::vec2& position,
		float scale, 
		const glm::vec4& color = glm::vec4(0.0f, 0.0f, 0.0f, 1.0f)
	);
	void DrawTextOutline(
		const std::string& fontName, 
		const std::string& text, 
		const glm::vec2& position,
		float scale, 
		const glm::vec4& color = glm::vec4(0.0f, 0.0f, 0.0f, 1.0f)
	);
	~Text() { };
};

class DebugText : public Text {
public:
	static DebugText* getInstance();
	bool loadFonts(const std::string &font_folder) = delete;
	DebugText(DebugText const&) = delete;
	void operator=(DebugText const&) = delete;
	
	template<typename... Args>
	void DrawDebugText(const glm::vec2& pos, 
							  const glm::vec4& color, 
							  const float scale,
							  const std::string& text, 
							  Args... args) 
	{
		DrawText(pos, color, scale, formatString(text, args...));
	}

	
private:
	static std::mutex mutex;
	static DebugText *instance;
	Font font;
	DebugText();
	void loadDebugFont();
	~DebugText();

	template <typename... Args>
	std::string formatString(const std::string& str, Args... args) const
	{
		return std::vformat(str, std::make_format_args(args...));
	}
	void DrawText(const glm::vec2& pos, 
							  const glm::vec4& color, 
							  const float scale,
							  const std::string& text);
	
};

#endif // _H_FTFONT_H
