module mt

! Contains interfaces for the library routines

! HDF5

interface
   subroutine mt_h5close() bind(c)
     use iso_c_binding
   end subroutine mt_h5close
end interface

interface
   subroutine mt_h5open() bind(c)
     use iso_c_binding
   end subroutine mt_h5open
end interface

! Attributes

interface
   subroutine mt_aget_float(hid, name, attr, value) bind(c)
     use hdf5
     use iso_c_binding
     integer(hid_t), intent(in), value :: hid
     character(c_char), intent(in) :: name(*)
     character(c_char), intent(in) :: attr(*)
     real(c_float), intent(out) :: value
   end subroutine mt_aget_float
end interface

interface
   subroutine mt_aset_float(hid, name, attr, value) bind(c)
     use hdf5
     use iso_c_binding
     integer(hid_t), intent(in), value :: hid
     character(c_char), intent(in) :: name(*)
     character(c_char), intent(in) :: attr(*)
     real(c_float), intent(in), value :: value
   end subroutine mt_aset_float
end interface

interface
   subroutine mt_aget_int(hid, name, attr, value) bind(c)
     use hdf5
     use iso_c_binding
     integer(hid_t), intent(in), value :: hid
     character(c_char), intent(in) :: name(*)
     character(c_char), intent(in) :: attr(*)
     integer(c_int), intent(out) :: value
   end subroutine mt_aget_int
end interface

interface
   subroutine mt_aset_int(hid, name, attr, value) bind(c)
     use hdf5
     use iso_c_binding
     integer(hid_t), intent(in), value :: hid
     character(c_char), intent(in) :: name(*)
     character(c_char), intent(in) :: attr(*)
     integer(c_int), intent(in), value :: value
   end subroutine mt_aset_int
end interface

interface
   subroutine mt_aget_string(hid, name, attr, value) bind(c)
     use hdf5
     use iso_c_binding
     integer(hid_t), intent(in), value :: hid
     character(c_char), intent(in) :: name(*)
     character(c_char), intent(in) :: attr(*)
     character(c_char), intent(out) :: value(*)
   end subroutine mt_aget_string
end interface

interface
   subroutine mt_aset_string(hid, name, attr, value) bind(c)
     use hdf5
     integer(hid_t), intent(in), value :: hid
     character(c_char), intent(in) :: name(*)
     character(c_char), intent(in) :: attr(*)
     character(c_char), intent(in) :: value(*)
   end subroutine mt_aset_string
end interface

! Datasets

interface
   subroutine mt_dmake(hid, name, nobj, type, data) bind(c)
     use hdf5
     integer(hid_t), intent(in), value :: hid
     character(c_char), intent(in) :: name(*)
     integer(hsize_t), intent(in), value :: nobj
     character(c_char), intent(in) :: type(*)
     type(*), dimension(*), intent(in) :: data
   end subroutine mt_dmake
end interface

interface
   subroutine mt_dread(hid, name, type, data) bind(c)
     use hdf5
     integer(hid_t), intent(in), value :: hid
     character(c_char), intent(in) :: name(*)
     character(c_char), intent(in) :: type(*)
     type(*), dimension(*), intent(in) :: data
   end subroutine mt_dread
end interface

! Files

interface
   integer(hid_t) function mt_fopen(file,ioflags,comment) bind(c)
     use hdf5
     use iso_c_binding
     character(c_char), intent(in) :: file(*)
     character(c_char), intent(in) :: ioflags(*)
     character(c_char), intent(in), optional :: comment(*)
   end function mt_fopen
end interface

interface
   subroutine mt_fclose(fid) bind(c)
     use hdf5
     integer(hid_t), intent(in), value :: fid
   end subroutine mt_fclose
end interface

! Groups

interface
   integer(hid_t) function mt_gopen(hid,name) bind(c)
     use hdf5
     integer(hid_t), intent(in), value :: hid
     character(c_char), intent(in) :: name(*)
   end function mt_gopen
end interface

interface
   subroutine mt_gclose(gid) bind(c)
     use hdf5
     integer(hid_t), intent(in), value :: gid
   end subroutine mt_gclose
end interface

! Strings

interface
   pure function mt_str_c2f(c_string) result(string)
     use iso_c_binding
     ! Doesn't work with correct string declaration
     !character(c_char), intent(in) :: c_string(*)
     character*(*), intent(in) :: c_string
     character*(1024) :: string
   end function mt_str_c2f
end interface

interface
   pure function mt_str_f2c(string) result(c_string)
     use iso_c_binding
     character*(*), intent(in) :: string
     character(c_char) :: c_string*(1024)
   end function mt_str_f2c
end interface

! Tables

interface
   subroutine mt_tmake(gid,name,nfields,field_names,field_types,&
        nrecords,chunksize,table) bind(c)
     use hdf5
     use iso_c_binding
     integer(hid_t), intent(in), value :: gid
     character(c_char), intent(in) :: name(*)
     integer(hsize_t), intent(in), value :: nfields, nrecords, chunksize
     type(c_ptr), dimension(*), intent(in) :: field_names  ! array of pointers to field names
     character(c_char), dimension(*), intent(in) :: field_types
     type(*), dimension(*), intent(in) :: table   ! Holds memory address of table
   end subroutine mt_tmake
end interface

interface
   subroutine mt_tread(gid,name,nfields,field_names,field_types,&
        &nrecords,table) bind(c)
     use hdf5
     use iso_c_binding
     integer(hid_t), intent(in), value :: gid
     character(c_char), intent(in) :: name(*)
     integer(hsize_t), intent(in), value :: nfields, nrecords
     character(c_char), intent(in) :: field_names(*)    ! string containing field names
     character(c_char), dimension(*), intent(in) :: field_types
     type(*), dimension(*), intent(in) :: table   ! Holds memory address of table
     !This alternative declaration works if use c_loc(table) in the call
     !type(c_ptr), intent(in), value :: table   ! Holds memory address of table
   end subroutine mt_tread
end interface

interface
   integer(hsize_t) function mt_treadinfo(gid,name,nfields) bind(c)
     use hdf5
     use iso_c_binding
     integer(hid_t), intent(in), value :: gid
     character(c_char), intent(in) :: name(*)
     integer(hsize_t), intent(out) :: nfields
   end function mt_treadinfo
end interface

end module mt
