!=========================================================================
!
! Included from file hdf5_io_hdf5.f90.
! You are not expected to understand this. --JIM
!
!=========================================================================

#ifdef READ
  #define READ_WRITE(x) hdf5_read ## x
  #define INTENT inout
  #define H5F_FILE_ACCESS H5F_ACC_RDONLY_F
#else
  #define READ_WRITE(x) hdf5_write ## x
  #define INTENT in
  #define H5F_FILE_ACCESS H5F_ACC_RDWR_F
#endif

#ifdef TYPE_INT
  #define THE_TYPE integer
  #define SUBROUTINE_NAME_SCALAR READ_WRITE(_int)
  #define SUBROUTINE_NAME_ARRAY READ_WRITE(_int_array)
  #define TYPE_SUFFIX(x) x ## _int_f
  #define H5TYPE H5T_NATIVE_INTEGER
#endif
#ifdef TYPE_DOUBLE
  #define THE_TYPE real(DP)
  #define SUBROUTINE_NAME_SCALAR READ_WRITE(_double)
  #define SUBROUTINE_NAME_ARRAY READ_WRITE(_double_array)
  #define TYPE_SUFFIX(x) x ## _double_f
  #define H5TYPE H5T_NATIVE_DOUBLE
#endif

#ifdef READ
  #define H5LT_READ_WRITE TYPE_SUFFIX(h5ltread_dataset)
#else
  #define H5LT_READ_WRITE TYPE_SUFFIX(h5ltmake_dataset)
#endif

subroutine SUBROUTINE_NAME_SCALAR(loc_id, dset_name, buf, errcode)
  integer(HID_T), intent(in) :: loc_id !< HDF5 file id
  character(LEN=*), intent(in) :: dset_name !< HDF5 dataset name
  THE_TYPE, intent(INTENT) :: buf !< data buffer
  integer :: errcode !< HDF5 error code
  
  integer(HSIZE_T), dimension(1) :: dims_h5type(1)
# ifdef READ
  THE_TYPE, dimension(1) :: buf_1(1)
#else
  logical :: exists_
  integer(HID_T) :: dset_id
#endif
  
  PUSH_SUB(SUBROUTINE_NAME_SCALAR)
  
  dims_h5type(1) = 0
  
#ifdef READ
  call H5LT_READ_WRITE(loc_id, dset_name, buf_1, dims_h5type, errcode)
  buf = buf_1(1)
#else
  !FHJ: We can`t use H5LTmake_dataset_* if the dataset already exists!
  exists_ = H5LTfind_dataset_f(loc_id, dset_name)==1
  if (exists_) then
    call h5dopen_f(loc_id, dset_name, dset_id, errcode)
    call h5dwrite_f(dset_id, H5TYPE, (/buf/), dims_h5type, errcode)
    call h5dclose_f(dset_id, errcode)
  else
    call H5LT_READ_WRITE(loc_id, dset_name, 0, dims_h5type, (/buf/), errcode)
  endif
#endif
  
  POP_SUB(SUBROUTINE_NAME_SCALAR)
end subroutine

subroutine SUBROUTINE_NAME_ARRAY(loc_id, dset_name, dims, buf, errcode)
  integer(HID_T), intent(in) :: loc_id !< HDF5 file id
  character(LEN=*), intent(in) :: dset_name !< HDF5 dataset name
  integer, intent(in), dimension(:) :: dims !< size of the buffer buf
  THE_TYPE, intent(INTENT), dimension(*) :: buf !< data buffer
  integer :: errcode !< error code
  
  integer :: rank
  integer(HSIZE_T), dimension(size(dims)) :: dims_h5type
#ifndef READ
  logical :: exists_
  integer(HID_T) :: dset_id
#endif
  
  PUSH_SUB(SUBROUTINE_NAME_ARRAY)
  
  rank = size(dims)
  dims_h5type = dims
    
#ifdef READ
  call H5LT_READ_WRITE(loc_id, dset_name, buf, dims_h5type, errcode)
#else
  !FHJ: We can`t use H5LTmake_dataset_* if the dataset already exists!
  exists_ = H5LTfind_dataset_f(loc_id, dset_name)==1
  if (exists_) then
    call h5dopen_f(loc_id, dset_name, dset_id, errcode)
    call h5dwrite_f(dset_id, H5TYPE, buf, dims_h5type, errcode)
    call h5dclose_f(dset_id, errcode)
  else
    call H5LT_READ_WRITE(loc_id, dset_name, rank, dims_h5type, buf, errcode)
  endif
#endif
  
  POP_SUB(SUBROUTINE_NAME_ARRAY)
end subroutine

#undef READ_WRITE
#undef INTENT
#undef THE_TYPE
#undef TYPE_SUFFIX
#undef H5TYPE
#undef SUBROUTINE_NAME_SCALAR
#undef SUBROUTINE_NAME_ARRAY

#undef H5LT_READ_WRITE
#undef H5F_FILE_ACCESS
