/*
 *  Copyright 1994-2022 Olivier Girondel
 *
 *  This file is part of lebiniou.
 *
 *  lebiniou is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  lebiniou is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with lebiniou. If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef __BINIOU_PARTICLES_H
#define __BINIOU_PARTICLES_H

#include "point3d.h"
#include "buffer_8bits.h"
#include "params3d.h"
#include "rgba.h"


/* Basic Particle System */

#define PS_DEFAULT_MAX_PARTICLES    4096
#define PS_NOLIMIT                  0


typedef struct {
  float     ttl;                /* time to live */
  union {
    Pixel_t idx;                /* color */
    rgba_t  rgba;
  } col;
  Point3d_t pos, vel, acc, gra; /* position, speed, acceleration */
  float     gfa;                /* gfa: gravity factor (1.0 == g) */
  struct timeval age;           /* particle's age */
} Particle_t;


Particle_t *Particle_new_indexed(float, Pixel_t, Point3d_t, Point3d_t, Point3d_t, float);
Particle_t *Particle_new_rgba(float, rgba_t, Point3d_t, Point3d_t, Point3d_t, float);

/* -------------------------------------------------------- */

typedef struct {
  uint32_t max_particles;
  uint32_t nb_particles;
  GSList *particles;
} Particle_System_t;


Particle_System_t *Particle_System_new(const long);
void Particle_System_delete(Particle_System_t *);

uint8_t Particle_System_can_add(const Particle_System_t *);
void   Particle_System_add(Particle_System_t *, const Particle_t *);
void   Particle_System_go(Particle_System_t *);
void   Particle_System_draw(const Particle_System_t *, const Params3d_t *, Buffer8_t *);

static inline uint16_t Particle_System_is_dead(const Particle_System_t *ps)
{
  return (uint16_t)(ps->nb_particles == 0);
}

#endif /* __BINIOU_PARTICLES_H */
