#pragma once

#include <SDL2/SDL.h>
#include "movingsprite.h"
#include <fstream>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>

#ifndef ANIMATEDSPRITE_H
#define ANIMATEDSPRITE_H

struct animation_t
{
    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 currentFrame;             // Frame actual
    int counter;                  // Contador para las animaciones
};

struct animatedSprite_t
{
    std::vector<animation_t> animations; // Vector con las diferentes animaciones
    Texture *texture;                    // Textura con los graficos para el sprite
};

// Carga la animación desde un fichero
animatedSprite_t loadAnimationFromFile(Texture *texture, std::string filePath, bool verbose = false);

class AnimatedSprite : public MovingSprite
{
private:
    // Variables
    std::vector<animation_t> animation; // Vector con las diferentes animaciones
    int currentAnimation;               // Animacion activa

public:
    // Constructor
    AnimatedSprite(Texture *texture = nullptr, SDL_Renderer *renderer = nullptr, std::string file = "", std::vector<std::string> *buffer = nullptr);
    AnimatedSprite(SDL_Renderer *renderer, animatedSprite_t *animation);

    // Destructor
    ~AnimatedSprite();

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

    // Obtiene el numero de frames de la animación actual
    int getNumFrames();

    // Establece el frame actual de la animación
    void setCurrentFrame(int num);

    // Establece el valor del contador
    void setAnimationCounter(std::string name, int num);

    // Establece la velocidad de una animación
    void setAnimationSpeed(std::string name, int speed);
    void setAnimationSpeed(int index, int speed);

    // Establece el frame al que vuelve la animación al finalizar
    void setAnimationLoop(std::string name, int loop);
    void setAnimationLoop(int index, int loop);

    // Establece el valor de la variable
    void setAnimationCompleted(std::string name, bool value);
    void setAnimationCompleted(int index, bool value);

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

    // Devuelve el rectangulo de una animación y frame concreto
    SDL_Rect getAnimationClip(std::string name = "default", Uint8 index = 0);
    SDL_Rect getAnimationClip(int indexA = 0, Uint8 indexF = 0);

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

    // Carga la animación desde un vector
    bool loadFromVector(std::vector<std::string> *source);

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

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

    // OLD - Establece el rectangulo para un frame de una animación
    void setAnimationFrames(Uint8 index_animation, Uint8 index_frame, int x, int y, int w, int h);

    // OLD - Establece el contador para todas las animaciones
    void setAnimationCounter(int value);

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

#endif