#pragma once

#include <SDL3/SDL.h>

#include <memory>  // Para shared_ptr

#include "core/rendering/surface_sprite.hpp"  // Para SSprite
class Surface;                                // lines 8-8

// Clase SMovingSprite. Añade movimiento y flip al sprite
class SurfaceMovingSprite : public SurfaceSprite {
    public:
    protected:
        float x_;  // Posición en el eje X
        float y_;  // Posición en el eje Y

        float vx_ = 0.0F;  // Velocidad en el eje X. Cantidad de pixeles a desplazarse
        float vy_ = 0.0F;  // Velocidad en el eje Y. Cantidad de pixeles a desplazarse

        float ax_ = 0.0F;  // Aceleración en el eje X. Variación de la velocidad
        float ay_ = 0.0F;  // Aceleración en el eje Y. Variación de la velocidad

        SDL_FlipMode flip_;  // Indica como se voltea el sprite

        // Mueve el sprite (time-based)
        void move(float delta_time);

        // Mueve el sprite (frame-based, deprecated)
        void move();

    public:
        // Constructor
        SurfaceMovingSprite(std::shared_ptr<Surface> surface, SDL_FRect pos, SDL_FlipMode flip);
        SurfaceMovingSprite(std::shared_ptr<Surface> surface, SDL_FRect pos);
        explicit SurfaceMovingSprite(std::shared_ptr<Surface> surface);

        // Destructor
        ~SurfaceMovingSprite() override = default;

        // Actualiza las variables internas del objeto (time-based)
        void update(float delta_time) override;

        // Actualiza las variables internas del objeto (frame-based, deprecated)
        [[deprecated("Use update(float delta_time) instead")]]
        void update() override;

        // Reinicia todas las variables a cero
        void clear() override;

        // Muestra el sprite por pantalla
        void render() override;
        void render(Uint8 source_color, Uint8 target_color) override;

        // Obtiene la variable
        [[nodiscard]] auto getPosX() const -> float { return x_; }
        [[nodiscard]] auto getPosY() const -> float { return y_; }
        [[nodiscard]] auto getVelX() const -> float { return vx_; }
        [[nodiscard]] auto getVelY() const -> float { return vy_; }
        [[nodiscard]] auto getAccelX() const -> float { return ax_; }
        [[nodiscard]] auto getAccelY() const -> float { return ay_; }

        // Establece la variable
        void setVelX(float value) { vx_ = value; }
        void setVelY(float value) { vy_ = value; }
        void setAccelX(float value) { ax_ = value; }
        void setAccelY(float value) { ay_ = value; }

        // Establece el valor de la variable
        void setFlip(SDL_FlipMode flip) { flip_ = flip; }

        // Gira el sprite horizontalmente
        void flip() { flip_ = (flip_ == SDL_FLIP_HORIZONTAL) ? SDL_FLIP_NONE : SDL_FLIP_HORIZONTAL; }

        // Obtiene el valor de la variable
        auto getFlip() -> SDL_FlipMode { return flip_; }

        // Establece la posición y_ el tamaño del objeto
        void setPos(SDL_FRect rect);

        // Establece el valor de las variables
        void setPos(float x, float y);

        // Establece el valor de la variable
        void setPosX(float value);

        // Establece el valor de la variable
        void setPosY(float value);
};