#pragma once

#include <SDL3/SDL.h>

#include <string>  // for string, basic_string

// 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 {
    int x;
    int y;
    int r;
};

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

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

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

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

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

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

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

// Estructura para mapear el teclado usado en la demo
struct DemoKeys {
    Uint8 left;
    Uint8 right;
    Uint8 no_input;
    Uint8 fire;
    Uint8 fire_left;
    Uint8 fire_right;
};

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

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

// Detector de colisiones entre dos circulos
auto checkCollision(const Circle &a, const Circle &b) -> bool;

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

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

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

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

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

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

// Detector de colisiones entre dos lineas
auto checkCollision(const Line &l1, const Line &l2) -> SDL_Point;

// Detector de colisiones entre dos lineas
auto checkCollision(const DiagonalLine &l1, const VerticalLine &l2) -> SDL_Point;

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

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

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

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

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