#pragma once

#include <SDL3/SDL_stdinc.h> // Para Uint8
#include <memory>			 // Para unique_ptr, shared_ptr
#include <string>			 // Para string
#include "sprite.h"			 // Para Sprite
#include "utils.h"			 // Para Color

class Texture;

// --- Constantes para flags de texto ---
constexpr int TEXT_COLOR = 1;
constexpr int TEXT_SHADOW = 2;
constexpr int TEXT_CENTER = 4;
constexpr int TEXT_STROKE = 8;

// --- Estructuras auxiliares ---
struct TextOffset
{
	int x, y, w;
};

struct TextFile
{
	int box_width;			// Anchura de la caja de cada caracter en el png
	int box_height;			// Altura de la caja de cada caracter en el png
	TextOffset offset[128]; // Vector con las posiciones y ancho de cada letra
};

// Llena una estructura TextFile desde un fichero
std::shared_ptr<TextFile> loadTextFile(const std::string &file_path);

// --- Clase Text: pinta texto en pantalla a partir de un bitmap ---
class Text
{
public:
	// --- Constructores y destructor ---
	Text(std::shared_ptr<Texture> texture, const std::string &text_file);
	Text(std::shared_ptr<Texture> texture, std::shared_ptr<TextFile> text_file);
	~Text() = default;

	// --- Métodos de escritura en pantalla ---
	void write(int x, int y, const std::string &text, int kerning = 1, int lenght = -1); // Escribe el texto en pantalla
	void write2X(int x, int y, const std::string &text, int kerning = 1);				 // Escribe el texto al doble de tamaño

	// --- Escritura en textura ---
	std::shared_ptr<Texture> writeToTexture(const std::string &text, int zoom = 1, int kerning = 1);																									   // Escribe el texto en una textura
	std::shared_ptr<Texture> writeDXToTexture(Uint8 flags, const std::string &text, int kerning = 1, Color textColor = Color(), Uint8 shadow_distance = 1, Color shadow_color = Color(), int lenght = -1); // Escribe el texto con extras en una textura

	// --- Métodos de escritura avanzada ---
	void writeColored(int x, int y, const std::string &text, Color color, int kerning = 1, int lenght = -1);																				// Escribe el texto con colores
	void writeShadowed(int x, int y, const std::string &text, Color color, Uint8 shadow_distance = 1, int kerning = 1, int lenght = -1);													// Escribe el texto con sombra
	void writeCentered(int x, int y, const std::string &text, int kerning = 1, int lenght = -1);																							// Escribe el texto centrado en un punto x
	void writeDX(Uint8 flags, int x, int y, const std::string &text, int kerning = 1, Color textColor = Color(), Uint8 shadow_distance = 1, Color shadow_color = Color(), int lenght = -1); // Escribe texto con extras

	// --- Utilidades ---
	int lenght(const std::string &text, int kerning = 1) const; // Obtiene la longitud en pixels de una cadena
	int getCharacterSize() const;								// Devuelve el tamaño de caracter actual

	// --- Configuración ---
	void setFixedWidth(bool value); // Establece si se usa un tamaño fijo de letra
	void setPalette(int number);	// Establece una paleta

private:
	// --- Objetos y punteros ---
	std::unique_ptr<Sprite> sprite_ = nullptr; // Objeto con los gráficos para el texto

	// --- Variables ---
	int box_width_ = 0;			  // Anchura de la caja de cada caracter en el png
	int box_height_ = 0;		  // Altura de la caja de cada caracter en el png
	bool fixed_width_ = false;	  // Indica si el texto se ha de escribir con longitud fija en todas las letras
	TextOffset offset_[128] = {}; // Vector con las posiciones y ancho de cada letra
};