#pragma once

#include <SDL3/SDL.h>

#include <string>  // for string, basic_string
#include <vector>  // for vector

// Dificultad del juego
constexpr int DIFFICULTY_EASY = 0;
constexpr int DIFFICULTY_NORMAL = 1;
constexpr int DIFFICULTY_HARD = 2;

// Estructura para definir un circulo
struct circle_t {
    int x;
    int y;
    int r;
};

// Estructura para definir una linea horizontal
struct h_line_t {
    int x1, x2, y;
};

// Estructura para definir una linea vertical
struct v_line_t {
    int x, y1, y2;
};

// Estructura para definir una linea diagonal
struct d_line_t {
    int x1, y1, x2, y2;
};

// Estructura para definir una linea
struct line_t {
    int x1, y1, x2, y2;
};

// Estructura para definir un color
struct color_t {
    Uint8 r;
    Uint8 g;
    Uint8 b;

    color_t()
        : r(0),
          g(0),
          b(0) {}  // Constructor por defecto
    color_t(Uint8 red, Uint8 green, Uint8 blue)
        : r(red),
          g(green),
          b(blue) {}
};

// Tipos de paleta
enum palette_e {
    p_zxspectrum,
    p_zxarne
};

// Estructura para saber la seccion y subseccion del programa
struct section_t {
    Uint8 name;
    Uint8 subsection;
};

// Estructura para mapear el teclado usado en la demo
struct demoKeys_t {
    Uint8 left;
    Uint8 right;
    Uint8 noInput;
    Uint8 fire;
    Uint8 fireLeft;
    Uint8 fireRight;
};

// Estructura para albergar métodos de control
struct input_t {
    int id;            // Identificador en el vector de mandos
    std::string name;  // Nombre del dispositivo
    Uint8 deviceType;  // Tipo de dispositivo (teclado o mando)
};

// Calcula el cuadrado de la distancia entre dos puntos
double distanceSquared(int x1, int y1, int x2, int y2);

// Detector de colisiones entre dos circulos
bool checkCollision(const circle_t &a, const circle_t &b);

// Detector de colisiones entre un circulo y un rectangulo
bool checkCollision(const circle_t &a, const SDL_Rect &b);

// Detector de colisiones entre un dos rectangulos
bool checkCollision(const SDL_Rect &a, const SDL_Rect &b);

// Detector de colisiones entre un punto y un rectangulo
bool checkCollision(const SDL_Point &p, const SDL_Rect &r);

// Detector de colisiones entre una linea horizontal y un rectangulo
bool checkCollision(const h_line_t &l, const SDL_Rect &r);

// Detector de colisiones entre una linea vertical y un rectangulo
bool checkCollision(const v_line_t &l, const SDL_Rect &r);

// Detector de colisiones entre una linea horizontal y un punto
bool checkCollision(const h_line_t &l, const SDL_Point &p);

// Detector de colisiones entre dos lineas
SDL_Point checkCollision(const line_t &l1, const line_t &l2);

// Detector de colisiones entre dos lineas
SDL_Point checkCollision(const d_line_t &l1, const v_line_t &l2);

// Detector de colisiones entre un punto y una linea diagonal
bool checkCollision(const SDL_Point &p, const d_line_t &l);

// Normaliza una linea diagonal
void normalizeLine(d_line_t &l);

// Devuelve un color_t a partir de un string
color_t stringToColor(palette_e pal, const std::string &str);

// Convierte una cadena en un valor booleano
bool stringToBool(const std::string &str);

// Convierte un valor booleano en una cadena
std::string boolToString(bool value);

// Convierte una cadena a minusculas
std::string toLower(const std::string &str);
