const sdl = @import("./sdl.zig").c;
const std = @import("std");
const GameState = @import("./game_state.zig").GameState;
const Offset = @import("./utils/offset.zig").Offset;
const FONT_SIZE = 24;

var font: ?*sdl.TTF_Font = null;
var text_texture: ?*sdl.SDL_Texture = null;
var text_init = false;

pub const GameText = struct {
    text: []const u8,
    color: sdl.SDL_Color,
    surface: *sdl.SDL_Surface,
    w: u32,
    h: u32,

    pub fn loadFromRenderedText(text: []const u8, color: sdl.SDL_Color) !GameText {
        const trunc_str = text[0..text.len];
        const c_text: [*c]const u8 = @ptrCast(trunc_str);
        const text_surface: [*c]sdl.SDL_Surface = sdl.TTF_RenderText_Solid(font.?, c_text, color) orelse {
            sdl.SDL_Log("Error loading text surface: %s\n", sdl.SDL_GetError());
            return error.FailedToRenderSurface;
        };

        return .{
            .surface = text_surface,
            .text = text,
            .color = color,
            .w = @intCast(text_surface.*.w),
            .h = @intCast(text_surface.*.h),
        };
    }

    pub fn deinit(self: *GameText) void {
        sdl.SDL_FreeSurface(self.text_surface);
    }

    pub fn setBlendMode(self: *GameText, blend: sdl.SDL_BlendMode) !void {
        _ = self;
        _ = blend;
        return error.Unimplemented;
    }

    pub fn setAlpha(self: *GameText, alpha: u8) !void {
        _ = self;
        _ = alpha;
        return error.Unimplemented;
    }

    pub fn render(
        self: *GameText,
        game_state: *GameState,
        offset: Offset,
    ) !void {
        if (!text_init) {
            return error.TextNotInitialized;
        }

        if (text_texture != null) {
            sdl.SDL_DestroyTexture(text_texture);
            text_texture = null;
        }

        // TODO dont create new texture if unchanged
        text_texture = sdl.SDL_CreateTextureFromSurface(game_state.renderer, self.surface) orelse {
            sdl.SDL_Log("Error loading text texture: %s\n", sdl.SDL_GetError());
            return error.FailedToRenderTexture;
        };

        const srcr = sdl.SDL_Rect{ .x = 0, .y = 0, .w = @intCast(self.w), .h = @intCast(self.h) };
        const destr = sdl.SDL_Rect{ .x = @intCast(offset.x), .y = @intCast(offset.y), .w = @intCast(self.w), .h = @intCast(self.h) };
        _ = sdl.SDL_RenderCopy(game_state.renderer, text_texture, &srcr, &destr);
    }

    pub fn initFont() !void {
        const loaded_font = sdl.TTF_OpenFont("./assets/fonts/DepartureMonoNF-Regular.ttf", FONT_SIZE) orelse {
            sdl.SDL_Log("Error loading ttf font: %s\n", sdl.TTF_GetError());
            return error.FailedToLoadFont;
        };

        font = loaded_font;
        text_init = true;
    }

    pub fn deinitFont() void {
        sdl.SDL_DestroyTexture(text_texture);
        sdl.TTF_CloseFont(font);
        text_init = false;
    }
};
