#ifndef CTRL_H
#define CTRL_H

#define MAX_CTRL_ARGS   128
#define MAX_CTRL_NAME   128
#define	MAX_CTRL_DESC	512

struct float_ctrl_s;
struct vec3_ctrl_s;

#ifdef  _MSC_VER
#define CTRL_CALL   __fastcall
#else   /* !_MSC_VER */
#define CTRL_CALL
#endif  /* !_MSC_VER */

typedef vec_t (CTRL_CALL *float_controller_entry_t)(struct float_ctrl_s *self,vec_t arg);
typedef void (*float_controller_setup_t)(struct float_ctrl_s *self);
typedef void (CTRL_CALL *vec3_controller_entry_t)(struct vec3_ctrl_s *self,vec_p ret_val);
typedef void (*vec3_controller_setup_t)(struct vec3_ctrl_s *self);

/*
 * Following two structures are used during initialization stage
 */
typedef struct float_ctrl_rec_s
{
	char	*name;
	u32_t   num_scalar_params;
	float_controller_entry_t entry; /* returns modulus of force */
	float_controller_entry_t energy; /* returns potential energy */
	float_controller_setup_t setup; /* setup: called once after parsing */
	char	*desc;
}   float_ctrl_rec_t, *float_ctrl_rec_p;

typedef struct vec3_ctrl_rec_s
{
	char	*name;
	u32_t   num_scalar_params;
	vec3_controller_entry_t entry; /* returns modulus of force */
	vec3_controller_setup_t setup; /* setup: called once after parsing */
	char	*desc;
}   vec3_ctrl_rec_t, *vec3_ctrl_rec_p;

/*
 * Next two structures are actual controllers
 */
struct particle_system_s;

typedef struct float_ctrl_s
{
	float_controller_entry_t entry;
	float_controller_entry_t energy;
	vec_t params[MAX_CTRL_ARGS];
	vboolean cutoff; /* use cutoff distance */
	vec_t cutoff_distance;
	struct particle_system_s *ps;
	char id[MAX_CTRL_NAME];
}   float_ctrl_t, *float_ctrl_p;

typedef struct vec3_ctrl_s
{
	vec3_controller_entry_t entry;
	vec_t params[MAX_CTRL_ARGS];
	struct particle_system_s *ps;
	char id[MAX_CTRL_NAME];
}   vec3_ctrl_t, *vec3_ctrl_p;

#include "psys.h"

void helpControllers();
float_ctrl_p fcGetById(vhandle_t lexer,struct particle_system_s *ps,char *id);
vec3_ctrl_p vcGetById(vhandle_t lexer,struct particle_system_s *ps,char *id);
void clearControllersCache(struct particle_system_s *ps);

#endif  /* !CTRL_H */
