#ifndef V_RKEMBD_H
#define	V_RKEMBD_H

/*
 * If monitor() returns false, integration terminates.
 */
typedef vboolean (V_CALL *ode_monitor_t)(void *param,vec_t x,vec_p y);
/*
 * If rightside() returns false, current step is rejected.
 * To terminate integration, call odeTerminate() inside rightside();
 */
typedef vboolean (V_CALL *ode_rightside_t)(void *param,vec_t dxdy_dst[],vec_t x,vec_p y);

typedef enum
{
	/*
	 * pnames for real-value parameters
	 */
	ode_timeout,
	ode_tolerance,
	ode_maximal_step,
	ode_minimal_step,
	ode_initial_step,
	ode_monitor_delta,
	/*
	 * pnames for booleans
	 */
	ode_verbose,
	ode_monitor_exact,
	/*
	 * pnames for pointers
	 */
	ode_rightside,
	ode_monitor,
	ode_rightside_arg,
	ode_monitor_arg,
	
	ode_pname_max
}	ode_pname_t;

#ifdef  __cplusplus
extern  "C" {
#endif  /* __cplusplus */
	vhandle_t	V_GLOBAL	odeCreateSolver(u32_t num_variables);
	vboolean	V_GLOBAL	odeIntegrate(vhandle_t handle,vec_p ystart,vec_t x1,vec_t x2); 
	void    	V_GLOBAL    odeTerminate(vhandle_t handle);
	void    	V_GLOBAL    odeDestroySolver(vhandle_t handle);
	vboolean	V_GLOBAL	odeSetReal(vhandle_t handle,ode_pname_t pname,vec_t param);
	vboolean	V_GLOBAL	odeSetBoolean(vhandle_t handle,ode_pname_t pname,vboolean param);
	vboolean	V_GLOBAL	odeSetPointer(vhandle_t handle,ode_pname_t pname,void_p param);
#ifdef  __cplusplus
}
#endif  /* __cplusplus */

#define	odeSetRightside(handle,rightside) \
	{ \
		ode_rightside_t rs = (rightside); \
		odeSetPointer(handle,ode_rightside,*((void_p*)(&rs))); \
	}

#define	odeSetMonitor(handle,monitor) \
	{ \
		ode_monitor_t mon = (monitor); \
		odeSetPointer(handle,ode_monitor,*((void_p*)(&mon))); \
	}

#endif	/* !V_RKEMBD_H */
