module gfits_interfaces_public
#if defined(VAX)
  interface
    subroutine gdf_setblnk4(bval)
      !---------------------------------------------------------------------
      ! @ public
      !   Set the blanking for automatic conversions
      !---------------------------------------------------------------------
      real(4), intent(in) :: bval
    end subroutine gdf_setblnk4
  end interface
  !
  interface
    subroutine gdf_setblnk8(bval)
      !---------------------------------------------------------------------
      ! @ public
      !   Set the blanking for automatic conversions
      !---------------------------------------------------------------------
      real(8), intent(in) :: bval
    end subroutine gdf_setblnk8
  end interface
  !
#endif
#if defined(EEEI)
  interface
    subroutine gdf_setblnk4(bval)
      !---------------------------------------------------------------------
      ! @ public
      !   Set the blanking for automatic conversions
      !---------------------------------------------------------------------
      real(4), intent(in) :: bval
    end subroutine gdf_setblnk4
  end interface
  !
#endif
  interface
    subroutine fitreal(fd,ndat,array,scale,zero,error)
      use gbl_message
      use gfits_buf
      use gfits_types
      !---------------------------------------------------------------------
      ! @ public
      ! Write NDAT data values in FITS data area,
      ! with scaling SCALE and offset ZERO
      !---------------------------------------------------------------------
      type(gfits_hdesc_t), intent(inout) :: fd           !
      integer(kind=4),     intent(in)    :: ndat         ! Number of data elements
      real(kind=4),        intent(in)    :: array(ndat)  ! Data array
      real(kind=4),        intent(in)    :: scale        ! Scaling factor
      real(kind=4),        intent(in)    :: zero         ! Zero offset
      logical,             intent(inout) :: error        ! Error flag
    end subroutine fitreal
  end interface
  !
  interface
    subroutine fitreal_end(fd,error)
      use gfits_buf
      use gfits_types
      !---------------------------------------------------------------------
      ! @ public
      !---------------------------------------------------------------------
      type(gfits_hdesc_t), intent(inout) :: fd     !
      logical,             intent(inout) :: error  ! Error flag
    end subroutine fitreal_end
  end interface
  !
  interface
    subroutine gfits_getreal(fd,ndat,array,scal,zero,error)
      use gildas_def
      use gbl_message
      use gfits_types
      !---------------------------------------------------------------------
      ! @ public
      ! Read NDAT data values from FITS data area, with scaling SCALE and
      ! offset ZERO
      !---------------------------------------------------------------------
      type(gfits_hdesc_t),       intent(in)    :: fd           !
      integer(kind=size_length), intent(in)    :: ndat         ! Number of desired data values
      real(kind=4),              intent(inout) :: array(ndat)  ! Data values
      real(kind=4),              intent(in)    :: scal         ! Scale factor
      real(kind=4),              intent(in)    :: zero         ! Offset
      logical,                   intent(inout) :: error        ! Error flag
    end subroutine gfits_getreal
  end interface
  !
  interface
    subroutine gfits_putbuf(int1,nr,error)
      use gfits_buf
      !---------------------------------------------------------------------
      ! @ public
      ! Write one row of a binary table to a FITS logical record
      !---------------------------------------------------------------------
      integer(kind=4), intent(in)    :: nr        ! Length of buffer
      integer(kind=1), intent(in)    :: int1(nr)  ! Buffer
      logical,         intent(inout) :: error     ! Error flag
    end subroutine gfits_putbuf
  end interface
  !
  interface
    subroutine gfits_getbuf(int1,nr,error)
      use gildas_def
      use gfits_buf
      !---------------------------------------------------------------------
      ! @ public-mandatory
      ! Get one row of a binary table from a FITS logical record
      !---------------------------------------------------------------------
      integer(kind=size_length), intent(in)    :: nr        ! Length of buffer
      integer(kind=1),           intent(inout) :: int1(nr)  ! Buffer
      logical,                   intent(inout) :: error     ! Error flag
    end subroutine gfits_getbuf
  end interface
  !
  interface
    subroutine gfits_skibuf(nb,error)
      use gildas_def
      use gfits_buf
      use gbl_message
      !---------------------------------------------------------------------
      ! @ public
      ! Skip NB bytes on input file
      !---------------------------------------------------------------------
      integer(kind=size_length), intent(in)    :: nb     ! Bytes to skip
      logical,                   intent(inout) :: error  ! Error flag
    end subroutine gfits_skibuf
  end interface
  !
  interface
    subroutine gfits_skidat(fd,ndat,error)
      use gildas_def
      use gbl_message
      use gfits_types
      !---------------------------------------------------------------------
      ! @ public
      !  Skip NDAT data values from FITS data area,
      !---------------------------------------------------------------------
      type(gfits_hdesc_t),       intent(in)    :: fd     !
      integer(kind=size_length), intent(in)    :: ndat   ! Number of desired data values
      logical,                   intent(inout) :: error  ! Error flag
    end subroutine gfits_skidat
  end interface
  !
  interface
    subroutine gfits_goto_hdu(fd,khdu,error)
      use gildas_def
      use gbl_message
      use gfits_types
      use gfits_buf
      !---------------------------------------------------------------------
      ! @ public
      ! Go to the requested HDU
      !---------------------------------------------------------------------
      type(gfits_hdesc_t), intent(inout) :: fd     !
      integer(kind=4),     intent(in)    :: khdu   ! Requested HDU (1=Primary)
      logical,             intent(inout) :: error  ! Error flag
    end subroutine gfits_goto_hdu
  end interface
  !
  interface
    subroutine gfits_list_hdus(name,error)
      use gbl_message
      use gfits_types
      !---------------------------------------------------------------------
      ! @ public
      ! Go to the requested HDU
      !---------------------------------------------------------------------
      character(len=*), intent(in)    :: name   ! File name
      logical,          intent(inout) :: error  ! Error flag
    end subroutine gfits_list_hdus
  end interface
  !
  interface
    subroutine gfits_get(comm,argu,check,error,quiet,continue,comment,eof)
      use gfits_buf
      !---------------------------------------------------------------------
      ! @ public
      !  Retrieve the next line of the FITS header
      !---------------------------------------------------------------------
      character(len=*), intent(out)           :: comm      ! Returned FITS keyword
      character(len=*), intent(out)           :: argu      ! Returned keyword value
      logical,          intent(in)            :: check     ! Printout FITS card
      logical,          intent(out)           :: error     ! Logical error flag
      logical,          intent(in),  optional :: quiet     ! Verbosity flag
      logical,          intent(in),  optional :: continue  ! Merge CONTINUE'd lines?
      character(len=*), intent(out), optional :: comment   !
      logical,          intent(out), optional :: eof       !
    end subroutine gfits_get
  end interface
  !
  interface
    subroutine gfits_put(line,check,error)
      use gfits_buf
      !---------------------------------------------------------------------
      ! @ public
      !       Write a FITS line of the header
      !---------------------------------------------------------------------
      character(len=*), intent(in)    :: line   ! FITS card image
      logical,          intent(in)    :: check  ! Verbose flag
      logical,          intent(inout) :: error  ! Error flag
    end subroutine gfits_put
  end interface
  !
  interface
    subroutine gfits_flush_data(error)
      use gfits_buf
      !---------------------------------------------------------------------
      ! @ public
      ! Write current FITS buffer to disk. It the buffer is not full, DATA
      ! is padded with ZEROES (Wells et al, A&A Sup. Ser 44, P.364, line 47)
      !---------------------------------------------------------------------
      logical, intent(out) :: error                 ! Error flag
    end subroutine gfits_flush_data
  end interface
  !
  interface
    subroutine gfits_flush_header(error)
      use gfits_buf
      !---------------------------------------------------------------------
      ! @ public
      ! Write current FITS buffer to disk. It the buffer is not full, HEADER
      ! is padded with BLANKS (Wells et al, A&A Sup. Ser 44, P.365, line 57)
      !---------------------------------------------------------------------
      logical, intent(out) :: error                 ! Error flag
    end subroutine gfits_flush_header
  end interface
  !
  interface
    subroutine gfits_hierarch(key,value,error)
      use gbl_message
      !---------------------------------------------------------------------
      ! @ public
      !  Decode the 'value' as 'key' + new 'value' if input 'key' is
      ! HIERARCH.
      ! ---
      !  HIERARCH keyword convention is described here:
      !    http://fits.gsfc.nasa.gov/registry/hierarch_keyword.html
      !  Note that this is only a convention.
      !---------------------------------------------------------------------
      character(len=*), intent(out)   :: key    ! Output key
      character(len=*), intent(inout) :: value  ! Input/Output value
      logical,          intent(inout) :: error  ! Logical error flag
    end subroutine gfits_hierarch
  end interface
  !
  interface
    function gfits_unquote(value)
      !---------------------------------------------------------------------
      ! @ public
      !  Unquote the input string (if any quotes) and return the value.
      ! Useful in the context of FITS headers where the strings are often
      ! single-quoted.
      !---------------------------------------------------------------------
      character(len=80) :: gfits_unquote  ! Function value on return
      character(len=*), intent(in) :: value
    end function gfits_unquote
  end interface
  !
  interface
    subroutine gfits_load_header(hdict,check,getsymbol,error)
      use gfits_types
      !---------------------------------------------------------------------
      ! @ public
      ! Load the FITS header in the dictionary structure.
      !  COMMENT lines are ignored
      !  HISTORY lines are ignored
      !  HIERARCH lines are interpreted as appropriate
      ! This could be customized
      !---------------------------------------------------------------------
      type(gfits_hdict_t), intent(out)   :: hdict      !
      logical,             intent(in)    :: check      !
      external                           :: getsymbol  ! Symbol translation routine
      logical,             intent(inout) :: error      !
    end subroutine gfits_load_header
  end interface
  !
  interface
    subroutine gfits_check_simple(card,error)
      use gbl_message
      use gfits_types
      !---------------------------------------------------------------------
      ! @ public
      ! Sanity check of the SIMPLE card in FITS header. This is generic for
      ! any FITS file.
      !---------------------------------------------------------------------
      type(fits_unkn_0d_t), intent(in)    :: card   !
      logical,              intent(inout) :: error  !
    end subroutine gfits_check_simple
  end interface
  !
  interface
    subroutine gfits_check_xtension(card,error,xkind)
      use gbl_message
      use gfits_types
      !---------------------------------------------------------------------
      ! @ public
      ! Sanity check of the XTENSION card in FITS header. This is generic
      ! for any FITS file. Optionally check for the XTENSION kind.
      !---------------------------------------------------------------------
      type(fits_unkn_0d_t),       intent(in)    :: card   !
      logical,                    intent(inout) :: error  !
      character(len=*), optional, intent(in)    :: xkind  ! Desired XTENSION kind
    end subroutine gfits_check_xtension
  end interface
  !
  interface
    subroutine gfits_check_format(card,nbit,fmt,error)
      use gbl_format
      use gbl_message
      use gfits_types
      !---------------------------------------------------------------------
      ! @ public
      ! Translate BITPIX to internal format code. This is generic for any
      ! FITS file.
      !---------------------------------------------------------------------
      type(fits_unkn_0d_t), intent(in)    :: card   !
      integer(kind=4),      intent(out)   :: nbit   !
      integer(kind=4),      intent(out)   :: fmt    !
      logical,              intent(inout) :: error  !
    end subroutine gfits_check_format
  end interface
  !
  interface
    subroutine gfits_check_naxis(card,naxis,error)
      use gildas_def
      use gbl_message
      use gfits_types
      !---------------------------------------------------------------------
      ! @ public
      ! Translate NAXIS. This is generic for any FITS extension.
      !---------------------------------------------------------------------
      type(fits_unkn_0d_t), intent(in)    :: card   !
      integer(kind=4),      intent(out)   :: naxis  !
      logical,              intent(inout) :: error  !
    end subroutine gfits_check_naxis
  end interface
  !
  interface
    subroutine gfits_check_naxisi(fhdict,dims,error)
      use gildas_def
      use gbl_message
      use gfits_types
      !---------------------------------------------------------------------
      ! @ public
      ! Translate all the NAXISi. This is generic for any FITS extension.
      !---------------------------------------------------------------------
      type(gfits_hdict_t),        intent(in)    :: fhdict   !
      integer(kind=index_length), intent(out)   :: dims(:)  !
      logical,                    intent(inout) :: error    !
    end subroutine gfits_check_naxisi
  end interface
  !
  interface
    subroutine gfits_getnosymbol(symb,tran,error)
      !---------------------------------------------------------------------
      ! @ public-mandatory (because symbol is used elsewhere)
      ! No symbol translation. 2 main use cases:
      ! - no symbol dictionary available in the current context, or
      ! - user should not be able to modify the critical elements (e.g.
      !   NAXIS*) needed in the context
      !---------------------------------------------------------------------
      character(len=*), intent(in)  :: symb   ! Symbol name
      character(len=*), intent(in)  :: tran   ! Symbol translation
      logical,          intent(out) :: error  ! Logical error flag
    end subroutine gfits_getnosymbol
  end interface
  !
  interface gfits_get_value
    subroutine gfits_get_char(fh,key,found,value,error)
      use gfits_types
      !---------------------------------------------------------------------
      ! @ public-generic gfits_get_value
      ! Get the value in the dictionary from the given key, and evaluate it
      ! as character string. Quotes are removed if any. The output value is
      ! not modified if its key is not found.
      !---------------------------------------------------------------------
      type(gfits_hdict_t), intent(in)    :: fh
      character(len=*),    intent(in)    :: key
      logical,             intent(out)   :: found
      character(len=*),    intent(inout) :: value
      logical,             intent(inout) :: error
    end subroutine gfits_get_char
    subroutine gfits_get_inte(fh,key,found,value,error)
      use gbl_message
      use gfits_types
      !---------------------------------------------------------------------
      ! @ public-generic gfits_get_value
      ! Get the value in the dictionary from the given key, and evaluate it
      ! as an integer. The output value is not modified if its key is not
      ! found.
      !---------------------------------------------------------------------
      type(gfits_hdict_t), intent(in)    :: fh
      character(len=*),    intent(in)    :: key
      logical,             intent(out)   :: found
      integer(kind=4),     intent(inout) :: value
      logical,             intent(inout) :: error
    end subroutine gfits_get_inte
    subroutine gfits_get_long(fh,key,found,value,error)
      use gbl_message
      use gfits_types
      !---------------------------------------------------------------------
      ! @ public-generic gfits_get_value
      ! Get the value in the dictionary from the given key, and evaluate it
      ! as long integer. The output value is not modified if its key is not
      ! found.
      !---------------------------------------------------------------------
      type(gfits_hdict_t), intent(in)    :: fh
      character(len=*),    intent(in)    :: key
      logical,             intent(out)   :: found
      integer(kind=8),     intent(inout) :: value
      logical,             intent(inout) :: error
    end subroutine gfits_get_long
    subroutine gfits_get_real(fh,key,found,value,error)
      use gbl_message
      use gfits_types
      !---------------------------------------------------------------------
      ! @ public-generic gfits_get_value
      ! Get the value in the dictionary from the given key, and evaluate it
      ! as single precision float. The output value is not modified if its
      ! key is not found.
      !---------------------------------------------------------------------
      type(gfits_hdict_t), intent(in)    :: fh
      character(len=*),    intent(in)    :: key
      logical,             intent(out)   :: found
      real(kind=4),        intent(inout) :: value
      logical,             intent(inout) :: error
    end subroutine gfits_get_real
    subroutine gfits_get_dble(fh,key,found,value,error)
      use gbl_message
      use gfits_types
      !---------------------------------------------------------------------
      ! @ public-generic gfits_get_value
      ! Get the value in the dictionary from the given key, and evaluate it
      ! as double precision float. The output value is not modified if its
      ! key is not found.
      !---------------------------------------------------------------------
      type(gfits_hdict_t), intent(in)    :: fh
      character(len=*),    intent(in)    :: key
      logical,             intent(out)   :: found
      real(kind=8),        intent(inout) :: value
      logical,             intent(inout) :: error
    end subroutine gfits_get_dble
    subroutine gfits_get_logi(fh,key,found,value,error)
      use gbl_message
      use gfits_types
      !---------------------------------------------------------------------
      ! @ public-generic gfits_get_value
      ! Get the value in the dictionary from the given key, and evaluate it
      ! as a logical. The output value is not modified if its key is not
      ! found.
      !---------------------------------------------------------------------
      type(gfits_hdict_t), intent(in)    :: fh
      character(len=*),    intent(in)    :: key
      logical,             intent(out)   :: found
      logical,             intent(inout) :: value
      logical,             intent(inout) :: error
    end subroutine gfits_get_logi
  end interface gfits_get_value
  !
  interface
    subroutine gfits_open(file,status,error,overwrite)
      use gfits_buf
      use gbl_message
      use gbl_format
      !---------------------------------------------------------------------
      ! @ public
      ! FITS API routine
      !       Connect with a FITS file on disk.
      !---------------------------------------------------------------------
      character(len=*),  intent(in)    :: file       ! FITS file name
      character(len=*),  intent(in)    :: status     ! Read (IN) or Write (OUT) status
      logical,           intent(inout) :: error      ! Error flag
      logical, optional, intent(in)    :: overwrite  ! Overwrite in case of OUT status?
    end subroutine gfits_open
  end interface
  !
  interface
    subroutine gfits_close(error)
      use gfits_buf
      !---------------------------------------------------------------------
      ! @ public
      ! FITS API routine
      !       Disconnect from a FITS file, after flushing the data if needed
      !---------------------------------------------------------------------
      logical, intent(inout) :: error  ! Error flag
    end subroutine gfits_close
  end interface
  !
  interface
    subroutine gfits_skirec(nrec,error)
      use gildas_def
      use gfits_buf
      use gbl_message
      !---------------------------------------------------------------------
      ! @ public
      ! FITS  API routine
      !       Skips a (positive or negative) number of FITS logical records
      !---------------------------------------------------------------------
      integer(kind=record_length), intent(in)    :: nrec   ! Number of records to skip
      logical,                     intent(inout) :: error  ! Error flag
    end subroutine gfits_skirec
  end interface
  !
  interface
    subroutine gfits_getrecnum(irecnum)
      use gildas_def
      use gfits_buf
      !---------------------------------------------------------------------
      ! @ public
      ! FITS  API routine
      !       Returns the number of the present FITS 2880-bytes record.
      !---------------------------------------------------------------------
      integer(kind=record_length), intent(out) :: irecnum  ! Current record number
    end subroutine gfits_getrecnum
  end interface
  !
  interface
    subroutine gfits_setrecnum(irecnum)
      use gildas_def
      use gfits_buf
      !---------------------------------------------------------------------
      ! @ public
      ! FITS  API Routine
      !       Sets the number of the FITS 2880-bytes record.
      !---------------------------------------------------------------------
      integer(kind=record_length), intent(in) :: irecnum  ! Current record number
    end subroutine gfits_setrecnum
  end interface
  !
  interface
    subroutine gfits_getrecoffset(ioffset)
      use gfits_buf
      !---------------------------------------------------------------------
      ! @ public
      ! FITS  API routine
      !       Returns the offset (in bytes) of the next data to be read
      !       inside the present 2880-bytes record.
      !---------------------------------------------------------------------
      integer(kind=4), intent(out) :: ioffset        ! Offset in current record
    end subroutine gfits_getrecoffset
  end interface
  !
  interface
    subroutine gfits_setrecoffset(ioffset)
      use gfits_buf
      !---------------------------------------------------------------------
      ! @ public
      ! FITS  API routine
      !       Sets the offset (in bytes) of the next data to be read inside
      !       the present 2880-bytes record.
      !---------------------------------------------------------------------
      integer(kind=4), intent(in) :: ioffset          ! Offset in current record
    end subroutine gfits_setrecoffset
  end interface
  !
  interface
    subroutine gfits_getstdrec(error)
      use gfits_buf
      !---------------------------------------------------------------------
      ! @ public
      ! FITS  API routine
      !     Get the next buffer internally
      !     Only used by CLASS 3dfits.f90
      !---------------------------------------------------------------------
      logical, intent(inout) :: error  ! Error flag
    end subroutine gfits_getstdrec
  end interface
  !
  interface
    function gfits_iseof()
      use gfits_buf
      !---------------------------------------------------------------------
      ! @ public
      ! FITS API routine
      !     Tells if the FITS file has reached EOF
      !---------------------------------------------------------------------
      logical :: gfits_iseof                 ! intent(out)
    end function gfits_iseof
  end interface
  !
  interface
    subroutine gfits_rewind_file(error)
      use gfits_buf
      !---------------------------------------------------------------------
      ! @ public
      ! Rewind the pointers to start of file
      !---------------------------------------------------------------------
      logical, intent(inout) :: error
    end subroutine gfits_rewind_file
  end interface
  !
  interface
    subroutine gfits_rewind_hdu(error)
      use gfits_buf
      !---------------------------------------------------------------------
      ! @ public
      ! Rewind the pointers to start of current HDU
      !---------------------------------------------------------------------
      logical, intent(inout) :: error
    end subroutine gfits_rewind_hdu
  end interface
  !
  interface
    subroutine gfits_message_set_id(id)
      use gbl_message
      !---------------------------------------------------------------------
      ! @ public
      ! Alter library id into input id. Should be called by the library
      ! which wants to share its id with the current one.
      !---------------------------------------------------------------------
      integer, intent(in) :: id
    end subroutine gfits_message_set_id
  end interface
  !
end module gfits_interfaces_public
