/*
 * $Id: mexnc.h 2159 2007-03-06 16:50:52Z johnevans007 $
 * */

# if !defined	MEXNC_H
# define		MEXNC_H



/*	
 *	NetCDF Operations.	
 *
 *	*/

typedef enum s_opcode	{

	ABORT = 0,
	CLOSE,
	COPY_ATT,
	_CREATE,
	CREATE,
	DEF_DIM,
	DEF_VAR,
	DEL_ATT,
	_ENDDEF,
	END_DEF,
	ENDDEF,
	GET_ATT_DOUBLE,
	GET_ATT_FLOAT,
	GET_ATT_INT,
	GET_ATT_SHORT,
	GET_ATT_SCHAR,
	GET_ATT_UCHAR,
	GET_ATT_TEXT,
	GET_VAR_DOUBLE,
	GET_VAR_FLOAT,
	GET_VAR_INT,
	GET_VAR_SHORT,
	GET_VAR_SCHAR,
	GET_VAR_UCHAR,
	GET_VAR_TEXT,
	GET_VAR1_DOUBLE,
	GET_VAR1_FLOAT,
	GET_VAR1_INT,
	GET_VAR1_SHORT,
	GET_VAR1_SCHAR,
	GET_VAR1_UCHAR,
	GET_VAR1_TEXT,
	GET_VARA_DOUBLE,
	GET_VARA_FLOAT,
	GET_VARA_INT,
	GET_VARA_SHORT,
	GET_VARA_SCHAR,
	GET_VARA_UCHAR,
	GET_VARA_TEXT,
	GET_VARS_DOUBLE,
	GET_VARS_FLOAT,
	GET_VARS_INT,
	GET_VARS_SHORT,
	GET_VARS_SCHAR,
	GET_VARS_UCHAR,
	GET_VARS_TEXT,
	GET_VARM_DOUBLE,
	GET_VARM_FLOAT,
	GET_VARM_INT,
	GET_VARM_SHORT,
	GET_VARM_SCHAR,
	GET_VARM_UCHAR,
	GET_VARM_TEXT,
	INQ,
	INQ_ATT,
	INQ_ATTID,
	INQ_ATTLEN,
	INQ_ATTNAME,
	INQ_ATTTYPE,
	INQ_DIM,
	INQ_DIMID,
	INQ_DIMLEN,
	INQ_DIMNAME,
	INQ_LIBVERS,
	INQ_NDIMS,
	INQ_NVARS,
	INQ_NATTS,
	INQ_UNLIMDIM,
	INQ_VARID,
	INQ_VAR,
	INQ_VARNAME,
	INQ_VARTYPE,
	INQ_VARNDIMS,
	INQ_VARDIMID,
	INQ_VARNATTS,
	_OPEN,
	OPEN,
	PUT_ATT_DOUBLE,
	PUT_ATT_FLOAT,
	PUT_ATT_INT,
	PUT_ATT_SHORT,
	PUT_ATT_SCHAR,
	PUT_ATT_UCHAR,
	PUT_ATT_TEXT,
	PUT_VAR_DOUBLE,
	PUT_VAR_FLOAT,
	PUT_VAR_INT,
	PUT_VAR_SHORT,
	PUT_VAR_SCHAR,
	PUT_VAR_UCHAR,
	PUT_VAR_TEXT,
	PUT_VARA_DOUBLE,
	PUT_VARA_FLOAT,
	PUT_VARA_INT,
	PUT_VARA_SHORT,
	PUT_VARA_SCHAR,
	PUT_VARA_UCHAR,
	PUT_VARA_TEXT,
	PUT_VARS_DOUBLE,
	PUT_VARS_FLOAT,
	PUT_VARS_INT,
	PUT_VARS_SHORT,
	PUT_VARS_SCHAR,
	PUT_VARS_UCHAR,
	PUT_VARS_TEXT,
	PUT_VARM_DOUBLE,
	PUT_VARM_FLOAT,
	PUT_VARM_INT,
	PUT_VARM_SHORT,
	PUT_VARM_SCHAR,
	PUT_VARM_UCHAR,
	PUT_VARM_TEXT,
	PUT_VAR1_DOUBLE,
	PUT_VAR1_FLOAT,
	PUT_VAR1_INT,
	PUT_VAR1_SHORT,
	PUT_VAR1_SCHAR,
	PUT_VAR1_UCHAR,
	PUT_VAR1_TEXT,
	REDEF,
	RENAME_ATT,
	RENAME_DIM,
	RENAME_VAR,
	SET_FILL,
	STRERROR,
	SYNC,

	/*
	 * Deprecated NetCDF 2.4
	 * */
	DIMDEF,
	DIMID,
	DIMINQ,
	DIMRENAME,
	ENDEF,
	INQUIRE,
	VARDEF,
	VARID,
	VARINQ,
	VARPUT1,
	VARGET1,
	VARPUT,
	VARGET,
	VARPUTG,
	VARGETG,
	VARRENAME,
	VARCOPY,
	ATTPUT,
	ATTINQ,
	ATTGET,
	ATTCOPY,
	ATTNAME,
	ATTRENAME,
	ATTDEL,
	RECPUT,
	RECGET,
	RECINQ,
	TYPELEN,
	SETFILL,
	SETOPTS,
	ERR,
	PARAMETER,
	NONE,

	/*
	 * Non-mexnc calls
	 * */
	GET_MEXNC_INFO

	}	OPCODE;

typedef struct s_op	{
	OPCODE   opcode;
	char    *opname;
	int      nrhs;		/*	Required nrhs.	*/
	int      nlhs;		/*	Maximum nlhs.	*/
} op;

/*	NetCDF Parameters.	*/

typedef struct s_parm	{
	int      code;
	char    *name;
	int      len;		/*	Minimal unique length.	*/
} parm;
	



static op ops[] =	{
		{ ABORT,            "abort",            2, 1 },
		{ CLOSE,            "close",            2, 1 },
		{ COPY_ATT,         "copy_att",         6, 1 }, 
		{ _CREATE,          "_create",          4, 3 }, 
		{ CREATE,           "create",           2, 2 }, 
		{ DEF_DIM,          "def_dim",          4, 2 }, 
		{ DEF_VAR,          "def_var",          6, 2 }, 
		{ DEL_ATT,          "del_att",          4, 1 }, 
		{ _ENDDEF,          "_enddef",          5, 1 }, 
		{ END_DEF,          "end_def",          1, 1 }, 
		{ ENDDEF,           "enddef",           1, 1 }, 
		{ GET_ATT_DOUBLE,   "get_att_double",   4, 2 }, 
		{ GET_ATT_FLOAT,    "get_att_float",    4, 2 }, 
		{ GET_ATT_INT,      "get_att_int",      4, 2 }, 
		{ GET_ATT_SHORT,    "get_att_short",    4, 2 }, 
		{ GET_ATT_SCHAR,    "get_att_schar",    4, 2 }, 
		{ GET_ATT_UCHAR,    "get_att_uchar",    4, 2 }, 
		{ GET_ATT_TEXT,     "get_att_text",     4, 2 }, 
		{ GET_MEXNC_INFO,   "get_mexnc_info",   1, 2 }, 
		{ GET_VAR_DOUBLE,   "get_var_double",   3, 2 }, 
		{ GET_VAR_FLOAT,    "get_var_float",    3, 2 }, 
		{ GET_VAR_INT,      "get_var_int",      3, 2 }, 
		{ GET_VAR_SHORT,    "get_var_short",    3, 2 }, 
		{ GET_VAR_SCHAR,    "get_var_schar",    3, 2 }, 
		{ GET_VAR_UCHAR,    "get_var_uchar",    3, 2 }, 
		{ GET_VAR_TEXT,     "get_var_text",     3, 2 }, 
		{ GET_VAR1_DOUBLE,  "get_var1_double",  4, 2 }, 
		{ GET_VAR1_FLOAT,   "get_var1_float",   4, 2 }, 
		{ GET_VAR1_INT,     "get_var1_int",     4, 2 }, 
		{ GET_VAR1_SHORT,   "get_var1_short",   4, 2 }, 
		{ GET_VAR1_SCHAR,   "get_var1_schar",   4, 2 }, 
		{ GET_VAR1_UCHAR,   "get_var1_uchar",   4, 2 }, 
		{ GET_VAR1_TEXT,    "get_var1_text",    4, 2 }, 
		{ GET_VARA_DOUBLE,  "get_vara_double",  5, 2 }, 
		{ GET_VARA_FLOAT,   "get_vara_float",   5, 2 }, 
		{ GET_VARA_INT,     "get_vara_int",     5, 2 }, 
		{ GET_VARA_SHORT,   "get_vara_short",   5, 2 }, 
		{ GET_VARA_SCHAR,   "get_vara_schar",   5, 2 }, 
		{ GET_VARA_UCHAR,   "get_vara_uchar",   5, 2 }, 
		{ GET_VARA_TEXT,    "get_vara_text",    5, 2 }, 
		{ GET_VARS_DOUBLE,  "get_vars_double",  6, 2 }, 
		{ GET_VARS_FLOAT,   "get_vars_float",   6, 2 }, 
		{ GET_VARS_INT,     "get_vars_int",     6, 2 }, 
		{ GET_VARS_SHORT,   "get_vars_short",   6, 2 }, 
		{ GET_VARS_SCHAR,   "get_vars_schar",   6, 2 }, 
		{ GET_VARS_UCHAR,   "get_vars_uchar",   6, 2 }, 
		{ GET_VARS_TEXT,    "get_vars_text",    6, 2 }, 
		{ GET_VARM_DOUBLE,  "get_varm_double",  7, 2 }, 
		{ GET_VARM_FLOAT,   "get_varm_float",   7, 2 }, 
		{ GET_VARM_INT,     "get_varm_int",     7, 2 }, 
		{ GET_VARM_SHORT,   "get_varm_short",   7, 2 }, 
		{ GET_VARM_SCHAR,   "get_varm_schar",   7, 2 }, 
		{ GET_VARM_UCHAR,   "get_varm_uchar",   7, 2 }, 
		{ GET_VARM_TEXT,    "get_varm_text",    7, 2 }, 
		{ INQ,              "inq",              2, 5 }, 
		{ INQ_ATT,          "inq_att",          4, 3 }, 
		{ INQ_ATTID,        "inq_attid",        4, 2 }, 
		{ INQ_ATTLEN,       "inq_attlen",       4, 2 }, 
		{ INQ_ATTNAME,      "inq_attname",      4, 2 }, 
		{ INQ_ATTTYPE,      "inq_atttype",      4, 2 }, 
		{ INQ_DIM,          "inq_dim",          3, 3 }, 
		{ INQ_DIMID,        "inq_dimid",        3, 2 }, 
		{ INQ_DIMLEN,       "inq_dimlen",       3, 2 }, 
		{ INQ_DIMNAME,      "inq_dimname",      3, 2 }, 
		{ INQ_LIBVERS,      "inq_libvers",      1, 1 }, 
		{ INQ_NDIMS,        "inq_ndims",        2, 2 }, 
		{ INQ_NVARS,        "inq_nvars",        2, 2 }, 
		{ INQ_NATTS,        "inq_natts",        2, 2 }, 
		{ INQ_UNLIMDIM,     "inq_unlimdim",     1, 2 }, 
		{ INQ_VARID,        "inq_varid",        3, 2 }, 
		{ INQ_VAR,          "inq_var",          3, 6 }, 
		{ INQ_VARNAME,      "inq_varname",      3, 2 }, 
		{ INQ_VARTYPE,      "inq_vartype",      3, 2 }, 
		{ INQ_VARNDIMS,     "inq_varndims",     3, 2 }, 
		{ INQ_VARDIMID,     "inq_vardimid",     3, 2 }, 
		{ INQ_VARNATTS,     "inq_varnatts",     3, 2 }, 
		{ _OPEN,            "_open",            4, 3 }, 
		{ OPEN,             "open",             2, 2 }, 
		{ PUT_ATT_DOUBLE,   "put_att_double",   7, 1 }, 
		{ PUT_ATT_FLOAT,    "put_att_float",    7, 1 }, 
		{ PUT_ATT_INT,      "put_att_int",      7, 1 }, 
		{ PUT_ATT_SHORT,    "put_att_short",    7, 1 }, 
		{ PUT_ATT_SCHAR,    "put_att_schar",    7, 1 }, 
		{ PUT_ATT_UCHAR,    "put_att_uchar",    7, 1 }, 
		{ PUT_ATT_TEXT,     "put_att_text",     7, 1 }, 
		{ PUT_VAR_DOUBLE,   "put_var_double",   4, 1 }, 
		{ PUT_VAR_FLOAT,    "put_var_float",    4, 1 }, 
		{ PUT_VAR_INT,      "put_var_int",      4, 1 }, 
		{ PUT_VAR_SHORT,    "put_var_short",    4, 1 }, 
		{ PUT_VAR_SCHAR,    "put_var_schar",    4, 1 }, 
		{ PUT_VAR_UCHAR,    "put_var_uchar",    4, 1 }, 
		{ PUT_VAR_TEXT,     "put_var_text",     4, 1 }, 
		{ PUT_VARA_DOUBLE,  "put_vara_double",  6, 1 }, 
		{ PUT_VARA_FLOAT,   "put_vara_float",   6, 1 }, 
		{ PUT_VARA_INT,     "put_vara_int",     6, 1 }, 
		{ PUT_VARA_SHORT,   "put_vara_short",   6, 1 }, 
		{ PUT_VARA_SCHAR,   "put_vara_schar",   6, 1 }, 
		{ PUT_VARA_UCHAR,   "put_vara_uchar",   6, 1 }, 
		{ PUT_VARA_TEXT,    "put_vara_text",    6, 1 }, 
		{ PUT_VARS_DOUBLE,  "put_vars_double",  7, 1 }, 
		{ PUT_VARS_FLOAT,   "put_vars_float",   7, 1 }, 
		{ PUT_VARS_INT,     "put_vars_int",     7, 1 }, 
		{ PUT_VARS_SHORT,   "put_vars_short",   7, 1 }, 
		{ PUT_VARS_SCHAR,   "put_vars_schar",   7, 1 }, 
		{ PUT_VARS_UCHAR,   "put_vars_uchar",   7, 1 }, 
		{ PUT_VARS_TEXT,    "put_vars_text",    7, 1 }, 
		{ PUT_VARM_DOUBLE,  "put_varm_double",  8, 1 }, 
		{ PUT_VARM_FLOAT,   "put_varm_float",   8, 1 }, 
		{ PUT_VARM_INT,     "put_varm_int",     8, 1 }, 
		{ PUT_VARM_SHORT,   "put_varm_short",   8, 1 }, 
		{ PUT_VARM_SCHAR,   "put_varm_schar",   8, 1 }, 
		{ PUT_VARM_UCHAR,   "put_varm_uchar",   8, 1 }, 
		{ PUT_VARM_TEXT,    "put_varm_text",    8, 1 }, 
		{ PUT_VAR1_DOUBLE,  "put_var1_double",  5, 1 }, 
		{ PUT_VAR1_FLOAT,   "put_var1_float",   5, 1 }, 
		{ PUT_VAR1_INT,     "put_var1_int",     5, 1 }, 
		{ PUT_VAR1_SHORT,   "put_var1_short",   5, 1 }, 
		{ PUT_VAR1_SCHAR,   "put_var1_schar",   5, 1 }, 
		{ PUT_VAR1_UCHAR,   "put_var1_uchar",   5, 1 }, 
		{ PUT_VAR1_TEXT,    "put_var1_text",    5, 1 }, 
		{ REDEF,            "redef",            1, 1 }, 
		{ RENAME_ATT,       "rename_att",       5, 1 }, 
		{ RENAME_DIM,       "rename_dim",       4, 1 }, 
		{ RENAME_VAR,       "rename_var",       4, 1 }, 
		{ SET_FILL,         "set_fill",         3, 2 }, 
		{ STRERROR,         "strerror",         1, 1 }, 
		{ SYNC,             "sync",             2, 1 }, 
	
		/*
		 * Deprecated Netcdf 2.4
		 * */
		{ DIMDEF,           "dimdef",           4, 2 }, 
		{ DIMID,            "dimid",            3, 2 }, 
		{ DIMINQ,           "diminq",           3, 3 }, 
		{ DIMRENAME,        "dimrename",        4, 1 }, 
		{ ENDEF,            "endef",            1, 1 }, 
		{ INQUIRE,          "inquire",          2, 5 }, 
		{ VARDEF,           "vardef",           6, 2 }, 
		{ VARID,            "varid",            3, 2 }, 
		{ VARINQ,           "varinq",           3, 6 }, 
	
		{ VARPUT1,          "varput1",          5, 1 }, 
		{ VARGET1,          "varget1",          4, 2 }, 
		{ VARPUT,           "varput",           6, 1 }, 
		{ VARGET,           "varget",           5, 2 }, 
		{ VARPUTG,          "varputg",          7, 1 }, 
		{ VARGETG,          "vargetg",          6, 2 }, 
		{ VARRENAME,        "varrename",        4, 1 }, 
		{ VARCOPY,          "varcopy",          3, 2 }, 
		{ ATTPUT,           "attput",           7, 1 }, 
		{ ATTINQ,           "attinq",           4, 3 }, 
		{ ATTGET,           "attget",           4, 2 }, 
		{ ATTCOPY,          "attcopy",          6, 1 }, 
		{ ATTNAME,          "attname",          4, 2 }, 
		{ ATTRENAME,        "attrename",        5, 1 }, 
		{ ATTDEL,           "attdel",           4, 1 }, 
		{ RECPUT,           "recput",           4, 1 }, 
		{ RECGET,           "recget",           3, 2 }, 
		{ RECINQ,           "recinq",           2, 3 }, 
		{ TYPELEN,          "typelen",          2, 2 }, 
		{ SETFILL,          "setfill",          3, 2 }, 
		{ SETOPTS,          "setopts",          2, 1 }, 
		{ ERR,              "err",              1, 1 }, 
		{ PARAMETER,        "parameter",        1, 1 }, 
		{ NONE,             "none",             0, 0 }
	};





void          handle_netcdf2_api ( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[], op *nc_op );	
void          handle_netcdf3_api ( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[], op *nc_op );	
size_t       *Mat2Size_t ( const mxArray *mat );
ptrdiff_t    *Mat2Ptrdiff_t ( const mxArray *mat );
char         *Mat2Str (const mxArray *);

void          check_char_argument_type    ( const mxArray *mx[], char *opname, int idx ); 
void          check_mode_argument_type    ( const mxArray *mx[], char *opname, int idx ); 
void          check_mode_argument_type    ( const mxArray *mx[], char *opname, int idx ); 
void          check_numeric_argument_type ( const mxArray *mx[], char *opname, int idx );
void          check_char_or_numeric_argument_type ( const mxArray *mx[], char *opname, int idx );

void          check_other_args_for_empty_set ( op *nc_op, const mxArray *prhs[], int nrhs );

int           interpret_char_parameter ( const mxArray *mx );
mxArray      *mexncCreateDoubleScalar ( double value );
int           Parameter (const mxArray *);
void          Usage (void);

void set_output_matrix_rank 
( 
    int     ncid, 
    int     num_nc_dims,
    int    *dimids, 
    size_t *nc_count_coords, 
    op     *nc_op, 
    int    *mx_rank 
); 

nc_type       unpackDataType ( const mxArray *mx );
ptrdiff_t    *unpackPtrdiff_t ( const mxArray *mx );
size_t       *unpackSize_t ( const mxArray *mx );
char         *unpackString ( const mxArray *mx );
int           unpack_char_file_mode ( char *input_string_mode );

void          varm_coord_sanity_check ( const mxArray *prhs[], int ndims );


# endif
