#ifndef _SLGSL_MODULE_H_
#define _SLGSL_MODULE_H_

#include <gsl/gsl_vector.h>
#include <gsl/gsl_matrix.h>

extern void slgsl_reset_errors (void);
extern void slgsl_check_errors (const char *module_name);


typedef struct
{
   double x;
   double *xp;
   SLang_Array_Type *at;
   unsigned int num_elements;
   unsigned int inc;
}
SLGSL_Double_Array_Type;

typedef struct
{
   int x;
   int *xp;
   SLang_Array_Type *at;
   unsigned int num_elements;
   unsigned int inc;
}
SLGSL_Int_Array_Type;

typedef struct
{
   double x[2];
   double *xp;
   SLang_Array_Type *at;
   unsigned int num_elements;
   unsigned int inc;
}
SLGSL_Complex_Array_Type;

extern int slgsl_create_d_array (SLGSL_Double_Array_Type *a, SLGSL_Double_Array_Type *b);
extern int slgsl_create_c_array (SLGSL_Complex_Array_Type *a, SLGSL_Complex_Array_Type *b);
extern void slgsl_free_i_array (SLGSL_Int_Array_Type *a);
extern void slgsl_free_d_array (SLGSL_Double_Array_Type *a);
extern void slgsl_free_c_array (SLGSL_Complex_Array_Type *a);
extern int slgsl_push_i_array (SLGSL_Int_Array_Type *a, int do_free);
extern int slgsl_push_d_array (SLGSL_Double_Array_Type *a, int do_free);
extern int slgsl_push_c_array (SLGSL_Complex_Array_Type *a, int do_free);

extern int slgsl_pop_d_array (SLGSL_Double_Array_Type *a, int);
extern int slgsl_pop_i_array (SLGSL_Int_Array_Type *a, int);
extern int slgsl_pop_c_array (SLGSL_Complex_Array_Type *a, int);
extern int slgsl_pop_dd_array (SLGSL_Double_Array_Type *a, SLGSL_Double_Array_Type *b, int);
extern int slgsl_pop_id_array (SLGSL_Int_Array_Type *a, SLGSL_Double_Array_Type *b, int);
extern int slgsl_pop_idd_array (SLGSL_Int_Array_Type *a, SLGSL_Double_Array_Type *b, SLGSL_Double_Array_Type *c, int);
extern int slgsl_pop_iid_array (SLGSL_Int_Array_Type *a, SLGSL_Int_Array_Type *b, SLGSL_Double_Array_Type *c, int);
extern int slgsl_pop_iidd_array (SLGSL_Int_Array_Type *a, SLGSL_Int_Array_Type *b, SLGSL_Double_Array_Type *c, SLGSL_Double_Array_Type *d, int);
extern int slgsl_pop_ddd_array (SLGSL_Double_Array_Type *a, SLGSL_Double_Array_Type *b, SLGSL_Double_Array_Type *c, int);
extern int slgsl_pop_dddd_array (SLGSL_Double_Array_Type *a, SLGSL_Double_Array_Type *b, 
				 SLGSL_Double_Array_Type *c, SLGSL_Double_Array_Type *d, int);


extern void slgsl_do_d_d_fun (const char *fun, double (*f)(double));
extern void slgsl_do_d_i_fun (const char *fun, double (*f)(int));
extern void slgsl_do_d_dd_fun (const char *fun, double (*f)(double, double));
extern void slgsl_do_d_ddd_fun (const char *fun, double (*f)(double, double, double));
extern void slgsl_do_d_dddd_fun (const char *fun, double (*f)(double, double, double,double));
extern void slgsl_do_d_id_fun (const char *fun, double (*f)(int, double));
extern void slgsl_do_d_idd_fun (const char *fun, double (*f)(int, double, double));
extern void slgsl_do_d_iid_fun (const char *fun, double (*f)(int, int, double));
extern void slgsl_do_d_iidd_fun (const char *fun, double (*f)(int, int, double, double));
extern void slgsl_do_i_d_fun (const char *fun, int (*f)(double));


typedef struct SLGSL_Matrix_Type
{
   unsigned int size1, size2;
   union
     {
	gsl_matrix d;
	gsl_matrix_complex c;
     }
   m;
   int is_complex;
   void (*free_method)(struct SLGSL_Matrix_Type *);
   int (*push_method)(struct SLGSL_Matrix_Type *);
   SLang_Array_Type *at;
}
SLGSL_Matrix_Type;

typedef struct SLGSL_Vector_Type
{
   unsigned int size;
   union
     {
	gsl_vector d;
	gsl_vector_complex c;
     }
   v;
   int is_complex;
   void (*free_method)(struct SLGSL_Vector_Type *);
   int (*push_method)(struct SLGSL_Vector_Type *);
   SLang_Array_Type *at;
}
SLGSL_Vector_Type;

extern void slgsl_free_matrix (SLGSL_Matrix_Type *matrix);
extern int slgsl_push_matrix (SLGSL_Matrix_Type *matrix);
extern int slgsl_pop_matrix (SLGSL_Matrix_Type **matrixp, SLtype type, int copy);
extern int slgsl_pop_square_matrix (SLGSL_Matrix_Type **matrixp, SLtype type, int copy);
extern SLGSL_Matrix_Type *slgsl_new_matrix (SLtype type, unsigned int n0, unsigned int n1, int copy, SLang_Array_Type *at);

extern void slgsl_free_vector (SLGSL_Vector_Type *vector);
extern int slgsl_push_vector (SLGSL_Vector_Type *vector);
extern int slgsl_assign_vector_to_ref (SLGSL_Vector_Type *vector, SLang_Ref_Type *ref);
extern int slgsl_pop_vector (SLGSL_Vector_Type **vectorp, SLtype type, int copy);
extern SLGSL_Vector_Type *slgsl_new_vector (SLtype type, unsigned int n, int copy, SLang_Array_Type *at);

extern int init_gslcdf_module_ns (char *);
extern void deinit_gslcdf_module (void);

extern int init_gslconst_module_ns (char *);
extern void deinit_gslconst_module (void);

extern int init_gslfft_module_ns (char *);
extern void deinit_gslfft_module (void);

extern int init_gslinterp_module_ns (char *);
extern void deinit_gslinterp_module (void);

extern int init_gslmatrix_module_ns (char *);
extern void deinit_gslmatrix_module (void);

extern int init_gslrand_module_ns (char *);
extern void deinit_gslrand_module (void);

extern int init_gslsf_module_ns (char *);
extern void deinit_gslsf_module (void);

extern int init_gsldwt_module_ns (char *);
extern void deinit_gsldwt_module (void);

extern int init_gslinteg_module_ns (char *);
extern void deinit_gslinteg_module (void);


#endif
