#ifndef __H5PARTERRORS_H
#define __H5PARTERRORS_H


/***************** Error Handling ***************/

#define CHECK_FILEHANDLE( f ) \
	if ( _file_is_valid ( f ) != H5PART_SUCCESS ) \
		return HANDLE_H5PART_BADFD_ERR;

#define CHECK_WRITABLE_MODE( f )  \
	if ( f->mode==H5PART_READ ) \
		return (*_err_handler) ( \
			_H5Part_get_funcname(), \
			H5PART_ERR_INVAL, \
			"Attempting to write to read-only file" );

#define CHECK_READONLY_MODE( f )  \
	if ( ! f->mode==H5PART_READ ) \
		return (*_err_handler) ( \
			_H5Part_get_funcname(), \
			H5PART_ERR_INVAL, \
			"Operation is not allowed on writable files." );

#define CHECK_TIMEGROUP( f ) \
	if ( f->timegroup <= 0 ) \
		return (*_err_handler) ( \
			_H5Part_get_funcname(), \
			H5PART_ERR_INVAL, \
			"Timegroup <= 0.");

/**************** H5Part *********************/

#define HANDLE_H5PART_BADFD_ERR \
	(*_err_handler)( \
		_H5Part_get_funcname(), \
		H5PART_ERR_BADFD, \
		"Called with bad filehandle." );

#define HANDLE_H5PART_INIT_ERR \
        (*_err_handler) ( \
		_H5Part_get_funcname(), \
		H5PART_ERR_INIT, \
		"Cannot initialize H5Part." );

#define HANDLE_H5PART_NOMEM_ERR \
	(*_err_handler) ( \
		_H5Part_get_funcname(), \
		H5PART_ERR_NOMEM, \
		"Out of memory." );

#define HANDLE_H5PART_SETSTEP_ERR( rc, step ) \
	(*_err_handler) ( \
		_H5Part_get_funcname(), \
		rc, \
		"Cannont set time-step to %lld.", (long long)step );

#define HANDLE_H5PART_FILE_ACCESS_TYPE_ERR( flags ) \
		(*_err_handler) ( \
			_H5Part_get_funcname(), \
			H5PART_ERR_INVAL, \
			"Invalid file access type \"%d\".", flags);

#define HANDLE_H5PART_STEP_EXISTS_ERR( step ) \
	(*_err_handler)( \
		_H5Part_get_funcname(), \
		H5PART_ERR_INVAL, \
		"Step #%lld already exists, step cannot be set to an existing" \
		" step in write and append mode", (long long)step );

#define HANDLE_H5PART_SET_VIEW_ERR( rc, start, end ) \
		(*_err_handler) ( \
			_H5Part_get_funcname(), \
			rc, \
			"Cannot set view to (%lld, %lld).", \
			(long long)start, (long long)end );

#define HANDLE_H5PART_GET_NUM_PARTICLES_ERR( rc ) \
		(*_err_handler) ( \
			_H5Part_get_funcname(), \
			rc, \
			"Cannot get number of particles." );

#define HANDLE_H5PART_NOENTRY_ERR( group_name, type, idx ) \
		(*_err_handler) ( \
			_H5Part_get_funcname(), \
			H5PART_ERR_NOENTRY, \
			"No entry with index %lld and type %d in group %s!", \
			(long long)idx, type, group_name );

/**************** HDF5 *********************/
/* H5A: Attribute */
#define HANDLE_H5A_CLOSE_ERR \
	 (*_err_handler) ( \
		_H5Part_get_funcname(), \
		H5PART_ERR_HDF5, \
		"Cannot terminate access to attribute." );

#define HANDLE_H5A_CREATE_ERR( s ) \
	 (*_err_handler) ( \
		_H5Part_get_funcname(), \
		H5PART_ERR_HDF5, \
		"Cannot create attribute \"%s\".", s );

#define HANDLE_H5A_GET_NAME_ERR \
	 (*_err_handler) ( \
		_H5Part_get_funcname(), \
		H5PART_ERR_HDF5, \
		"Cannot get attribute name." );

#define HANDLE_H5A_GET_NUM_ATTRS_ERR \
	 (*_err_handler) ( \
		_H5Part_get_funcname(), \
		H5PART_ERR_HDF5, \
		"Cannot get number of attributes." );

#define HANDLE_H5A_GET_SPACE_ERR \
	 (*_err_handler) ( \
		_H5Part_get_funcname(), \
		H5PART_ERR_HDF5, \
		"Cannot get a copy of dataspace for attribute." );

#define HANDLE_H5A_GET_TYPE_ERR \
	 (*_err_handler) ( \
		_H5Part_get_funcname(), \
		H5PART_ERR_HDF5, \
		"Cannot get attribute datatype." );

#define HANDLE_H5A_OPEN_IDX_ERR( n ) \
	 (*_err_handler) ( \
		_H5Part_get_funcname(), \
		H5PART_ERR_HDF5, \
		"Cannot open attribute specified by index \"%lld\".", \
		(long long)n );

#define HANDLE_H5A_OPEN_NAME_ERR( s ) \
	 (*_err_handler) ( \
		_H5Part_get_funcname(), \
		H5PART_ERR_HDF5, \
		"Cannot open attribute specified by name \"%s\".", s );

#define HANDLE_H5A_READ_ERR \
	 (*_err_handler) ( \
		_H5Part_get_funcname(), \
		H5PART_ERR_HDF5, \
		"Cannot read attribute" );

#define HANDLE_H5A_WRITE_ERR( s ) \
	 (*_err_handler) ( \
		_H5Part_get_funcname(), \
		H5PART_ERR_HDF5, \
		"Cannot write attribute \"%s\".", s );

/* H5D: Dataset */
#define HANDLE_H5D_CLOSE_ERR \
	 (*_err_handler) ( \
		_H5Part_get_funcname(), \
		H5PART_ERR_HDF5, \
		"Close of dataset failed." );

#define HANDLE_H5D_CREATE_ERR( s, n ) \
	 (*_err_handler) ( \
		_H5Part_get_funcname(), \
		H5PART_ERR_HDF5, \
		"Cannot create dataset for name \"%s\", step \"%lld\".", \
		s, (long long) n );

#define HANDLE_H5D_GET_SPACE_ERR \
	 (*_err_handler) ( \
		_H5Part_get_funcname(), \
		H5PART_ERR_HDF5, \
		"Cannot get dataspace identifier.");

#define HANDLE_H5D_GET_TYPE_ERR \
	 (*_err_handler) ( \
		_H5Part_get_funcname(), \
		H5PART_ERR_HDF5, \
		"Cannot determine dataset type.");

#define HANDLE_H5D_OPEN_ERR( s ) \
	 (*_err_handler) ( \
		_H5Part_get_funcname(), \
		H5PART_ERR_HDF5, \
		"Cannot open dataset \"%s\".", s );

#define HANDLE_H5D_READ_ERR( s, n ) \
	 (*_err_handler) ( \
		_H5Part_get_funcname(), \
		H5PART_ERR_HDF5, \
		"Read from dataset \"%s\" failed, step \"%lld\".", \
		s, (long long) n );

#define HANDLE_H5D_WRITE_ERR( s, n ) \
	 (*_err_handler) ( \
		_H5Part_get_funcname(), \
		H5PART_ERR_HDF5, \
		"Write to dataset \"%s\" failed, step \"%lld\".", \
		s, (long long)n );

/* H5F: file */
#define HANDLE_H5F_CLOSE_ERR \
	 (*_err_handler) ( \
		_H5Part_get_funcname(), \
		H5PART_ERR_HDF5, \
		"Cannot terminate access to file." );

#define HANDLE_H5F_OPEN_ERR( filename, flags ) \
		(*_err_handler) ( \
			_H5Part_get_funcname(), \
			H5PART_ERR_HDF5, \
			"Cannot open file \"%s\" with mode \"%d\"", filename, flags );



/* H5G: group */
#define HANDLE_H5G_CLOSE_ERR \
	 (*_err_handler) ( \
		_H5Part_get_funcname(), \
		H5PART_ERR_HDF5, \
		"Cannot terminate access to datagroup." );

#define HANDLE_H5G_CREATE_ERR( s ) \
	 (*_err_handler) ( \
		_H5Part_get_funcname(), \
		H5PART_ERR_HDF5, \
		"Cannot create datagroup \"%s\".", s );

#define HANDLE_H5G_GET_OBJINFO_ERR( s ) \
	 (*_err_handler) ( \
		_H5Part_get_funcname(), \
		H5PART_ERR_HDF5, \
		"Cannot get information about object \"%s\".", s );

#define HANDLE_H5G_OPEN_ERR( s ) \
	 (*_err_handler) ( \
		_H5Part_get_funcname(), \
		H5PART_ERR_HDF5, \
		"Cannot open group \"%s\".", s );


/* H5P: property */
#define HANDLE_H5P_CLOSE_ERR( s ) \
	 (*_err_handler) ( \
		_H5Part_get_funcname(), \
		H5PART_ERR_HDF5, \
		"Cannot terminate access to property list \"%s\".", s );

#define HANDLE_H5P_CREATE_ERR \
	 (*_err_handler) ( \
		_H5Part_get_funcname(), \
		H5PART_ERR_HDF5, \
		"Cannot create property list." );

#define HANDLE_H5P_SET_DXPL_MPIO_ERR \
		(*_err_handler) ( \
			_H5Part_get_funcname(), \
			H5PART_ERR_HDF5, \
			"MPI: Cannot set data transfer mode." );


#define HANDLE_H5P_SET_FAPL_MPIO_ERR \
		(*_err_handler) ( \
			_H5Part_get_funcname(), \
			H5PART_ERR_HDF5, \
			"Cannot store IO communicator information to the " \
			"file access property list.");

/* H5S: dataspace */
#define HANDLE_H5S_CREATE_SIMPLE_ERR( n ) \
	 (*_err_handler) ( \
		_H5Part_get_funcname(), \
		H5PART_ERR_HDF5, \
		"Cannot create dataspace with len \"%lld\".", (long long) n );

#define HANDLE_H5S_CLOSE_ERR \
	 (*_err_handler) ( \
		_H5Part_get_funcname(), \
		H5PART_ERR_HDF5, \
		"Cannot terminate access to dataspace." ); 

#define HANDLE_H5S_GET_SELECT_NPOINTS_ERR \
	 (*_err_handler) ( \
		_H5Part_get_funcname(), \
		H5PART_ERR_HDF5, \
		"Cannot determine the number of elements in dataspace selection." ); 

#define HANDLE_H5S_GET_SIMPLE_EXTENT_NPOINTS_ERR \
	 (*_err_handler) ( \
		_H5Part_get_funcname(), \
		H5PART_ERR_HDF5, \
		"Cannot determine number of elements in dataspace." ); 

#define HANDLE_H5S_SELECT_HYPERSLAB_ERR \
	 (*_err_handler) ( \
		_H5Part_get_funcname(), \
		H5PART_ERR_HDF5, \
		"Cannot set select hyperslap region or add the specified region" );

/* H5T:  type */
#define HANDLE_H5T_CLOSE_ERR \
	 (*_err_handler) ( \
		_H5Part_get_funcname(), \
		H5PART_ERR_HDF5, \
		"Cannot release datatype." );


/* MPI */
#define HANDLE_MPI_ALLGATHER_ERR \
	 (*_err_handler) ( \
		_H5Part_get_funcname(), \
		H5PART_ERR_MPI, \
		"Cannot gather data." );

#define HANDLE_MPI_COMM_SIZE_ERR \
	 (*_err_handler) ( \
		_H5Part_get_funcname(), \
		H5PART_ERR_MPI, \
		"Cannot get number of processes in my group." );

#define HANDLE_MPI_COMM_RANK_ERR \
	 (*_err_handler) ( \
		_H5Part_get_funcname(), \
		H5PART_ERR_MPI, \
		"Cannot get rank of the calling process in my group." );

#endif
