#pragma once

#include "pxl8_types.h"

typedef struct pxl8_gfx pxl8_gfx;
typedef struct pxl8_palette pxl8_palette;
typedef struct pxl8_particles pxl8_particles;
typedef struct pxl8_rng pxl8_rng;

typedef struct pxl8_particle {
    f32 angle;
    f32 ax, ay, az;
    u32 color;
    u32 end_color;
    u8 flags;
    f32 life;
    f32 max_life;
    f32 size;
    f32 spin;
    u32 start_color;
    f32 vx, vy, vz;
    f32 x, y, z;
} pxl8_particle;

typedef void (*pxl8_particle_render_fn)(pxl8_gfx* gfx, pxl8_particle* p, void* userdata);
typedef void (*pxl8_particle_spawn_fn)(pxl8_particles* ps, pxl8_particle* p);
typedef void (*pxl8_particle_update_fn)(pxl8_particle* p, f32 dt, void* userdata);

#ifdef __cplusplus
extern "C" {
#endif

pxl8_particles* pxl8_particles_create(u32 max_count, pxl8_rng* rng);
void pxl8_particles_destroy(pxl8_particles* ps);

void pxl8_particles_clear(pxl8_particles* ps);
void pxl8_particles_emit(pxl8_particles* ps, u32 count);
void pxl8_particles_render(pxl8_particles* ps, pxl8_gfx* gfx);
void pxl8_particles_update(pxl8_particles* ps, f32 dt);

u32 pxl8_particles_count(const pxl8_particles* ps);
u32 pxl8_particles_max_count(const pxl8_particles* ps);
pxl8_particle* pxl8_particles_get(pxl8_particles* ps, u32 index);
pxl8_rng* pxl8_particles_rng(pxl8_particles* ps);

f32 pxl8_particles_get_drag(const pxl8_particles* ps);
f32 pxl8_particles_get_gravity_x(const pxl8_particles* ps);
f32 pxl8_particles_get_gravity_y(const pxl8_particles* ps);
f32 pxl8_particles_get_spawn_rate(const pxl8_particles* ps);
f32 pxl8_particles_get_spread_x(const pxl8_particles* ps);
f32 pxl8_particles_get_spread_y(const pxl8_particles* ps);
f32 pxl8_particles_get_turbulence(const pxl8_particles* ps);
void* pxl8_particles_get_userdata(const pxl8_particles* ps);
f32 pxl8_particles_get_x(const pxl8_particles* ps);
f32 pxl8_particles_get_y(const pxl8_particles* ps);

void pxl8_particles_set_colors(pxl8_particles* ps, u8 color_min, u8 color_max);
void pxl8_particles_set_drag(pxl8_particles* ps, f32 drag);
void pxl8_particles_set_gravity(pxl8_particles* ps, f32 gx, f32 gy);
void pxl8_particles_set_life(pxl8_particles* ps, f32 life_min, f32 life_max);
void pxl8_particles_set_palette(pxl8_particles* ps, pxl8_palette* palette);
void pxl8_particles_set_position(pxl8_particles* ps, f32 x, f32 y);
void pxl8_particles_set_render_fn(pxl8_particles* ps, pxl8_particle_render_fn fn);
void pxl8_particles_set_size(pxl8_particles* ps, f32 size_min, f32 size_max);
void pxl8_particles_set_spawn_fn(pxl8_particles* ps, pxl8_particle_spawn_fn fn);
void pxl8_particles_set_spawn_rate(pxl8_particles* ps, f32 rate);
void pxl8_particles_set_spread(pxl8_particles* ps, f32 spread_x, f32 spread_y);
void pxl8_particles_set_turbulence(pxl8_particles* ps, f32 turbulence);
void pxl8_particles_set_update_fn(pxl8_particles* ps, pxl8_particle_update_fn fn);
void pxl8_particles_set_userdata(pxl8_particles* ps, void* userdata);
void pxl8_particles_set_velocity(pxl8_particles* ps, f32 vx_min, f32 vx_max, f32 vy_min, f32 vy_max);

#ifdef __cplusplus
}
#endif
