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

local particles = {}

local Particles = {}
Particles.__index = Particles

function Particles.new(max_count)
    local ps = C.pxl8_particles_create(max_count or 1000, core.rng)
    if ps == nil then
        return nil
    end
    local pal = C.pxl8_gfx_palette(core.gfx)
    if pal ~= nil then
        C.pxl8_particles_set_palette(ps, pal)
    end
    return setmetatable({ _ptr = ps }, Particles)
end

function Particles:clear()
    C.pxl8_particles_clear(self._ptr)
end

function Particles:destroy()
    if self._ptr then
        C.pxl8_particles_destroy(self._ptr)
        self._ptr = nil
    end
end

function Particles:emit(count)
    C.pxl8_particles_emit(self._ptr, count or 1)
end

function Particles:render()
    C.pxl8_particles_render(self._ptr, core.gfx)
end

function Particles:update(dt)
    C.pxl8_particles_update(self._ptr, dt)
end

function Particles:count()
    return C.pxl8_particles_count(self._ptr)
end

function Particles:get(index)
    return C.pxl8_particles_get(self._ptr, index)
end

function Particles:set_position(x, y)
    C.pxl8_particles_set_position(self._ptr, x, y)
end

function Particles:set_gravity(gx, gy)
    C.pxl8_particles_set_gravity(self._ptr, gx, gy)
end

function Particles:set_spread(sx, sy)
    C.pxl8_particles_set_spread(self._ptr, sx, sy)
end

function Particles:set_drag(drag)
    C.pxl8_particles_set_drag(self._ptr, drag)
end

function Particles:set_turbulence(turbulence)
    C.pxl8_particles_set_turbulence(self._ptr, turbulence)
end

function Particles:set_spawn_rate(rate)
    C.pxl8_particles_set_spawn_rate(self._ptr, rate)
end

function Particles:set_colors(ramp_min, ramp_max)
    ramp_max = ramp_max or ramp_min
    if ramp_min > ramp_max then
        ramp_min, ramp_max = ramp_max, ramp_min
    end
    C.pxl8_particles_set_colors(self._ptr, ramp_min, ramp_max)
end

function Particles:set_palette(palette)
    C.pxl8_particles_set_palette(self._ptr, palette)
end

function Particles:set_life(life_min, life_max)
    C.pxl8_particles_set_life(self._ptr, life_min, life_max or life_min)
end

function Particles:set_size(size_min, size_max)
    C.pxl8_particles_set_size(self._ptr, size_min, size_max or size_min)
end

function Particles:set_velocity(vx_min, vx_max, vy_min, vy_max)
    C.pxl8_particles_set_velocity(self._ptr, vx_min, vx_max, vy_min, vy_max)
end

particles.Particles = Particles

return particles
