#pragma once

#include <SDL2/SDL_rect.h> // Para SDL_Rect
#include <memory>          // Para shared_ptr
#include <string>          // Para string
#include <vector>          // Para vector
#include "moving_sprite.h" // Para MovingSprite
class Texture;             // lines 9-9

struct Animation
{
    std::string name;             // Nombre de la animacion
    std::vector<SDL_Rect> frames; // Cada uno de los frames que componen la animación
    int speed;                    // Velocidad de la animación
    int loop;                     // Indica a que frame vuelve la animación al terminar. -1 para que no vuelva
    bool completed;               // Indica si ha finalizado la animación
    int current_frame;            // Frame actual
    int counter;                  // Contador para las animaciones

    Animation() : name(std::string()), speed(5), loop(0), completed(false), current_frame(0), counter(0) {}
};

using AnimationsFileBuffer = std::vector<std::string>;

// Carga las animaciones en un vector(Animations) desde un fichero
AnimationsFileBuffer loadAnimationsFromFile(const std::string &file_path);

class AnimatedSprite : public MovingSprite
{
protected:
    // Variables
    std::vector<Animation> animations_; // Vector con las diferentes animaciones
    int current_animation_ = 0;         // Animacion activa

    // Calcula el frame correspondiente a la animación actual
    void animate();

    // Carga la animación desde un vector de cadenas
    void loadFromAnimationsFileBuffer(const AnimationsFileBuffer &source);

public:
    // Constructor
    AnimatedSprite(std::shared_ptr<Texture> texture, const std::string &file_path);
    AnimatedSprite(std::shared_ptr<Texture> texture, const AnimationsFileBuffer &animations);
    explicit AnimatedSprite(std::shared_ptr<Texture> texture)
        : MovingSprite(texture) {}

    // Destructor
    virtual ~AnimatedSprite() = default;

    // Actualiza las variables del objeto
    void update() override;

    // Comprueba si ha terminado la animación
    bool animationIsCompleted();

    // Obtiene el indice de la animación a partir del nombre
    int getIndex(const std::string &name);

    // Establece la animacion actual
    void setCurrentAnimation(const std::string &name = "default");
    void setCurrentAnimation(int index = 0);

    // Reinicia la animación
    void resetAnimation();
};