const std = @import("std");
const sdl = @import("sdl.zig").c;
const atils = @import("./asset_utils.zig");
const GameState = @import("./game_state.zig").GameState;
const slime_sprite_sheet_texture_path = "assets/slime_still.png";
const rgba = @import("./utils/rgb_color.zig").RGBAColor;

pub const Slime = struct {
    total_frames: u8 = 6,
    x: i32 = 64,
    y: i32 = 300,
    f: u16 = 0,
    color: rgba = .{
        .r = 0xd5,
        .g = 0x0f,
        .b = 0x65,
        .a = 110,
    },
};

pub const SlimeFactory = struct {
    slimes: std.ArrayList(Slime) = undefined,
    slime_sprite_sheet_texture: *sdl.struct_SDL_Texture = undefined,

    pub fn init(allocator: std.mem.Allocator, renderer: *sdl.struct_SDL_Renderer) !SlimeFactory {
        const texture = try atils.loadTexture(renderer, slime_sprite_sheet_texture_path);
        const val = sdl.SDL_SetTextureBlendMode(texture, sdl.SDL_BLENDMODE_BLEND);
        if (val != 0) {
            sdl.SDL_Log("Failed to set blend mode: %s", sdl.SDL_GetError());
            return error.FailedToSetBlendMode;
        }
        return .{
            .slimes = std.ArrayList(Slime).init(allocator),
            .slime_sprite_sheet_texture = texture,
        };
    }

    pub fn deinit(sf: *SlimeFactory) void {
        sdl.SDL_DestroyTexture(sf.slime_sprite_sheet_texture);
        sf.slimes.deinit();
    }

    pub fn add(sf: *SlimeFactory, slime: Slime) !void {
        try sf.slimes.append(slime);
    }

    pub fn render(sf: *SlimeFactory, game_state: *GameState) void {
        if (sf.slimes.items.len == 0) return;

        const slime_color = sf.slimes.items[0].color;

        _ = sdl.SDL_SetTextureColorMod(
            sf.slime_sprite_sheet_texture,
            slime_color.r,
            slime_color.g,
            slime_color.b,
        );
        _ = sdl.SDL_SetTextureAlphaMod(sf.slime_sprite_sheet_texture, slime_color.a);
        for (sf.slimes.items, 0..) |slime, s_idx| {
            const sprite_frame_x_dim: u16 = slime.f * 64;
            const sprite_frame_rect: sdl.struct_SDL_Rect = .{ .x = sprite_frame_x_dim, .y = 0, .w = 64, .h = 64 };
            const dest_rect: sdl.struct_SDL_Rect = .{ .x = slime.x, .y = slime.y, .w = 64, .h = 64 };
            _ = sdl.SDL_RenderCopy(game_state.renderer, sf.slime_sprite_sheet_texture, &sprite_frame_rect, &dest_rect);
            sf.slimes.items[s_idx].f = (sf.slimes.items[s_idx].f + 1) % sf.slimes.items[s_idx].total_frames;
        }
    }
};
