#include "Renderer_iface.h"
#include <SDL3/SDL.h>

namespace renderer {

class SDLRendererImpl : public Renderer {
public:
    explicit SDLRendererImpl(SDL_Renderer* rdr) : rdr_(rdr) {}
    ~SDLRendererImpl() override = default;

    SDL_Texture* createTextureFromSurface(SDL_Surface* surf) override {
        if (!rdr_ || !surf) return nullptr;
        return SDL_CreateTextureFromSurface(rdr_, surf);
    }

    void destroyTexture(SDL_Texture* tex) override {
        if (tex) SDL_DestroyTexture(tex);
    }
    void copy(SDL_Texture* tex, const SDL_Rect* src, const SDL_Rect* dst) override {
        if (!rdr_ || !tex) return;
        // Convert integer rects to float rects and call SDL_RenderTexture (SDL3 API)
        SDL_FRect fs{}; SDL_FRect fd{};
        const SDL_FRect* ps = nullptr;
        const SDL_FRect* pd = nullptr;
        if (src) { fs.x = static_cast<float>(src->x); fs.y = static_cast<float>(src->y); fs.w = static_cast<float>(src->w); fs.h = static_cast<float>(src->h); ps = &fs; }
        if (dst) { fd.x = static_cast<float>(dst->x); fd.y = static_cast<float>(dst->y); fd.w = static_cast<float>(dst->w); fd.h = static_cast<float>(dst->h); pd = &fd; }
        SDL_RenderTexture(rdr_, tex, ps, pd);
    }

    void renderTexture(SDL_Texture* tex, const SDL_FRect* src, const SDL_FRect* dst) override {
        if (!rdr_ || !tex) return;
        SDL_RenderTexture(rdr_, tex, src, dst);
    }

    void setTextureAlphaMod(SDL_Texture* tex, Uint8 a) override {
        if (!tex) return;
        SDL_SetTextureAlphaMod(tex, a);
    }

    void clear(const SDL_Color& color) override {
        if (!rdr_) return;
        SDL_SetRenderDrawColor(rdr_, color.r, color.g, color.b, color.a);
        SDL_RenderClear(rdr_);
    }

    void setDrawColor(const SDL_Color& color) override {
        if (!rdr_) return;
        SDL_SetRenderDrawColor(rdr_, color.r, color.g, color.b, color.a);
    }

    void fillRectF(const SDL_FRect* rect) override {
        if (!rdr_ || !rect) return;
        SDL_RenderFillRect(rdr_, rect);
    }

    void drawRectF(const SDL_FRect* rect) override {
        if (!rdr_ || !rect) return;
        SDL_RenderRect(rdr_, rect);
    }

    void renderLine(float x1, float y1, float x2, float y2) override {
        if (!rdr_) return;
        SDL_RenderLine(rdr_, x1, y1, x2, y2);
    }

    void present() override {
        if (!rdr_) return;
        SDL_RenderPresent(rdr_);
    }

private:
    SDL_Renderer* rdr_ = nullptr;
};

// Factory helper
std::unique_ptr<Renderer> MakeSDLRenderer(SDL_Renderer* rdr) {
    return std::make_unique<SDLRendererImpl>(rdr);
}

} // namespace renderer
