#pragma once

#include <SDL3/SDL.h>

#include <memory>     // Para shared_ptr
#include <string>     // Para string
#include <vector>     // Para vector
class SurfaceSprite;  // lines 8-8
class Surface;        // lines 9-9

class Ending {
    private:
        // Estructuras
        struct EndingSurface  // Estructura con dos texturas y sprites, uno para mostrar y el otro hace de cortinilla
        {
                std::shared_ptr<Surface> image_surface;       // Surface a mostrar
                std::shared_ptr<SurfaceSprite> image_sprite;  // SSprite para mostrar la textura
                std::shared_ptr<Surface> cover_surface;       // Surface que cubre a la otra textura
                std::shared_ptr<SurfaceSprite> cover_sprite;  // SSprite para mostrar la textura que cubre a la otra textura
                int cover_clip_desp;                          // Desplazamiento del spriteClip de la textura de cobertura
                int cover_clip_height;                        // Altura del spriteClip de la textura de cobertura
        };

        struct TextAndPosition  // Estructura con un texto y su posición en el eje Y
        {
                std::string caption;  // Texto
                int pos;              // Posición
        };

        struct TextIndex {
                int index;
                int trigger;
        };

        struct SceneData  // Estructura para crear cada una de las escenas del final
        {
                std::vector<TextIndex> text_index;  // Indices del vector de textos a mostrar y su disparador
                int picture_index;                  // Indice del vector de imagenes a mostrar
                int counter_end;                    // Valor del contador en el que finaliza la escena
        };

        // Objetos y punteros
        std::shared_ptr<Surface> cover_surface_;  // Surface para cubrir el texto

        // Variables
        int counter_;                              // Contador
        int pre_counter_;                          // Contador previo
        int cover_counter_;                        // Contador para la cortinilla
        Uint32 ticks_;                             // Contador de ticks para ajustar la velocidad del programa
        std::vector<EndingSurface> sprite_texts_;  // Vector con los sprites de texto con su cortinilla
        std::vector<EndingSurface> sprite_pics_;   // Vector con los sprites de texto con su cortinilla
        int current_scene_;                        // Escena actual
        std::vector<SceneData> scenes_;            // Vector con los textos e imagenes de cada escena

        // Actualiza el objeto
        void update();

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

        // Comprueba el manejador de eventos
        static void checkEvents();

        // Comprueba las entradas
        static void checkInput();

        // Inicializa los textos
        void iniTexts();

        // Inicializa las imagenes
        void iniPics();

        // Inicializa las escenas
        void iniScenes();

        // Actualiza los contadores
        void updateCounters();

        // Actualiza las cortinillas de los elementos
        void updateSpriteCovers();

        // Comprueba si se ha de cambiar de escena
        void checkChangeScene();

        // Rellena la textura para la cortinilla
        void fillCoverTexture();

        // Dibuja la cortinilla de cambio de escena
        void renderCoverTexture();

        // Actualiza el volumen de la musica
        void updateMusicVolume() const;

    public:
        // Constructor
        Ending();

        // Destructor
        ~Ending() = default;

        // Bucle principal
        void run();
};