#pragma once

#include <SDL3/SDL.h>

#include <cstdint>
#include <string>  // for basic_string, string
#include <vector>

class Texture {
   public:
    static SDL_ScaleMode current_scale_mode;  // Modo de escalado global para nuevas texturas

    static void setGlobalScaleMode(SDL_ScaleMode mode);  // Establece el modo de escalado global para nuevas texturas

    explicit Texture(SDL_Renderer *renderer, const std::string &path = "", bool verbose = false);  // Constructor
    Texture(SDL_Renderer *renderer, const std::vector<uint8_t> &bytes, bool verbose = false);      // Constructor desde bytes (PNG en memoria)
    ~Texture();                                                                                    // Destructor

    auto loadFromFile(const std::string &path, SDL_Renderer *renderer, bool verbose = false) -> bool;                                     // Carga una imagen desde un fichero
    auto loadFromMemory(const uint8_t *data, size_t size, SDL_Renderer *renderer, bool verbose = false) -> bool;                          // Carga una imagen desde bytes en memoria
    auto createBlank(SDL_Renderer *renderer, int width, int height, SDL_TextureAccess /*access*/ = SDL_TEXTUREACCESS_STREAMING) -> bool;  // Crea una textura en blanco
    void unload();                                                                                                                        // Libera la memoria de la textura

    void setColor(Uint8 red, Uint8 green, Uint8 blue);  // Establece el color para la modulacion
    void setBlendMode(SDL_BlendMode blending);          // Establece el blending
    void setAlpha(Uint8 alpha);                         // Establece el alpha para la modulación

    void render(SDL_Renderer *renderer, int x, int y, SDL_Rect *clip = nullptr, float zoom_w = 1, float zoom_h = 1, double angle = 0.0, SDL_Point *center = nullptr, SDL_FlipMode flip = SDL_FLIP_NONE);  // Renderiza la textura en un punto específico
    void setAsRenderTarget(SDL_Renderer *renderer);                                                                                                                                                       // Establece la textura como objetivo de renderizado

    [[nodiscard]] auto getWidth() const -> int;   // Obtiene el ancho de la imagen
    [[nodiscard]] auto getHeight() const -> int;  // Obtiene el alto de la imagen

    auto reLoad() -> bool;                  // Recarga la textura
    auto getSDLTexture() -> SDL_Texture *;  // Obtiene la textura

   private:
    // Objetos y punteros
    SDL_Texture *texture_;    // La textura
    SDL_Renderer *renderer_;  // Renderizador donde dibujar la textura

    // Variables
    int width_;         // Ancho de la imagen
    int height_;        // Alto de la imagen
    std::string path_;  // Ruta de la imagen de la textura
};
