#ifndef	GENPARSE_H
#define	GENPARSE_H

#include <v_lib.h>
#include "rgcache.h"

typedef enum
{
	fg_constant = 1,
	fg_uniform = 2,
	fg_gaussian = 3,
	fg_iterators = 99,
	fg_linear_iterator = 100,
	fg_log10_iterator = 101
} float_generator_type;

/* 
 * TODO: extend 'for' with 'logbase', can easily perform arbitrary base interpolation
 */

typedef struct float_generator_s
{
	float_generator_type	type;
	char	*name;
	vboolean finished; /* iterations complete */
	union
	{
		vec_t constant;
		struct
		{
			rgcache_p rgc;
			vec_t min, max;
		} uniform;
		struct
		{
			rgcache_p rgc; /* must be at the same place */
			vec_t mean, stdev;
		} gaussian;
		struct
		{
			u32_t steps, idx; /* required for bidirectional iterators */
			vec_t from, to, val, delta;
		} ilinear;
		struct
		{
			u32_t steps, idx; /* required for bidirectional iterators */
			vec_t log10from, log10to, log10val, log10delta;
		} ilog10;
	} u;
	vboolean (*next)(struct float_generator_s *self,vec_t *ret_val);
	void (*reset)(struct float_generator_s *self);
	void (*destroy)(struct float_generator_s *self);
} float_generator_t, *float_generator_p;

/*
 * For all genXXX(), 'name' can be NULL.
 * In such case, as a name will be used:
 *  constant: just string with same number: "%g";
 *  uniform: "uniform_min_%g_max_%g";
 *  gaussian: "gaussian_mean_%g_stdev_%g";
 *  linear: "iterator_linear_from_%g_to_%g_steps_%u";
 *  loglinear: "iterator_loglinear_from_%g_to_%g_steps_%u";
 */
float_generator_p V_GLOBAL genConstant(vec_t val, char *name);
float_generator_p V_GLOBAL genUniform(vec_t min, vec_t max, char *name);
float_generator_p V_GLOBAL genGaussian(vec_t mean, vec_t stdev, char *name);
/*
float_generator_p V_GLOBAL genLinear(vec_t from, vec_t to, u32_t steps, char *name);
float_generator_p V_GLOBAL genLoglinear(vec_t from, vec_t to, u32_t steps, char *name);
*/

/*
 * Returns number of generators stored in 'store'.
 */
unsigned V_GLOBAL parseGenerators(vhandle_t lex,vp_stack_p store);

#endif /* GENPARSE_H */
