module imbfits_interfaces_public
  interface
    subroutine imbfits_dump_summary(imbf,olun,error)
      use gildas_def
      use gbl_message
      use imbfits_types
      !---------------------------------------------------------------------
      ! @ public
      ! Support routine for command:
      !   DUMP SUMMARY
      !---------------------------------------------------------------------
      type(imbfits_t), intent(in)    :: imbf
      integer(kind=4), intent(in)    :: olun   ! Output LUN
      logical,         intent(inout) :: error
    end subroutine imbfits_dump_summary
  end interface
  !
  interface
    subroutine imbfits_dump_subscans(imbf,olun,error)
      use gildas_def
      use gbl_message
      use imbfits_types
      !---------------------------------------------------------------------
      ! @ public
      ! Support routine for command:
      !   DUMP SUBSCANS
      ! The subroutine reopens the input file in its own structure to avoid
      ! messing up the global instances
      !---------------------------------------------------------------------
      type(imbfits_t), intent(inout) :: imbf
      integer(kind=4), intent(in)    :: olun   ! Output LUN
      logical,         intent(inout) :: error
    end subroutine imbfits_dump_subscans
  end interface
  !
  interface
    subroutine imbfits_dump_primary(primary,short,olun,error)
      use gbl_message
      use gildas_def
      use imbfits_types
      use imbfits_key_types
      !---------------------------------------------------------------------
      ! @ public
      !---------------------------------------------------------------------
      type(imbfits_primary_t), intent(in)    :: primary
      logical,                 intent(in)    :: short    ! Short or verbose output?
      integer(kind=4),         intent(in)    :: olun     ! Output LUN
      logical,                 intent(inout) :: error
    end subroutine imbfits_dump_primary
  end interface
  !
  interface
    subroutine imbfits_dump_scan(scan,column,short,olun,error)
      use imbfits_types
      use imbfits_key_types
      use imbfits_column_types
      !---------------------------------------------------------------------
      ! @ public
      !---------------------------------------------------------------------
      type(imbfits_scan_t), intent(in)    :: scan
      character(len=*),     intent(in)    :: column  ! Optional column name
      logical,              intent(in)    :: short   ! Short or verbose output?
      integer(kind=4),      intent(in)    :: olun    ! Output LUN
      logical,              intent(inout) :: error
    end subroutine imbfits_dump_scan
  end interface
  !
  interface
    subroutine imbfits_dump_frontend(front,column,short,olun,error)
      use imbfits_types
      use imbfits_key_types
      use imbfits_column_types
      !---------------------------------------------------------------------
      ! @ public
      !---------------------------------------------------------------------
      type(imbfits_front_t), intent(in)    :: front
      character(len=*),      intent(in)    :: column  ! Optional column name
      logical,               intent(in)    :: short   ! Short or verbose output?
      integer(kind=4),       intent(in)    :: olun    ! Output LUN
      logical,               intent(inout) :: error
    end subroutine imbfits_dump_frontend
  end interface
  !
  interface
    subroutine imbfits_dump_backend(back,column,short,olun,error)
      use imbfits_types
      use imbfits_key_types
      use imbfits_column_types
      !---------------------------------------------------------------------
      ! @ public
      !---------------------------------------------------------------------
      type(imbfits_back_t), intent(in)    :: back
      character(len=*),     intent(in)    :: column  ! Optional column name
      logical,              intent(in)    :: short   ! Short or verbose output?
      integer(kind=4),      intent(in)    :: olun    ! Output LUN
      logical,              intent(inout) :: error
    end subroutine imbfits_dump_backend
  end interface
  !
  interface
    subroutine imbfits_dump_antslow(isub,antslow,column,short,olun,error)
      use imbfits_types
      use imbfits_key_types
      use imbfits_column_types
      !---------------------------------------------------------------------
      ! @ public
      !---------------------------------------------------------------------
      integer(kind=4),         intent(in)    :: isub     ! Subscan number
      type(imbfits_antslow_t), intent(in)    :: antslow
      character(len=*),        intent(in)    :: column   ! Optional column name
      logical,                 intent(in)    :: short    ! Short or verbose output?
      integer(kind=4),         intent(in)    :: olun     ! Output LUN
      logical,                 intent(inout) :: error
    end subroutine imbfits_dump_antslow
  end interface
  !
  interface
    subroutine imbfits_dump_antfast(isub,antfast,column,short,olun,error)
      use imbfits_types
      use imbfits_key_types
      use imbfits_column_types
      !---------------------------------------------------------------------
      ! @ public
      !---------------------------------------------------------------------
      integer(kind=4),         intent(in)    :: isub     ! Subscan number
      type(imbfits_antfast_t), intent(in)    :: antfast
      character(len=*),        intent(in)    :: column   ! Optional column name
      logical,                 intent(in)    :: short    ! Short or verbose output?
      integer(kind=4),         intent(in)    :: olun     ! Output LUN
      logical,                 intent(inout) :: error
    end subroutine imbfits_dump_antfast
  end interface
  !
  interface
    subroutine imbfits_dump_derot(derot,column,short,olun,error)
      use imbfits_types
      use imbfits_key_types
      use imbfits_column_types
      !---------------------------------------------------------------------
      ! @ public
      !---------------------------------------------------------------------
      type(imbfits_derot_t), intent(in)    :: derot
      character(len=*),      intent(in)    :: column   ! Optional column name
      logical,               intent(in)    :: short    ! Short or verbose output?
      integer(kind=4),       intent(in)    :: olun     ! Output LUN
      logical,               intent(inout) :: error
    end subroutine imbfits_dump_derot
  end interface
  !
  interface
    subroutine imbfits_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 imbfits_message_set_id
  end interface
  !
  interface
    subroutine imbfits_message_debug(doalloc,alloc,doother,other,error)
      use imbfits_messaging
      !---------------------------------------------------------------------
      ! @ public
      !  Alter the imbfits specific severities. You can switch them to
      ! seve%d and seve%i only!
      !---------------------------------------------------------------------
      logical,         intent(in)    :: doalloc  !
      integer(kind=4), intent(in)    :: alloc    ! For iseve%alloc
      logical,         intent(in)    :: doother  !
      integer(kind=4), intent(in)    :: other    ! For iseve%other
      logical,         intent(inout) :: error    ! Logical error flag
    end subroutine imbfits_message_debug
  end interface
  !
  interface
    subroutine imbfits_read_header(filename,imbf,error)
      use gildas_def
      use gbl_message
      use imbfits_types
      !---------------------------------------------------------------------
      ! @ public
      ! Open the file, read the leading HDUs, and build the list
      ! (equivalence classes) of subscans.
      !---------------------------------------------------------------------
      character(len=*), intent(in)    :: filename
      type(imbfits_t),  intent(inout) :: imbf
      logical,          intent(inout) :: error
    end subroutine imbfits_read_header
  end interface
  !
  interface
    subroutine imbfits_open_file(filename,file,hdus,error)
      use gbl_message
      use gildas_def
      use cfitsio_api
      use imbfits_types
      !---------------------------------------------------------------------
      ! @ public
      !---------------------------------------------------------------------
      character(len=*),     intent(in)    :: filename
      type(imbfits_file_t), intent(out)   :: file
      type(imbfits_hdus_t), intent(out)   :: hdus
      logical,              intent(inout) :: error
    end subroutine imbfits_open_file
  end interface
  !
  interface
    subroutine imbfits_read_leadhdus(imbf,error)
      use imbfits_types
      !---------------------------------------------------------------------
      ! @ public
      ! Read the 4 first leading HDUs
      !---------------------------------------------------------------------
      type(imbfits_t), intent(inout) :: imbf
      logical,         intent(inout) :: error
    end subroutine imbfits_read_leadhdus
  end interface
  !
  interface
    subroutine imbfits_close_file(file,error)
      use gbl_message
      use gildas_def
      use cfitsio_api
      use imbfits_types
      !---------------------------------------------------------------------
      ! @ public
      !---------------------------------------------------------------------
      type(imbfits_file_t), intent(inout) :: file
      logical,              intent(inout) :: error
    end subroutine imbfits_close_file
  end interface
  !
  interface
    subroutine imbfits_free_leadhdus(imbf,error)
      use imbfits_types
      !---------------------------------------------------------------------
      ! @ public
      ! Free the leading HDUs. Can be called in an error recovery context
      ! i.e. with error .true. as input.
      !---------------------------------------------------------------------
      type(imbfits_t), intent(inout) :: imbf      !
      logical,         intent(inout) :: error     !
    end subroutine imbfits_free_leadhdus
  end interface
  !
  interface
    subroutine imbfits_read_header_antslow(imbf,isub,mjd_shift,antslow,error)
      use gbl_message
      use cfitsio_api
      use imbfits_types
      use imbfits_parameters
      use imbfits_key_types
      use imbfits_column_types
      !---------------------------------------------------------------------
      ! @ public
      ! Read the IMBF-antenna HDU
      !---------------------------------------------------------------------
      type(imbfits_t),         intent(in)    :: imbf       !
      integer(kind=4),         intent(in)    :: isub       ! Subscan number
      real(kind=8),            intent(in)    :: mjd_shift  ! [sec]
      type(imbfits_antslow_t), intent(inout) :: antslow    !
      logical,                 intent(inout) :: error      !
    end subroutine imbfits_read_header_antslow
  end interface
  !
  interface
    subroutine imbfits_read_header_derot(imbf,derot,error)
      use gbl_message
      use imbfits_types
      !---------------------------------------------------------------------
      ! @ public
      ! Read the IMBF-derot HDU
      !---------------------------------------------------------------------
      type(imbfits_t),       intent(in)    :: imbf   !
      type(imbfits_derot_t), intent(inout) :: derot  !
      logical,               intent(inout) :: error  !
    end subroutine imbfits_read_header_derot
  end interface
  !
  interface
    subroutine imbfits_read_header_derot_onehdu(imbf,derot,error)
      use gbl_message
      use cfitsio_api
      use imbfits_types
      use imbfits_parameters
      use imbfits_key_types
      use imbfits_column_types
      !---------------------------------------------------------------------
      ! @ public
      ! Read the IMBF-derot HDU
      !---------------------------------------------------------------------
      type(imbfits_t),       intent(in)    :: imbf   !
      type(imbfits_derot_t), intent(inout) :: derot  !
      logical,               intent(inout) :: error  !
    end subroutine imbfits_read_header_derot_onehdu
  end interface
  !
  interface
    subroutine imbfits_read_header_derot_allinone(imbf,allderot,error)
      use gbl_message
      use cfitsio_api
      use imbfits_types
      use imbfits_parameters
      !---------------------------------------------------------------------
      ! @ public
      !   Read all the IMBF-derot HDUs (for all subscans) concatenated as a
      ! single pseudo HDU. This subroutine makes sense only for pre-v2
      ! IMB-FITS.
      !   Note that this code assumes:
      !  1) that the subscans are ordered by time, and
      !  2) that the derotator tables are ordered by time.
      ! Possible overlap of the individual tables is correctly accounted
      ! for (duplicates are discarded).
      !---------------------------------------------------------------------
      type(imbfits_t),       intent(in)    :: imbf      !
      type(imbfits_derot_t), intent(inout) :: allderot  !
      logical,               intent(inout) :: error     !
    end subroutine imbfits_read_header_derot_allinone
  end interface
  !
  interface
    function imbfits_subscan_exists(imbf,sname,iclass)
      use imbfits_messaging
      use imbfits_types
      !---------------------------------------------------------------------
      ! @ public
      ! Return .true. if the subscan class 'sname' exists. Optionally
      ! return the equivalence class number.
      !---------------------------------------------------------------------
      logical :: imbfits_subscan_exists
      type(imbfits_t),            intent(in)  :: imbf    !
      character(len=*),           intent(in)  :: sname   ! Subscan eclass name
      integer(kind=4),  optional, intent(out) :: iclass  ! Subscan eclass number
    end function imbfits_subscan_exists
  end interface
  !
  interface
    subroutine imbfits_read_subscan_header(imbf,sname,snum,goodonly,mjdinter,  &
      mjd_shift,subs,error)
      use imbfits_messaging
      use imbfits_types
      !---------------------------------------------------------------------
      ! @ public
      ! Given a subscan name and relative number, move to the HDU and read
      ! the subscan headers from file.
      !---------------------------------------------------------------------
      type(imbfits_t),         intent(in)    :: imbf
      character(len=*),        intent(in)    :: sname      ! Subscan name
      integer(kind=4),         intent(in)    :: snum       ! Subscan number
      logical,                 intent(in)    :: goodonly   ! Ignore bad data?
      logical,                 intent(in)    :: mjdinter   ! Compute MJD intersection?
      real(kind=8),            intent(in)    :: mjd_shift  ! [sec]
      type(imbfits_subscan_t), intent(inout) :: subs
      logical,                 intent(inout) :: error
    end subroutine imbfits_read_subscan_header
  end interface
  !
  interface
    subroutine imbfits_read_subscan_header_bynum(imbf,isub,goodonly,mjdinter,  &
      mjd_shift,subs,error)
      use gbl_message
      use cfitsio_api
      use imbfits_types
      !---------------------------------------------------------------------
      ! @ public
      ! Given a subscan absolute number, move the HDU and read the subscan
      ! headers from file. On return let the CFITSIO pointer to the
      ! IMBF-backdataXXX HDU, such as its DATA column can be read right
      ! after.
      !---------------------------------------------------------------------
      type(imbfits_t),         intent(in)    :: imbf
      integer(kind=4),         intent(in)    :: isub
      logical,                 intent(in)    :: goodonly   ! Ignore bad data?
      logical,                 intent(in)    :: mjdinter   ! Compute MJD intersection?
      real(kind=8),            intent(in)    :: mjd_shift  ! [sec] Antslow MJD shift
      type(imbfits_subscan_t), intent(inout) :: subs
      logical,                 intent(inout) :: error
    end subroutine imbfits_read_subscan_header_bynum
  end interface
  !
  interface
    subroutine imbfits_free_header_antslow(antslow,error)
      use imbfits_types
      !---------------------------------------------------------------------
      ! @ public
      ! Free the IMBF-antenna HDU
      !---------------------------------------------------------------------
      type(imbfits_antslow_t), intent(inout) :: antslow  !
      logical,                 intent(inout) :: error    !
    end subroutine imbfits_free_header_antslow
  end interface
  !
  interface
    subroutine imbfits_free_subscan_header(subs,error)
      use imbfits_types
      !---------------------------------------------------------------------
      ! @ public
      ! Free subscan data (except DATA column)
      !---------------------------------------------------------------------
      type(imbfits_subscan_t), intent(inout) :: subs
      logical,                 intent(inout) :: error
    end subroutine imbfits_free_subscan_header
  end interface
  !
  interface
    subroutine imbfits_read_data(caller,file,nchan,npix,ftime,ntime,  &
      imbdata,error)
      use gbl_message
      use cfitsio_api
      use imbfits_types
      !---------------------------------------------------------------------
      ! @ public
      ! Reading subroutine specific to the 'DATA' column
      !---------------------------------------------------------------------
      character(len=*),     intent(in)    :: caller   ! Name of calling subroutine
      type(imbfits_file_t), intent(in)    :: file     !
      integer(kind=4),      intent(in)    :: nchan    !
      integer(kind=4),      intent(in)    :: npix     !
      integer(kind=4),      intent(in)    :: ftime    ! First 'time' row read
      integer(kind=4),      intent(in)    :: ntime    ! Number of 'time' rows read
      type(imbfits_data_t), intent(inout) :: imbdata  !
      logical,              intent(inout) :: error    !
    end subroutine imbfits_read_data
  end interface
  !
  interface
    subroutine imbfits_free_data(imbdata,error)
      use imbfits_types
      !---------------------------------------------------------------------
      ! @ public
      ! Freeing subroutine specific to the 'DATA' column
      !---------------------------------------------------------------------
      type(imbfits_data_t), intent(inout) :: imbdata  !
      logical,              intent(inout) :: error    !
    end subroutine imbfits_free_data
  end interface
  !
  interface
    subroutine imbfits_dump_imbfdata(imbf,olun,error)
      use gbl_message
      use imbfits_types
      use ram_sizes
      !---------------------------------------------------------------------
      ! @ public
      !---------------------------------------------------------------------
      type(imbfits_data_t), intent(in)    :: imbf
      integer(kind=4),      intent(in)    :: olun   ! Output LUN
      logical,              intent(inout) :: error
    end subroutine imbfits_dump_imbfdata
  end interface
  !
  interface
    subroutine imbfits_mvhdu_subscan(isub,hduid,imbf,error)
      use imbfits_messaging
      use imbfits_types
      !---------------------------------------------------------------------
      ! @ public
      ! Move to appropriate HDU for the isub-th subscan
      !---------------------------------------------------------------------
      integer(kind=4), intent(in)    :: isub   ! Subscan number
      integer(kind=4), intent(in)    :: hduid  ! HDU identifier
      type(imbfits_t), intent(in)    :: imbf   !
      logical,         intent(inout) :: error  !
    end subroutine imbfits_mvhdu_subscan
  end interface
  !
  interface
    subroutine imbfits_copy_back_chunks(ichunks,ochunks,error)
      use imbfits_types
      !---------------------------------------------------------------------
      ! @ public
      !---------------------------------------------------------------------
      type(imbfits_back_chunks_t), intent(in)    :: ichunks
      type(imbfits_back_chunks_t), intent(inout) :: ochunks
      logical,                     intent(inout) :: error
    end subroutine imbfits_copy_back_chunks
  end interface
  !
  interface
    subroutine imbfits_free_back_chunks(chunks,error)
      use imbfits_types
      !---------------------------------------------------------------------
      ! @ public
      !---------------------------------------------------------------------
      type(imbfits_back_chunks_t), intent(inout) :: chunks
      logical,                     intent(inout) :: error
    end subroutine imbfits_free_back_chunks
  end interface
  !
  interface
    subroutine imbfits_init_stokesloop(book,error)
      use gbl_message
      use imbfits_types
      !---------------------------------------------------------------------
      ! @ public
      !  Initialize the stokesset_book_t for later use by
      ! imbfits_get_next_stokesset
      !---------------------------------------------------------------------
      type(stokesset_book_t), intent(inout) :: book
      logical,                intent(inout) :: error
    end subroutine imbfits_init_stokesloop
  end interface
  !
  interface
    subroutine imbfits_get_next_stokesset(cdesc,book,error)
      use gbl_message
      use imbfits_types
      !---------------------------------------------------------------------
      ! @ public
      !  Get the next stokeset. As of today a stokeset can be:
      !  - A unique NONE chunkset (no polarimetry)
      !  - A collection AXISH+AXISV+REAL+IMAG (polarimetric chunksets)
      !---------------------------------------------------------------------
      type(imbfits_back_chunks_t), intent(in)    :: cdesc  ! Chunks description
      type(stokesset_book_t),      intent(inout) :: book   !
      logical,                     intent(inout) :: error  !
    end subroutine imbfits_get_next_stokesset
  end interface
  !
  interface
    subroutine imbfits_count_polar_stokesset(cdesc,nset,error)
      use imbfits_types
      !---------------------------------------------------------------------
      ! @ public
      !  Count the number POLARIMETRIC stokesets that would be found when
      ! iterating with imbfits_get_next_stokesset
      !---------------------------------------------------------------------
      type(imbfits_back_chunks_t), intent(in)    :: cdesc  ! Chunks description
      integer(kind=4),             intent(out)   :: nset   ! Number of stokesset
      logical,                     intent(inout) :: error  ! Logical error flag
    end subroutine imbfits_count_polar_stokesset
  end interface
  !
  interface
    subroutine imbfits_upcase_column(char,error)
      use imbfits_types
      !---------------------------------------------------------------------
      ! @ public
      !---------------------------------------------------------------------
      type(fits_char_1d_t), intent(inout) :: char
      logical,              intent(inout) :: error
    end subroutine imbfits_upcase_column
  end interface
  !
  interface imbfits_free_column
    subroutine imbfits_free_logi_1d(logi,error)
      use gbl_message
      use imbfits_types
      !---------------------------------------------------------------------
      ! @ public-generic imbfits_free_column
      !---------------------------------------------------------------------
      type(fits_logi_1d_t), intent(inout) :: logi    ! INOUT: keep allocation status
      logical,              intent(inout) :: error
    end subroutine imbfits_free_logi_1d
    subroutine imbfits_free_inte_1d(inte,error)
      use gbl_message
      use imbfits_types
      !---------------------------------------------------------------------
      ! @ public-generic imbfits_free_column
      !---------------------------------------------------------------------
      type(fits_inte_1d_t), intent(inout) :: inte    ! INOUT: keep allocation status
      logical,              intent(inout) :: error
    end subroutine imbfits_free_inte_1d
    subroutine imbfits_free_real_1d(real,error)
      use gbl_message
      use imbfits_types
      !---------------------------------------------------------------------
      ! @ public-generic imbfits_free_column
      !---------------------------------------------------------------------
      type(fits_real_1d_t), intent(inout) :: real    ! INOUT: keep allocation status
      logical,              intent(inout) :: error
    end subroutine imbfits_free_real_1d
    subroutine imbfits_free_dble_1d(dble,error)
      use gbl_message
      use imbfits_types
      !---------------------------------------------------------------------
      ! @ public-generic imbfits_free_column
      !---------------------------------------------------------------------
      type(fits_dble_1d_t), intent(inout) :: dble    ! INOUT: keep allocation status
      logical,              intent(inout) :: error
    end subroutine imbfits_free_dble_1d
    subroutine imbfits_free_char_1d(char,error)
      use gbl_message
      use imbfits_types
      !---------------------------------------------------------------------
      ! @ public-generic imbfits_free_column
      !---------------------------------------------------------------------
      type(fits_char_1d_t), intent(inout) :: char    ! INOUT: keep allocation status
      logical,              intent(inout) :: error
    end subroutine imbfits_free_char_1d
  end interface imbfits_free_column
  !
  interface
    subroutine imbfits_variable_imbfits(struct,imbf,ro,error)
      use imbfits_types
      !---------------------------------------------------------------------
      ! @ public
      !  Create or recreate Sic variables mapping a imbfits_t
      ! structure.
      !---------------------------------------------------------------------
      character(len=*), intent(in)    :: struct  ! Parent structure name
      type(imbfits_t),  intent(in)    :: imbf    !
      logical,          intent(in)    :: ro      ! Read-Only
      logical,          intent(inout) :: error   !
    end subroutine imbfits_variable_imbfits
  end interface
  !
  interface
    subroutine imbfits_variable_subscan(struct,subs,ro,error)
      use imbfits_types
      !---------------------------------------------------------------------
      ! @ public
      !  Create or recreate Sic variables mapping a imbfits_subscan_t
      ! structure.
      !---------------------------------------------------------------------
      character(len=*),        intent(in)    :: struct  ! Parent structure name
      type(imbfits_subscan_t), intent(in)    :: subs    !
      logical,                 intent(in)    :: ro      ! Read-Only
      logical,                 intent(inout) :: error   !
    end subroutine imbfits_variable_subscan
  end interface
  !
  interface
    subroutine imbfits_variable_imbfdata(struct,imbf,ro,error)
      use gildas_def
      use imbfits_types
      !---------------------------------------------------------------------
      ! @ public
      !  Create or recreate Sic variables mapping a imbfits_data_t
      ! structure.
      !---------------------------------------------------------------------
      character(len=*),     intent(in)    :: struct  ! Parent structure name
      type(imbfits_data_t), intent(in)    :: imbf    !
      logical,              intent(in)    :: ro      ! Read-Only
      logical,              intent(inout) :: error   !
    end subroutine imbfits_variable_imbfdata
  end interface
  !
end module imbfits_interfaces_public
