#pragma once

#include <SDL2/SDL_render.h> // for SDL_Renderer
#include <SDL2/SDL_stdinc.h> // for Uint8
#include <string>			 // for string
#include <memory>
#include "utils.h"
#include "sprite.h"
#include "texture.h"

#define TXT_COLOR 1
#define TXT_SHADOW 2
#define TXT_CENTER 4
#define TXT_STROKE 8

struct offset_t
{
	int x, y, w;
};

struct textFile_t
{
	int boxWidth;		  // Anchura de la caja de cada caracter en el png
	int boxHeight;		  // Altura de la caja de cada caracter en el png
	offset_t offset[128]; // Vector con las posiciones y ancho de cada letra
};

// Llena una estructuta textFile_t desde un fichero
textFile_t LoadTextFile(std::string file);

// Clase texto. Pinta texto en pantalla a partir de un bitmap
class Text
{
private:
	// Objetos y punteros
	std::unique_ptr<Sprite> sprite;	  // Objeto con los graficos para el texto
	std::shared_ptr<Texture> texture; // Textura con los bitmaps del texto

	// Variables
	int boxWidth;		  // Anchura de la caja de cada caracter en el png
	int boxHeight;		  // Altura de la caja de cada caracter en el png
	bool fixedWidth;	  // Indica si el texto se ha de escribir con longitud fija en todas las letras
	offset_t offset[128]; // Vector con las posiciones y ancho de cada letra

public:
	// Constructor
	Text(std::string bitmapFile, std::string textFile, SDL_Renderer *renderer);
	Text(std::string textFile, std::shared_ptr<Texture> texture);
	Text(textFile_t *textFile, std::shared_ptr<Texture> texture);

	// Destructor
	~Text() = default;

	// Escribe el texto en pantalla
	void write(int x, int y, std::string text, int kerning = 1, int lenght = -1);

	// Escribe el texto con colores
	void writeColored(int x, int y, std::string text, Color color, int kerning = 1, int lenght = -1);

	// Escribe el texto con sombra
	void writeShadowed(int x, int y, std::string text, Color color, Uint8 shadowDistance = 1, int kerning = 1, int lenght = -1);

	// Escribe el texto centrado en un punto x
	void writeCentered(int x, int y, std::string text, int kerning = 1, int lenght = -1);

	// Escribe texto con extras
	void writeDX(Uint8 flags, int x, int y, std::string text, int kerning = 1, Color textColor = {255, 255, 255}, Uint8 shadowDistance = 1, Color shadowColor = {0, 0, 0}, int lenght = -1);

	// Obtiene la longitud en pixels de una cadena
	int lenght(std::string text, int kerning = 1);

	// Devuelve el valor de la variable
	int getCharacterSize() const;

	// Recarga la textura
	void reLoadTexture();

	// Establece si se usa un tamaño fijo de letra
	void setFixedWidth(bool value);

	// Carga una paleta de colores para el texto
	void addPalette(std::string path);

	// Establece una paleta de colores para el texto
	void setPalette(int index);
};