local ffi = require("ffi")
local C = ffi.C
local core = require("pxl8.core")

local graphics = {}

function graphics.clear(color)
    C.pxl8_2d_clear(core.gfx, color or 0)
end

function graphics.pixel(x, y, color)
    if color then
        C.pxl8_2d_pixel(core.gfx, x, y, color)
    else
        return C.pxl8_2d_get_pixel(core.gfx, x, y)
    end
end

function graphics.line(x0, y0, x1, y1, color)
    C.pxl8_2d_line(core.gfx, x0, y0, x1, y1, color)
end

function graphics.rect(x, y, w, h, color)
    C.pxl8_2d_rect(core.gfx, x, y, w, h, color)
end

function graphics.rect_fill(x, y, w, h, color)
    C.pxl8_2d_rect_fill(core.gfx, x, y, w, h, color)
end

function graphics.circle(x, y, r, color)
    C.pxl8_2d_circle(core.gfx, x, y, r, color)
end

function graphics.circle_fill(x, y, r, color)
    C.pxl8_2d_circle_fill(core.gfx, x, y, r, color)
end

function graphics.text(str, x, y, color)
    C.pxl8_2d_text(core.gfx, str, x or 0, y or 0, color or 15)
end

function graphics.sprite(id, x, y, w, h, flip_x, flip_y)
    C.pxl8_2d_sprite(core.gfx, id or 0, x or 0, y or 0, w or 16, h or 16, flip_x or false, flip_y or false)
end

function graphics.load_palette(filepath)
    return C.pxl8_gfx_load_palette(core.gfx, filepath)
end

function graphics.load_sprite(filepath)
    local sprite_id = ffi.new("unsigned int[1]")
    local result = C.pxl8_gfx_load_sprite(core.gfx, filepath, sprite_id)
    if result == 0 then
        return sprite_id[0]
    else
        return nil, result
    end
end

function graphics.create_texture(pixels, width, height)
    local pixel_data = ffi.new("u8[?]", width * height)
    for i = 0, width * height - 1 do
        pixel_data[i] = pixels[i + 1] or 0
    end
    local result = C.pxl8_gfx_create_texture(core.gfx, pixel_data, width, height)
    if result < 0 then
        return nil
    end
    return result
end

function graphics.color_ramp(start, count, from_color, to_color)
    C.pxl8_gfx_color_ramp(core.gfx, start, count, from_color, to_color)
end

function graphics.fade_palette(start, count, amount, target_color)
    C.pxl8_gfx_fade_palette(core.gfx, start, count, amount, target_color)
end

function graphics.cycle_palette(start, count, step)
    C.pxl8_gfx_cycle_palette(core.gfx, start, count, step or 1)
end

function graphics.add_palette_cycle(start_index, end_index, speed)
    return C.pxl8_gfx_add_palette_cycle(core.gfx, start_index, end_index, speed or 1.0)
end

function graphics.remove_palette_cycle(cycle_id)
    C.pxl8_gfx_remove_palette_cycle(core.gfx, cycle_id)
end

function graphics.set_palette_cycle_speed(cycle_id, speed)
    C.pxl8_gfx_set_palette_cycle_speed(core.gfx, cycle_id, speed)
end

function graphics.clear_palette_cycles()
    C.pxl8_gfx_clear_palette_cycles(core.gfx)
end

function graphics.push_target()
    return C.pxl8_gfx_push_target(core.gfx)
end

function graphics.pop_target()
    C.pxl8_gfx_pop_target(core.gfx)
end

return graphics
