#ifndef V_RGEN_H
#define V_RGEN_H

#ifndef	SQRT_3
#define	SQRT_3	VEC(1.73205080756887729352745)
#endif

/*
 * Lower and upper bounds of uniformly distrubuted value
 */
#define	UNIFORM_LOWER(mean,stdev)	((mean) - (stdev) * SQRT_3)
#define	UNIFORM_UPPER(mean,stdev)	((mean) + (stdev) * SQRT_3)

/*
 * Low-level stuff
 */
#define RAN_NTAB 32

typedef struct ran_state_s
{
	s32_t idum;
	s32_t idum2;
	s32_t iy;
	s32_t iv[RAN_NTAB];
}	ran_state_t, *ran_state_p;

#ifdef	__cplusplus
extern "C" {
#endif	/* __cplusplus */
	/*
	 * Low-level routines
	 */
	void	V_GLOBAL	ranInitState(ran_state_p state,s32_t seed);
	s32_t	V_GLOBAL	ranGenerateNext(ran_state_p state);
	/*
	 * High-level routines
	 */
	vhandle_t	V_GLOBAL	ranCreateGenerator(s32_t seed);
	void	V_GLOBAL	ranDestroyGenerator(vhandle_t gen);
	s32_t	V_GLOBAL	ranNextLong(vhandle_t gen);
	vec_t	V_GLOBAL	ranNextFloat(vhandle_t gen);
	vec_t	V_GLOBAL	ranNextFloatRange(vhandle_t gen,vec_t min,vec_t max);
	void	V_GLOBAL	ranNextVec3Range(vhandle_t gen,vec3_t vec3_ret,vec_t min,vec_t max);
	void	V_GLOBAL	ranNextVec3RangeV(vhandle_t gen,vec3_t vec3_ret,vec3_t mins,vec3_t maxs);
	void	V_GLOBAL	ranNextVectorRange(vhandle_t gen,vector_p vec_ret,vec_t min,vec_t max);
	void	V_GLOBAL	ranNextVectorRangeV(vhandle_t gen,vector_p vec_ret,vector_p mins,vector_p maxs);

	vec_t	V_GLOBAL	ranNextGaussian(vhandle_t gen,vec_t mean,vec_t rms);
	void	V_GLOBAL	ranNextGaussianVec3(vhandle_t gen,vec3_t vec3_ret,vec_t mean,vec_t rms);
	void	V_GLOBAL	ranNextGaussianVec3V(vhandle_t gen,vec3_t vec3_ret,vec3_t mean,vec3_t rms);
	void	V_GLOBAL	ranNextGaussianVector(vhandle_t gen,vector_p vec_ret,vec_t mean,vec_t rms);
	void	V_GLOBAL	ranNextGaussianVectorV(vhandle_t gen,vector_p vec_ret,vector_p mean,vector_p rms);
	/* 09 nov 2011 */
	void	V_GLOBAL	ranDirection(vhandle_t gen,vec3_t dest);
	void	V_GLOBAL	ranNextGaussianVec2(vhandle_t gen,vec2_t vec2_ret,vec_t mean,vec_t rms);
#ifdef	__cplusplus
}
#endif	/* __cplusplus */

#endif	/* V_RGEN_H */
