#pragma once

#include <string>
#include <map>
#include <memory>
#include <vector>
#include <glm/glm.hpp>
#include <boost/noncopyable.hpp>
#include "Shader.hpp"

namespace ftgl
{
	struct texture_atlas_t;
	struct texture_font_t;
};

struct FontDescription
{
	std::string Filename;
	float Size;

	bool operator<(const FontDescription& val) const
	{
		if(Size != val.Size)
			return Size < val.Size;
		return Filename < val.Filename;
	}
};

class Text;

/// manages all existing Text-Objects and renders them in an efficient way
class TextManager : public boost::noncopyable
{
public:
	TextManager(glm::vec2 AtlasSize=glm::vec2(256, 256));
	~TextManager();
	void AddFont(std::string Filename, float Size);
	Text* NewText(std::string text, glm::vec2 Position, float Size = 0, std::string FontFile = "");
	void SetScreenSize(glm::vec2 size)	{	m_ScreenSize = size;	}

	void RenderAll();
private:
	glm::vec2 m_ScreenSize=glm::vec2(1024, 768);
	ftgl::texture_atlas_t* m_Atlas;
	std::map<FontDescription, ftgl::texture_font_t*> m_Fonts;
	std::vector<std::unique_ptr<Text>> m_Texts;
	Shader m_Shader;
};

/// object to manage a single text. The text is an UTF8-String, so Unicode is supported
class Text
{
public:
	/// should only be used by TextManager::NewText()
	Text(std::string text, glm::vec2 Position, ftgl::texture_font_t* Font);
	~Text();

	void SetText(std::string Text);
	void AddText(std::string Text);
	std::string GetText();

	/// should only be used by TextManager::RenderAll()
	void DrawCall();
	glm::vec2 GetScreenPosition() { return m_ScreenPosition; }
	void SetScreenPosition(glm::vec2 p) { m_ScreenPosition = p; }
private:
	glm::vec2 m_ScreenPosition;
	std::string m_CurrentText;
	ftgl::texture_font_t* m_Font;

	std::vector<glm::vec2> m_Positions;
	std::vector<glm::vec2> m_UVs;

	unsigned int m_PositionBuffer;
	unsigned int m_UVBuffer;
	unsigned int m_VAO;
};


