module gwcs_interfaces_public
  interface
    subroutine gwcs_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 gwcs_message_set_id
  end interface
  !
  interface
    subroutine modify_frame_velocity(new_velo,rchan,freq,fres,old_velo,vres,error)
      use phys_const
      !---------------------------------------------------------------------
      ! @ public
      ! Change Frame Velocity
      ! All updated values are intent(inout) because they are not modified
      ! if there is nothing to be done.
      !---------------------------------------------------------------------
      real(kind=4), intent(in)    :: new_velo  ! Desired velocity
      real(kind=8), intent(inout) :: rchan     ! Reference channel
      real(kind=8), intent(in)    :: freq      ! Frequency at ref. channel
      real(kind=8), intent(inout) :: fres      ! Frequency resolution
      real(kind=4), intent(inout) :: old_velo  ! Velocity at ref. channel
      real(kind=4), intent(inout) :: vres      ! Velocity resolution
      logical,      intent(inout) :: error     ! Logical error flag
    end subroutine modify_frame_velocity
  end interface
  !
  interface
    subroutine modify_rest_frequency(new_freq,rchan,old_freq,image,fres,vres,error)
      use phys_const
      !---------------------------------------------------------------------
      ! @ public
      ! Change Rest Frequency
      ! All updated values are intent(inout) because they are not modified
      ! if there is nothing to be done.
      !---------------------------------------------------------------------
      real(kind=8), intent(in)    :: new_freq  ! Desired frequency
      real(kind=8), intent(inout) :: rchan     ! Reference channel
      real(kind=8), intent(inout) :: old_freq  ! Frequency at ref. channel
      real(kind=8), intent(inout) :: image     ! Image frequency at ref. channel
      real(kind=8), intent(inout) :: fres      ! Frequency resolution
      real(kind=4), intent(inout) :: vres      ! Velocity resolution
      logical,      intent(inout) :: error     ! Logical error flag
    end subroutine modify_rest_frequency
  end interface
  !
  interface
    subroutine equ_to_gal(ra,dec,raoff,decoff,equinox,l,b,loff,boff,error)
      use gbl_constant
      use gbl_message
      !---------------------------------------------------------------------
      ! @ public
      !  Convert 1 position + 1 offset from Equatorial+Equinox to Galactic
      !---------------------------------------------------------------------
      real(kind=8), intent(in)    :: ra       !
      real(kind=8), intent(in)    :: dec      !
      real(kind=4), intent(in)    :: raoff    !
      real(kind=4), intent(in)    :: decoff   !
      real(kind=4), intent(in)    :: equinox  !
      real(kind=8), intent(out)   :: l        !
      real(kind=8), intent(out)   :: b        !
      real(kind=4), intent(out)   :: loff     !
      real(kind=4), intent(out)   :: boff     !
      logical,      intent(inout) :: error    !
    end subroutine equ_to_gal
  end interface
  !
  interface
    subroutine gal_to_equ(l,b,loff,boff,ra,dec,raoff,decoff,equinox,error)
      use gbl_constant
      use gbl_message
      !---------------------------------------------------------------------
      ! @ public
      !  Convert 1 position + 1 offset from Galactic to Equatorial+Equinox
      !---------------------------------------------------------------------
      real(kind=8), intent(in)    :: l        !
      real(kind=8), intent(in)    :: b        !
      real(kind=4), intent(in)    :: loff     !
      real(kind=4), intent(in)    :: boff     !
      real(kind=8), intent(out)   :: ra       !
      real(kind=8), intent(out)   :: dec      !
      real(kind=4), intent(out)   :: raoff    !
      real(kind=4), intent(out)   :: decoff   !
      real(kind=4), intent(in)    :: equinox  !
      logical,      intent(inout) :: error    !
    end subroutine gal_to_equ
  end interface
  !
  interface
    subroutine equ_to_equ(inra,indec,inroff,indoff,inequinox,ra,dec,  &
      raoff,decoff,equinox,error)
      use gbl_constant
      use gbl_message
      !---------------------------------------------------------------------
      ! @ public
      !  Convert 1 position + 1 offset from Equatorial+Equinox to
      ! Equatorial+Equinox
      !---------------------------------------------------------------------
      real(kind=8), intent(in)    :: inra       !
      real(kind=8), intent(in)    :: indec      !
      real(kind=4), intent(in)    :: inroff     !
      real(kind=4), intent(in)    :: indoff     !
      real(kind=4), intent(in)    :: inequinox  !
      real(kind=8), intent(out)   :: ra         !
      real(kind=8), intent(out)   :: dec        !
      real(kind=4), intent(out)   :: raoff      !
      real(kind=4), intent(out)   :: decoff     !
      real(kind=4), intent(in)    :: equinox    !
      logical,      intent(inout) :: error      !
    end subroutine equ_to_equ
  end interface
  !
  interface
    subroutine chgcoo(oldtyp,newtyp,oldepo,newepo,matrix)
      !---------------------------------------------------------------------
      ! @ public
      !  Change Coordinate system
      !------------------------------------------------------------------------
      character(len=2), intent(in)  :: oldtyp        ! Coordinate input type
      character(len=2), intent(in)  :: newtyp        ! Coordinate output type
      real(kind=4),     intent(in)  :: oldepo        ! Coordinate input epoch (if 'EQ')
      real(kind=4),     intent(in)  :: newepo        ! Coordinate output epoch (if 'EQ')
      real(kind=8),     intent(out) :: matrix(3,3)   ! Rotation Matrix
    end subroutine chgcoo
  end interface
  !
  interface
    subroutine qprec (ti,tf,angles)
      !---------------------------------------------------------------------
      ! @ public
      !  precession entre deux epoques selon Lieske et al (1977)
      !  from EPHAUT / BDL / C002 / 81-1
      !  modified 29 november 1984 by Michel Perault
      !  calcul de quantites liees aux deplacements precessionnels de
      !  l'equateur et de l'ecliptique entre deux epoques donnees
      !  en entree : TI epoque initiale (jours juliens)
      !              TF epoque finale (jours juliens)
      !  en sortie : ANGLES(1-3) quantites liees au deplacement precessionnel
      !              de l'equateur entre TI et TF (radian)
      !              ANGLES(4-6) quantites liees au deplacement precessionnel
      !              de l'ecliptique entre TI et TF (radian)
      !  notations : ANGLES(1) = DZETA
      !              ANGLES(2) = Z
      !              ANGLES(3) = TETA
      !              ANGLES(4) = petit PI
      !              ANGLES(5) = grand PI
      !              ANGLES(6) = P (precession generale en longitude)
      !  remarque  : les temps sont mesures en siecle julien a partir de
      !              l'epoque J2000.0 (JJ2451545)
      !---------------------------------------------------------------------
      real(kind=8), intent(in)  :: ti         !
      real(kind=8), intent(in)  :: tf         !
      real(kind=8), intent(out) :: angles(6)  !
    end subroutine qprec
  end interface
  !
  interface
    subroutine b1950_to_j2000(obs_epoch,alpha,delta)
      !---------------------------------------------------------------------
      ! @ public
      ! Convert Besselian coordinates to J2000, assuming zero proper motion,
      ! parallax, and radial velocity. Calls the general implementation of
      ! the formulas from Aoki et al AA 128, 263 (1983)
      !---------------------------------------------------------------------
      real(kind=4), intent(in)    :: obs_epoch  !
      real(kind=8), intent(inout) :: alpha      !
      real(kind=8), intent(inout) :: delta      !
    end subroutine b1950_to_j2000
  end interface
  !
  interface
    subroutine do_precess(epoch, new_epoch, lambda, beta)
      !---------------------------------------------------------------------
      ! @ public
      !---------------------------------------------------------------------
      real(kind=4), intent(inout) :: epoch      !
      real(kind=4), intent(in)    :: new_epoch  !
      real(kind=8), intent(inout) :: lambda     !
      real(kind=8), intent(inout) :: beta       !
    end subroutine do_precess
  end interface
  !
  interface
    subroutine spher (x, a)
      !---------------------------------------------------------------------
      ! @ public
      !       CARTESIAN TO SPHERICAL COORDINATE CONVERSION
      !------------------------------------------------------------------------
      real(kind=8), intent(in)  :: x(3)  ! Cartesian coordinates
      real(kind=8), intent(out) :: a(2)  ! Spherical coordinates
    end subroutine spher
  end interface
  !
  interface
    subroutine rect (a, x)
      !---------------------------------------------------------------------
      ! @ public
      !       SPHERICAL TO CARTESIAN COORDINATES CONVERSION
      !---------------------------------------------------------------------
      real(kind=8), intent(in)  :: a(2)  ! Spherical coordinates
      real(kind=8), intent(out) :: x(3)  ! Cartesian coordinates
    end subroutine rect
  end interface
  !
  interface equ_equ
    subroutine equ_equ_0d(ra1,dec1,equinox1,ra2,dec2,equinox2,error)
      use gbl_constant
      use gbl_message
      !---------------------------------------------------------------------
      ! @ public-generic equ_equ
      !  Convert 1 position from Equatorial+Equinox to Equatorial+Equinox
      !  Scalar version
      !---------------------------------------------------------------------
      real(kind=8),    intent(in)    :: ra1       !
      real(kind=8),    intent(in)    :: dec1      !
      real(kind=4),    intent(in)    :: equinox1  !
      real(kind=8),    intent(out)   :: ra2       !
      real(kind=8),    intent(out)   :: dec2      !
      real(kind=4),    intent(in)    :: equinox2  !
      logical,         intent(inout) :: error     !
    end subroutine equ_equ_0d
    subroutine equ_equ_1d(ra1,dec1,equinox1,ra2,dec2,equinox2,n,error)
      use gbl_constant
      use gbl_message
      !---------------------------------------------------------------------
      ! @ public-generic equ_equ
      !  Convert 1 position from Equatorial+Equinox to Equatorial+Equinox
      !  1D-array version
      !---------------------------------------------------------------------
      integer(kind=4), intent(in)    :: n         !
      real(kind=8),    intent(in)    :: ra1(n)    !
      real(kind=8),    intent(in)    :: dec1(n)   !
      real(kind=4),    intent(in)    :: equinox1  !
      real(kind=8),    intent(out)   :: ra2(n)    !
      real(kind=8),    intent(out)   :: dec2(n)   !
      real(kind=4),    intent(in)    :: equinox2  !
      logical,         intent(inout) :: error     !
    end subroutine equ_equ_1d
    subroutine equ_equ_2d(ra1,dec1,equinox1,ra2,dec2,equinox2,n,m,error)
      use gbl_constant
      use gbl_message
      !---------------------------------------------------------------------
      ! @ public-generic equ_equ
      !  Convert 1 position from Equatorial+Equinox to Equatorial+Equinox
      !  2D-array version
      !---------------------------------------------------------------------
      integer(kind=4), intent(in)    :: n,m        !
      real(kind=8),    intent(in)    :: ra1(n,m)   !
      real(kind=8),    intent(in)    :: dec1(n,m)  !
      real(kind=4),    intent(in)    :: equinox1   !
      real(kind=8),    intent(out)   :: ra2(n,m)   !
      real(kind=8),    intent(out)   :: dec2(n,m)  !
      real(kind=4),    intent(in)    :: equinox2   !
      logical,         intent(inout) :: error      !
    end subroutine equ_equ_2d
  end interface equ_equ
  !
  interface equ_gal
    subroutine equ_gal_0d(ra,dec,equinox,l,b,error)
      use gbl_constant
      use gbl_message
      !---------------------------------------------------------------------
      ! @ public-generic equ_gal
      !  Convert 1 position from Equatorial+Equinox to Galactic
      !  Scalar version
      !---------------------------------------------------------------------
      real(kind=8),    intent(in)    :: ra       !
      real(kind=8),    intent(in)    :: dec      !
      real(kind=4),    intent(in)    :: equinox  !
      real(kind=8),    intent(out)   :: l        !
      real(kind=8),    intent(out)   :: b        !
      logical,         intent(inout) :: error    !
    end subroutine equ_gal_0d
    subroutine equ_gal_1d(ra,dec,equinox,l,b,n,error)
      use gbl_constant
      use gbl_message
      !---------------------------------------------------------------------
      ! @ public-generic equ_gal
      !  Convert 1 position from Equatorial+Equinox to Galactic
      !  1D-array version
      !---------------------------------------------------------------------
      integer(kind=4), intent(in)    :: n         !
      real(kind=8),    intent(in)    :: ra(n)     !
      real(kind=8),    intent(in)    :: dec(n)    !
      real(kind=4),    intent(in)    :: equinox   !
      real(kind=8),    intent(out)   :: l(n)      !
      real(kind=8),    intent(out)   :: b(n)      !
      logical,         intent(inout) :: error     !
    end subroutine equ_gal_1d
    subroutine equ_gal_2d(ra,dec,equinox,l,b,n,m,error)
      use gbl_constant
      use gbl_message
      !---------------------------------------------------------------------
      ! @ public-generic equ_gal
      !  Convert 1 position from Equatorial+Equinox to Galactic
      !  2D-array version
      !---------------------------------------------------------------------
      integer(kind=4), intent(in)    :: n,m       !
      real(kind=8),    intent(in)    :: ra(n,m)   !
      real(kind=8),    intent(in)    :: dec(n,m)  !
      real(kind=4),    intent(in)    :: equinox   !
      real(kind=8),    intent(out)   :: l(n,m)    !
      real(kind=8),    intent(out)   :: b(n,m)    !
      logical,         intent(inout) :: error     !
    end subroutine equ_gal_2d
  end interface equ_gal
  !
  interface gal_equ
    subroutine gal_equ_0d(l,b,ra,dec,equinox,error)
      use gbl_constant
      use gbl_message
      !---------------------------------------------------------------------
      ! @ public-generic gal_equ
      !  Convert 1 position from Galactic to Equatorial+Equinox
      !  Scalar version
      !---------------------------------------------------------------------
      real(kind=8),    intent(in)    :: l        !
      real(kind=8),    intent(in)    :: b        !
      real(kind=8),    intent(out)   :: ra       !
      real(kind=8),    intent(out)   :: dec      !
      real(kind=4),    intent(in)    :: equinox  !
      logical,         intent(inout) :: error    !
    end subroutine gal_equ_0d
    subroutine gal_equ_1d(l,b,ra,dec,equinox,n,error)
      use gbl_constant
      use gbl_message
      !---------------------------------------------------------------------
      ! @ public-generic gal_equ
      !  Convert 1 position from Galactic to Equatorial+Equinox
      !  1D-array version
      !---------------------------------------------------------------------
      integer(kind=4), intent(in)    :: n        !
      real(kind=8),    intent(in)    :: l(n)     !
      real(kind=8),    intent(in)    :: b(n)     !
      real(kind=8),    intent(out)   :: ra(n)    !
      real(kind=8),    intent(out)   :: dec(n)   !
      real(kind=4),    intent(in)    :: equinox  !
      logical,         intent(inout) :: error    !
    end subroutine gal_equ_1d
    subroutine gal_equ_2d(l,b,ra,dec,equinox,n,m,error)
      use gbl_constant
      use gbl_message
      !---------------------------------------------------------------------
      ! @ public-generic gal_equ
      !  Convert 1 position from Galactic to Equatorial+Equinox
      !  1D-array version
      !---------------------------------------------------------------------
      integer(kind=4), intent(in)    :: n,m       !
      real(kind=8),    intent(in)    :: l(n,m)    !
      real(kind=8),    intent(in)    :: b(n,m)    !
      real(kind=8),    intent(out)   :: ra(n,m)   !
      real(kind=8),    intent(out)   :: dec(n,m)  !
      real(kind=4),    intent(in)    :: equinox   !
      logical,         intent(inout) :: error     !
    end subroutine gal_equ_2d
  end interface gal_equ
  !
  interface
    subroutine eq1950_gal(a,d,lii,bii,n)
      use phys_const
      !---------------------------------------------------------------------
      ! @ public
      !  Converts (A,D) (1950.0) in LII,BII
      !  Units are radians
      !---------------------------------------------------------------------
      real(kind=8),    intent(in)  :: a(*)    !
      real(kind=8),    intent(in)  :: d(*)    !
      real(kind=8),    intent(out) :: lii(*)  !
      real(kind=8),    intent(out) :: bii(*)  !
      integer(kind=4), intent(in)  :: n       !
    end subroutine eq1950_gal
  end interface
  !
  interface
    subroutine gal_eq1950(lii,bii,a,d,n)
      use phys_const
      !---------------------------------------------------------------------
      ! @ public
      !   Converts Lii,Bii to (A,D) (1950.0)
      !   Units are radians
      !---------------------------------------------------------------------
      real(kind=8),    intent(in)  :: lii(*)  !
      real(kind=8),    intent(in)  :: bii(*)  !
      real(kind=8),    intent(out) :: a(*)    !
      real(kind=8),    intent(out) :: d(*)    !
      integer(kind=4), intent(in)  :: n       !
    end subroutine gal_eq1950
  end interface
  !
  interface
    subroutine gwcs_projec(a0,d0,pangle,ptype,proj,error)
      use phys_const
      use gbl_constant
      use gbl_message
      use gwcs_types
      !---------------------------------------------------------------------
      ! @ public
      !       Define a projection
      !---------------------------------------------------------------------
      real(kind=8),       intent(in)    :: a0      !
      real(kind=8),       intent(in)    :: d0      !
      real(kind=8),       intent(in)    :: pangle  !
      integer(kind=4),    intent(in)    :: ptype   !
      type(projection_t), intent(out)   :: proj    !
      logical,            intent(inout) :: error   !
    end subroutine gwcs_projec
  end interface
  !
  interface
    subroutine abs_add_distance(lon1,lat1,off,angl,lon2,lat2)
      !---------------------------------------------------------------------
      ! @ public
      !   Add a distance to absolute spherical coordinates and return the
      ! resulting absolute spherical coordinates.
      !  This is basically an inverse Haversine formula.
      !  Angle:
      !    North   0
      !    East   90 (with longitude increasing towards East)
      !    South 180
      !    West  270
      !---------------------------------------------------------------------
      real(kind=8), intent(in)  ::  lon1  ! [rad] Longitude of input coordinates
      real(kind=8), intent(in)  ::  lat1  ! [rad] Latitude of input coordinates
      real(kind=8), intent(in)  ::  off   ! [rad] Offset/distance to be added
      real(kind=8), intent(in)  ::  angl  ! [rad] Angle of offset
      real(kind=8), intent(out) ::  lon2  ! [rad] Longitude of output coordinates
      real(kind=8), intent(out) ::  lat2  ! [rad] Latitude of output coordinates
    end subroutine abs_add_distance
  end interface
  !
  interface abs_to_rel
    subroutine abs_to_rel_0d(proj,a,d,x,y,n)
      use gwcs_types
      !---------------------------------------------------------------------
      ! @ public-generic abs_to_rel
      !  Convert a set of plane position to spherical coordinates according
      ! to the current projection formulae
      ! ---
      ! This version for scalar values
      !---------------------------------------------------------------------
      type(projection_t), intent(in)  :: proj  ! Description of projection
      real(kind=8),       intent(in)  :: a     ! R.A. (radians)
      real(kind=8),       intent(in)  :: d     ! Declinations
      real(kind=8),       intent(out) :: x     ! Offset in X
      real(kind=8),       intent(out) :: y     ! Offset in Y
      integer(kind=4),    intent(in)  :: n     ! Useless, assumed 1
    end subroutine abs_to_rel_0d
    subroutine abs_to_rel_1dn4(proj,a,d,x,y,n)
      use phys_const
      use gbl_constant
      use gbl_message
      use gwcs_types
      !---------------------------------------------------------------------
      ! @ public-generic abs_to_rel
      !  Convert a set of plane position to spherical coordinates according
      ! to the current projection formulae
      ! ---
      ! This version for 1D arrays, size as I*4
      !---------------------------------------------------------------------
      type(projection_t), intent(in)  :: proj  ! Description of projection
      real(kind=8),       intent(in)  :: a(*)  ! Array of R.A. (radians)
      real(kind=8),       intent(in)  :: d(*)  ! Array of declinations
      real(kind=8),       intent(out) :: x(*)  ! Array of offsets in X
      real(kind=8),       intent(out) :: y(*)  ! Array of offsets in Y
      integer(kind=4),    intent(in)  :: n     ! Size of arrays
    end subroutine abs_to_rel_1dn4
    subroutine abs_to_rel_1dn8(proj,a,d,x,y,n)
      use phys_const
      use gbl_constant
      use gbl_message
      use gwcs_types
      !---------------------------------------------------------------------
      ! @ public-generic abs_to_rel
      !  Convert a set of plane position to spherical coordinates according
      ! to the current projection formulae
      ! ---
      ! This version for 1D arrays, size as I*8
      !---------------------------------------------------------------------
      type(projection_t), intent(in)  :: proj  ! Description of projection
      real(kind=8),       intent(in)  :: a(*)  ! Array of R.A. (radians)
      real(kind=8),       intent(in)  :: d(*)  ! Array of declinations
      real(kind=8),       intent(out) :: x(*)  ! Array of offsets in X
      real(kind=8),       intent(out) :: y(*)  ! Array of offsets in Y
      integer(kind=8),    intent(in)  :: n     ! Size of arrays
    end subroutine abs_to_rel_1dn8
  end interface abs_to_rel
  !
  interface rel_to_abs
    subroutine rel_to_abs_0d(proj,x,y,a,d,n)
      use gwcs_types
      !---------------------------------------------------------------------
      ! @ public-generic rel_to_abs
      !  Convert a set of plane position to spherical coordinates according
      ! to the current projection formulae
      ! ---
      ! This version for scalar values
      !---------------------------------------------------------------------
      type(projection_t), intent(in)  :: proj  ! Description of projection
      real(kind=8),       intent(in)  :: x     ! Offset in X
      real(kind=8),       intent(in)  :: y     ! Offset in Y
      real(kind=8),       intent(out) :: a     ! R.A. (radians)
      real(kind=8),       intent(out) :: d     ! Declinations
      integer(kind=4),    intent(in)  :: n     ! Useless, assumed 1
    end subroutine rel_to_abs_0d
    subroutine rel_to_abs_1dn4(proj,x,y,a,d,n)
      use gwcs_types
      !---------------------------------------------------------------------
      ! @ public-generic rel_to_abs
      !  Convert a set of plane position to spherical coordinates according
      ! to the current projection formulae
      ! ---
      ! This version for 1D arrays, size as I*4
      !---------------------------------------------------------------------
      type(projection_t), intent(in)  :: proj  ! Description of projection
      real(kind=8),       intent(in)  :: x(*)  ! Array of offsets in X
      real(kind=8),       intent(in)  :: y(*)  ! Array of offsets in Y
      real(kind=8),       intent(out) :: a(*)  ! Array of R.A. (radians)
      real(kind=8),       intent(out) :: d(*)  ! Array of declinations
      integer(kind=4),    intent(in)  :: n     ! Size of arrays
    end subroutine rel_to_abs_1dn4
    subroutine rel_to_abs_1dn8(proj,x,y,a,d,n)
      use phys_const
      use gbl_constant
      use gbl_message
      use gwcs_types
      !---------------------------------------------------------------------
      ! @ public-generic rel_to_abs
      !  Convert a set of plane position to spherical coordinates according
      ! to the current projection formulae
      ! ---
      ! This version for 1D arrays, size as I*8
      !---------------------------------------------------------------------
      type(projection_t), intent(in)  :: proj  ! Description of projection
      real(kind=8),       intent(in)  :: x(*)  ! Array of offsets in X
      real(kind=8),       intent(in)  :: y(*)  ! Array of offsets in Y
      real(kind=8),       intent(out) :: a(*)  ! Array of R.A. (radians)
      real(kind=8),       intent(out) :: d(*)  ! Array of declinations
      integer(kind=8),    intent(in)  :: n     ! Size of arrays
    end subroutine rel_to_abs_1dn8
  end interface rel_to_abs
  !
  interface
    function projnam(iproj)
      use gbl_message
      !---------------------------------------------------------------------
      ! @ public
      ! Return the projection name as a character string
      ! ---
      !  The purpose of this function is to avoid declaring a static
      ! character string array containing the projection names: there are
      ! difficulties to share such kind of data between libraries under
      ! several systems (MSWIN, MINGW, ...)
      !---------------------------------------------------------------------
      character(len=13) :: projnam  ! Function value on return
      integer(kind=4), intent(in) :: iproj  ! The projection number
    end function projnam
  end interface
  !
  interface
    subroutine projnam_list(list)
      use gbl_constant
      !---------------------------------------------------------------------
      ! @ public
      ! Return the list of projections in a string array
      !---------------------------------------------------------------------
      character(len=*), intent(out) :: list(0:mproj)  !
    end subroutine projnam_list
  end interface
  !
  interface
    function gwcs_observatory_exists(arg)
      !---------------------------------------------------------------------
      ! @ public
      ! Function evaluates as true if the named observatory is known here
      !---------------------------------------------------------------------
      logical :: gwcs_observatory_exists
      character(len=*), intent(in) :: arg ! Telescope name
    end function gwcs_observatory_exists
  end interface
  !
  interface
    subroutine gwcs_print_telescope(teles,line)
      use image_def
      !---------------------------------------------------------------------
      ! @ public
      ! Build a one-line description of a type 'telesco'. This line is well
      ! suited for command V\HEADER.
      !---------------------------------------------------------------------
      type(telesco),    intent(in)  :: teles
      character(len=*), intent(out) :: line
    end subroutine gwcs_print_telescope
  end interface
  !
  interface
    subroutine gwcs_sexa(line,value,error)
      use gbl_message
      !---------------------------------------------------------------------
      ! @ public
      !  Decode a sexagesimal notation
      !---------------------------------------------------------------------
      character(len=*), intent(in)    :: line   !
      real(kind=8),     intent(out)   :: value  !
      logical,          intent(inout) :: error  !
    end subroutine gwcs_sexa
  end interface
  !
  interface
    subroutine gwcs_geo2lonlat(xyz,clon,clat,alt)
      !----------------------------------------------------
      ! @ public
      !   GWCS
      !   Convert XYZ to Longitude, Latitude, Altitude
      !----------------------------------------------------
      real(8), intent(in) :: xyz(3)
      character(len=*), intent(out) :: clon  ! In degree, sexagesimal
      character(len=*), intent(out) :: clat  ! In degree, sexagesimal
      real(8), intent(out) :: alt
    end subroutine gwcs_geo2lonlat
  end interface
  !
  interface
    subroutine gwcs_lonlat2geo(clon,clat,alt,xyz)
      !----------------------------------------------------
      ! @ public
      !
      !----------------------------------------------------
      real(8), intent(out) :: xyz(3)
      real(8), intent(in) :: clon  ! Degree
      real(8), intent(in) :: clat  ! Degree
      real(8), intent(in) :: alt   ! km
    end subroutine gwcs_lonlat2geo
  end interface
  !
  interface
    subroutine gwcs_xyz2lla(xyz, plh, a, fl)
      !------------------------------------------------------------
      ! @ public
      !
      ! Convert XYZ to Longitude, Latitude, Altitude
      ! for a given ellipsoid specified by A and FL
      !
      ! Longitude is East of Greenwich
      !
      ! References:
      ! Borkowski, K. M. (1989).  "Accurate algorithms to transform geocentric
      ! to geodetic coordinates", *Bulletin Geodesique*, v. 63, pp. 50-56.
      ! Borkowski, K. M. (1987).  "Transformation of geocentric to geodetic
      ! coordinates without approximations", *Astrophysics and Space Science*,
      ! v. 139, n. 1, pp. 1-4.  Correction in (1988), v. 146, n. 1, p. 201.
      !
      ! An equivalent formulation is recommended in the IERS Standards
      ! (1995), draft.
      !-------------------------------------------------------------------------
      real(8), intent(in) :: xyz(3)  ! XYZ coordinates (in units of distance)
      real(8), intent(out) :: plh(3) ! Longitude, Latitude (in radians) and height (in unit of distance)
      real(8), intent(in) :: a       ! semi-major axis of ellipsoid (in units are of distance)
      real(8), intent(in) :: fl      ! flattening of ellipsoid [unitless]
    end subroutine gwcs_xyz2lla
  end interface
  !
  interface
    subroutine gwcs_lla2xyz (plh, xyz, A, FL)
      !---------------------------------------------------------------------
      ! @ public
      ! Converts elliptic Longitude, Latitude and Height to geocentric X,Y,Z
      !
      ! references:
      ! Escobal, "Methods of Orbit Determination", 1965, Wiley & Sons, Inc.,
      ! pp. 27-29.
      !---------------------------------------------------------------------
      real(8), intent(in) :: plh(3)  ! Longitude, Latitude (in radians) and height (in unit of distance)
      real(8), intent(out) :: xyz(3) ! XYZ coordinates (in units of distance)
      real(8), intent(in) :: a       ! semi-major axis of ellipsoid (in units are of distance)
      real(8), intent(in) :: fl      ! flattening of ellipsoid [unitless]
    end subroutine gwcs_lla2xyz
  end interface
  !
  interface
    subroutine gwcs_azel2pa(lat,az,el,parang)
      !---------------------------------------------------------------------
      ! @ public
      ! Compute the parallactic angle from az/el and latitude of
      ! observation. Azimuth convention must be South at 180 degrees.
      ! If using azimuth South at 0 degrees, sinAz and cosAz sign should be
      ! swapped.
      !---------------------------------------------------------------------
      real(kind=8), intent(in)  :: lat     ! [rad]
      real(kind=8), intent(in)  :: az,el   ! [rad]
      real(kind=8), intent(out) :: parang  ! [rad]
    end subroutine gwcs_azel2pa
  end interface
  !
  interface gwcs_observatory
    subroutine gwcs_observatory_parameters(arg,lonlat,altitude,slimit,diam,error)
      use gbl_message
      !---------------------------------------------------------------------
      ! @ public-generic gwcs_observatory
      !  Return the observatory parameters given its name, raise an error
      ! if not found
      !---------------------------------------------------------------------
      character(len=*), intent(in)    :: arg        ! Telescope name
      real(kind=8),     intent(inout) :: lonlat(2)  !
      real(kind=8),     intent(inout) :: altitude   !
      real(kind=8),     intent(inout) :: slimit     !
      real(kind=4),     intent(inout) :: diam       !
      logical,          intent(inout) :: error      ! Logical error flag
    end subroutine gwcs_observatory_parameters
    subroutine gwcs_observatory_telesco(arg,telescope,error)
      use gbl_message
      use image_def
      !---------------------------------------------------------------------
      ! @ public-generic gwcs_observatory
      !  Return the observatory parameters in the 'telesco' structure given
      ! its name.
      !---------------------------------------------------------------------
      character(len=*), intent(in)    :: arg        ! Telescope name
      type(telesco),    intent(out)   :: telescope  ! Telescope structure
      logical,          intent(inout) :: error      ! Logical error flag
    end subroutine gwcs_observatory_telesco
  end interface gwcs_observatory
  !
end module gwcs_interfaces_public
