#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;

#define	CTRL_CALL

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_t arg,vec3_t 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[MAX_CTRL_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[MAX_CTRL_DESC];
}   float_ctrl_rec_t, float_ctrl_rec_p;

typedef struct vec3_ctrl_rec_s
{
	char	name[MAX_CTRL_NAME];
	u32_t   num_scalar_params;
	float_controller_entry_t entry; /* returns modulus of force */
	float_controller_entry_t energy; /* returns potential energy */
	vec3_controller_setup_t setup; /* setup: called once after parsing */
	char	desc[MAX_CTRL_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;
	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;

void helpControllers();
/*
 * lexLastWas() == controller ID
 * Parses ently, stores controller in stack, lexLastWas() == "}".
 */
vboolean lexParseFloatController(vhandle_t lexer,vp_stack_p cache);
vboolean lexParseVec3Controller(vhandle_t lexer,vp_stack_p cache);
float_ctrl_p getFloatControllerById(vp_stack_p cache);
vec3_ctrl_p getVec3ControllerById(vp_stack_p cache);
void clearControllersCache(vp_stack_p cache);

#endif  /* !CTRL_H */
