#pragma once

#include <SDL2/SDL_events.h>         // para SDL_ControllerButtonEvent
#include <SDL2/SDL_gamecontroller.h> // para SDL_GameControllerButton
#include <memory>                    // para shared_ptr, unique_ptr
#include <string>                    // para string
#include <vector>                    // para vector
class Input;
class Text;
enum class InputType : int;

struct DefineButtonsButton
{
    std::string label;               // Texto en pantalla para el botón
    InputType input;                 // Input asociado
    SDL_GameControllerButton button; // Botón del mando correspondiente

    // Constructor
    DefineButtonsButton(const std::string &lbl, InputType inp, SDL_GameControllerButton btn)
        : label(lbl), input(inp), button(btn) {}
};

// Clase Bullet
class DefineButtons
{
private:
    // Objetos
    Input *input_;               // Objeto pata gestionar la entrada
    std::shared_ptr<Text> text_; // Objeto para escribir texto

    // Variables
    bool enabled_ = false;                      // Indica si el objeto está habilitado
    int x_;                                     // Posición donde dibujar el texto
    int y_;                                     // Posición donde dibujar el texto
    std::vector<DefineButtonsButton> buttons_;  // Vector con las nuevas definiciones de botones/acciones
    size_t index_controller_ = 0;               // Indice del controlador a reasignar
    size_t index_button_ = 0;                   // Indice para saber qué botón se está definiendo
    std::vector<std::string> controller_names_; // Nombres de los mandos

    // Incrementa el indice de los botones
    void incIndexButton();

    // Comprueba el botón que se ha pulsado
    void doControllerButtonDown(SDL_ControllerButtonEvent &event);

    // Asigna los botones definidos al input
    void bindButtons();

    // Guarda los cambios en las opciones
    void saveBindingsToOptions();

    // Comprueba que un botón no esté ya asignado
    bool checkButtonNotInUse(SDL_GameControllerButton button);

    // Limpia la asignación de botones
    void clearButtons();

public:
    // Constructor
    explicit DefineButtons(std::unique_ptr<Text> text);

    // Destructor
    ~DefineButtons() = default;

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

    // Comprueba los eventos
    void checkEvents();

    // Habilita el objeto
    bool enable(int index);

    // Comprueba si está habilitado
    bool isEnabled();
};