#ifndef PSYS_H
#define PSYS_H

#include "config.h"
#include "ctrl.h"

typedef struct particle_system_s
{
	int	 random_seed;
	char	file_name[_MAX_PATH];
	char	name[MAX_ID];
	u32_t   num_particles;
	int		fail_counter;
	vec_t   *particle_radius;
	vec_t   *particle_density;
	vec_t   *particle_mass;
	vec_t   *particle_mass_delta;
	vec_t   *particle_reciprocal_mass; /* 1/m_j */
	vec_t   *particle_6_pi_eta_r; /* 6 * M_PI * env_eta * r_j */
	matrix_p dist;
	matrix_p surf_dist;
	matrix_p contact;
	vboolean tangent_forces;
	vec_t	*dglue;
	vec_t	hglue;
	vec_t	deltaz;

	u32_t   num_boundary_planes;
	u32_t   num_boundary_spheres;
	
	vec4_t  boundary_plane[MAX_BOUNDARY_PLANES];
	float_ctrl_p plane_interaction[MAX_BOUNDARY_PLANES];

	vec4_t  boundary_sphere[MAX_BOUNDARY_SPHERES];
	float_ctrl_p sphere_interaction[MAX_BOUNDARY_PLANES];

	float_ctrl_p binary_interaction;
	vec_t	binary_interaction_max_dist;

	vec_t   env_eta;
	vec3_ctrl_p env_velocity;

	vec3_ctrl_p unary_force;

	vec3_ctrl_p unary_accel;

	vec_t   *phase; /* positions & velocities of all particles */
	vec_t   cur_time;   /* as processed by ODE solver */
	vhandle_t rt_timer; /* used to measure elapsed time */
	vec_t   *cur_phase; /* as processed by ODE solver */
	u32_t   cur_idx; /* used by controller calls */
	vec3_t  *force; /* used by right-side routine */
	/* controllers can not be chared between particle systems */
	vp_stack_t float_controllers;
	vp_stack_t vec3_controllers;
	
	vhandle_t ode_solver;
	vec_t   solution_time_limit;
	vec_t   solution_realtime_limit;
	vec_t   solution_RK_tolerance;
	vec_t	solution_maximal_step;
	vec_t   solution_RK_timeout;
	vboolean nodraw;
	vboolean output_maxscript;
	u32_t   saves_per_second;
	u32_t   ms_draw_skips;
	vec_t	ms_global_scale;
	u32_t   global_skips;
	char	monitor_setup[MAX_MONITOR_DATA];
	vboolean (V_CALL *monitor)(struct particle_system_s *ps);
	vboolean (V_CALL *end_monitoring)(struct particle_system_s *ps);
	void_p  monitoring_context;
	vboolean (V_CALL *ode_monitor)(void_p arg,vec_t time,vec_t phase[]);
	void_p  ode_monitor_arg;
	u32_t   step_rejection_count;
	char	initial_filename[_MAX_PATH];
	char	final_filename[_MAX_PATH];
}   particle_system_t, *particle_system_p;

particle_system_p
psLoad(vhandle_t lexer);

void
psFree(particle_system_p ps);

#endif  /* !PSYS_H */
