#pragma once

#include <SDL2/SDL.h>
#include "utils.h"
#include "text.h"
#include "input.h"

#ifndef ON_SCREEN_KEYBOARD_H
#define ON_SCREEN_KEYBOARD_H

#define USE_UPPER 1
#define USE_LOWER 2
#define USE_NUMBER 4
#define USE_SYMBOL 8

using namespace std;

class OnScreenKeyboard
{
private:
	// Objetos y punteros
	SDL_Renderer *renderer;		// El renderizador de la ventana
	Text *text;					// Objeto para dibujar texto
	Input *input;				// Gestor de eventos de entrada de teclado o gamepad
	options_t *options;			// Variable con todas las opciones del programa
	SDL_Texture *texture;		// Textura donde dibujar el objeto
	SDL_Texture *textureCursor; // Textura para dibujar el cursor

	// Estructuras
	struct key_t
	{
		int col;		// Posición horizontal de la tecla
		int row;		// Posición vertical de la tecla
		string caption; // Texto de la tecla
	};

	struct cursor_t
	{
		int col;
		int row;
		SDL_Rect dest;
	};

	// Variables
	string char_upper;	   // Cadena de texto con las letras en mayúscula
	string char_lower;	   // Cadena de texto con las letras en minuscula
	string char_numbers;   // Cadena de texto con los números
	string char_symbol;	   // Cadena de texto con los símbolos
	bool use_char_upper;   // Indica si se utilizará ese set de caracteres
	bool use_char_lower;   // Indica si se utilizará ese set de caracteres
	bool use_char_numbers; // Indica si se utilizará ese set de caracteres
	bool use_char_symbol;  // Indica si se utilizará ese set de caracteres
	int totalChars;		   // Cantidad de caracteres a utilizar
	int columns;		   // Cantidad de caracteres que hay en una fila del teclado
	int rows;			   // Cantidad de filas de caracteres que tendrá el teclado
	color_t bgColor;	   // Color usado para el fondo
	string caption;		   // Texto a mostrar junto al texto a introducir
	int width;			   // Ancho del objeto
	int height;			   // Altura del objeto
	SDL_Rect dest;		   // Coordenadas donde se dibuja el objeto en pantalla
	vector<key_t> layout;  // Contiene la disposición del teclado
	cursor_t cursor;	   // Variable para gestionar el cursor
	string output;		   // Texto de salida
	SDL_Rect outputDest;   // Rectangulo con el texto de salida

	// Rellena la textura de fondo con el color y el texto
	void fillTexture();

	// Calcula cuantos caracteres se utilizaran para crear el teclado
	int getTotalChars();

	// Calcula cuantas columnas necesita el teclado
	int getColumns();

	// Calcula cuantas filas necesita el teclado
	int getRows();

	// Establece la disposición del teclado
	void setLayout();

	// Comprueba las entradas
	void checkInput();

	// Disminuye en una columna la posición del cursor
	void decCursorCol();

	// Incrementa en una columna la posición del cursor
	void incCursorCol();

	// Disminuye en una fila la posición del cursor
	void decCursorRow();

	// Aumenta en una columna la posición del cursor
	void incCursorRow();

	// Actualiza la posición de la textura del cursor
	void updateCursor();

	// Añade un caracter a la salida
	void addChar();

	// Borra el último caracter de la salida
	void removeChar();

public:
	// Constructor
	OnScreenKeyboard(SDL_Renderer *renderer, Input *input, string bitmapFile, string textFile, options_t *options, int width, int height, string output = "", color_t color = {0, 0, 0});

	// Destructor
	~OnScreenKeyboard();

	// Actualiza la lógica del objeto
	void update();

	// Dibuja el objeto en pantalla
	void render();

	// Establece el color de fondo
	void setBgColor(color_t color);

	// Establece el texto a mostrar junto al texto a introducir
	void setCaption(string text);

	// Establece qué caracteres ofrecerá el objeto
	void setChars(Uint8 mode);
};

#endif