#pragma once

#include <SDL2/SDL_rect.h>   // for SDL_Rect
#include <SDL2/SDL_render.h> // for SDL_Texture
#include <vector>            // for vector
#include <memory>
#include "sprite.h"                // lines 10-10
#include "text.h"

enum class OnScreenHelpStatus
{
    hidden,
    showing,
    entering,
    exitting,
};

// Classe on_screen_help
class OnScreenHelp
{
private:
    // [SINGLETON] Objeto screen privado para Don Melitón
    static OnScreenHelp *onScreenHelp;

    SDL_Texture *texture;      // Textura donde dibujar
    SDL_Rect dest;             // Posición donde dibujar la textura;
    int hiddenPos, showingPos; // Las dos posiciones donde colocar la textura

    OnScreenHelpStatus state; // Estado del objeto
    std::vector<int> path;    // Puntos por donde pasa la animación de la tarjeta
    int index;                // Indice para recorrer la animación

    // [SINGLETON] Ahora el constructor y el destructor son privados, para no poder crear objetos screen desde fuera

    // Constructor
    OnScreenHelp();

    // Destructor
    ~OnScreenHelp();

    // Rellena la textura con los gráficos y texto
    void fillTexture();

    // Define el ancho y alto de la textura
    void setSize();

    // Calcula la longitud en pixels del texto más largo
    auto getLargestStringSize() -> int const;

    // Renderizara el boton y el texto
    void renderButton(Sprite *sprite, Text *text, const SDL_Rect &buttonClip, const SDL_Rect &buttonPos, int textId);

    // Actualiza la posición
    void updatePosition();

    // Rellena los puntos por donde pasa la animación
    void precalculatePath(double start, double end, int steps);

public:
    // [SINGLETON] Crearemos el objeto screen con esta función estática
    static void init();

    // [SINGLETON] Destruiremos el objeto screen con esta función estática
    static void destroy();

    // [SINGLETON] Con este método obtenemos el objeto screen y podemos trabajar con él
    static OnScreenHelp *get();

    // Actualiza la lógica interna
    void update();

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

    // Activa o desactiva el objeto
    void toggleState();
};