#ifndef GENIE_CMODULE
#define GENIE_CMODULE

/*
* $Id: genie_cmodule.h,v 1.6 1997/06/25 01:06:53 faa Exp $
*
* Header for C interface to GENIE module routines
* Freddie Akeroyd, ISIS, 19/2/97
*
* A C module will be compiled in GENIE with MODULE/COMPILE/C,
* integrated into GENIE with MODULE/LOAD and functions within
* it called with MODULE:EXECUTE:C()
*/

/* Forward declaration for GenieWorkspace */
#ifdef __cplusplus
class GenieWorkspace;
#else
struct GenieWorkspace;
typedef struct GenieWorkspace GenieWorkspace; /* C has several namespaces! */
#endif /* __cplusplus */

/* Load typedefs for fort_int, fort_real and fort_double */
#include "fortran_types.h"

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

/*
* A typical C module will be prototyped
*
* #include <genie_cmodule.h>
* #include <genie_cmodule_ver.h>
*
* void my_c_module(GenieWorkspace* pars_get, GenieWorkspace* pars_put)
* {
* if (!cmodule_version_ok(CMODULE_MAJOR_VERSION, CMODULE_MINOR_VERSION))
* {
* cmodule_print("Library version mismatch in MY_C_MODULE",
* CMODULE_PRINT_ERROR);
* return;
* }
* <all is well, proceed>
*
*/

/* Get REAL parameter NAME from GENIE as VAL */
void cmodule_get_real(GenieWorkspace* pars_get, const char* name, fort_real* val
);

/* Return REAL variable VAL to GENIE as NAME */
void cmodule_put_real(GenieWorkspace* pars_put, const char* name, fort_real val)
;

/* Get DOUBLE parameter NAME from GENIE as VAL */
void cmodule_get_double(GenieWorkspace* pars_get, const char* name, fort_double*
val);

/* Return DOUBLE variable VAL to GENIE as NAME */
void cmodule_put_double(GenieWorkspace* pars_put, const char* name, fort_double
val);

/*
* Get STRING parameter NAME from GENIE as VAL
* This routine ALWAYS allocates space for val with malloc(),
* and you will need to free() at a later stage
*
*/
void cmodule_get_string(GenieWorkspace* pars_get, const char* name, char** val);

/* Return STRING variable VAL to GENIE as NAME */
void cmodule_put_string(GenieWorkspace* pars_put, const char* name, const char*
val);

/* Return STRING array VAL of LEN elements to GENIE as NAME */
void cmodule_put_string_array(GenieWorkspace* pars_put, const char* name,
const char* val[], fort_int len);

/* Get INTEGER parameter NAME from GENIE as VAL */
void cmodule_get_int(GenieWorkspace* pars_get, const char* name, fort_int* val);

/* Return INTEGER variable VAL to GENIE as NAME */
void cmodule_put_int(GenieWorkspace* pars_put, const char* name, fort_int val);

/*
* Get REAL array parameter NAME from GENIE as VAL
* On Input:
* The routine will malloc() space for the array if (*val == NULL),
* otherwise it will assume *val points to an array of size len
*
* On Output:
* On error, *len will be set to 0
* Otherwise, *len will be set to the number of elements read into *val
*/
void cmodule_get_real_array(GenieWorkspace* pars_get, const char* name, fort_rea
l** val, fort_int* len);

/* Comments as for cmodule_get_real_array() */
void cmodule_get_double_array(GenieWorkspace* pars_get, const char* name, fort_d
ouble** val, fort_int* len);

/* Comments as for cmodule_get_real_array() */
void cmodule_get_int_array(GenieWorkspace* pars_get, const char* name, fort_int*
* val, fort_int* len);

/* Return a REAL array VAL of length LEN to GENIE as NAME */
void cmodule_put_real_array(GenieWorkspace* pars_put, const char* name, const fo
rt_real* val, fort_int len);

/* Return a DOUBLE array VAL of length LEN to GENIE as NAME */
void cmodule_put_double_array(GenieWorkspace* pars_put, const char* name, const
fort_double* val, fort_int len);

/* Return an INTEGER array VAL of length LEN to GENIE as NAME */
void cmodule_put_int_array(GenieWorkspace* pars_put, const char* name, const for
t_int* val, fort_int len);

/* Print a message s to an output stream governed by option */
void cmodule_print(const char* s, fort_int option);

/* possible values for "option" in cmodule_print() are */
#define CMODULE_PRINT_NORMAL 0 /* Like GCL PRINTN */
#define CMODULE_PRINT_INFORMATION 1 /* Like GCL PRINTIN */
#define CMODULE_PRINT_ERROR 2 /* Like GCL PRINTEN */

/*
* Return a multi-dimensionsal array to GENIE; the array val has
* ndims dimensions and these are stored sequentially in the array
* dims_array[]
*/
fort_int cmodule_put_nd_real_array(GenieWorkspace* pars_put, const char* name,
const fort_real* val, const fort_int* dims_array, fort_int ndims);

/* return MAJOR and MINOR version of genie module interface */
fort_int cmodule_get_version(fort_int* major, fort_int* minor);

/* Check versions MAJOR and MINOR are compatable with
the current genie module interface; return 1 if all OK, 0 if
an error */
fort_int cmodule_version_ok(fort_int major, fort_int minor);

#ifdef __cplusplus
}
#endif /* __cplusplus */

#endif /* GENIE_CMODULE */