module astro_pfx_types
  !
  public
  private :: pfx_reallocate,pfx_free
  !
  integer(kind=4), parameter :: m_backmodes=10  !max number of units for a given backend
  integer(kind=4), parameter :: m_ch=128        !max number of chunks (fix or flexible)
  integer(kind=4), parameter :: m_chtypes=10    !max number of chunk types
  integer(kind=4), parameter :: m_typecol=3
  !
  type pfx_type_t
    character(len=50)   :: typename
    character(len=16)   :: itypecol(m_typecol)      ! color name (1=filled, 2 =hatched, 3 =border)
    logical(kind=4)     :: move_chunk   !
    integer(kind=4)     :: n_chunks     ! number of existing chunks of this type / unit
    integer(kind=4)     :: use_chunks     ! number of chunks that can be used/ unit
    integer(kind=4)     :: usage ! number of chunks configured
    real(kind=8)        :: df_chunks    ! resolution of chunks
    real(kind=8)        :: width_chunk  ! spacing of the chunks
    real(kind=8)        :: if2ch0      ! first position in grid of chunks
    integer(kind=4)     :: chunks(m_ch) !chunk usage (=0 => unused, >0 => used)
  end type pfx_type_t
  !
  type pfx_mode_t
    !describe a polyfix mode
    character(len=50)   :: backname             ! backend name
    character(len=50)   :: modename             ! mode name
    integer(kind=4)     :: n_types          ! number of type of chunks (e.g. hi and low res = 2)
    type(pfx_type_t)    :: chtype(m_chtypes)
  end type pfx_mode_t
  !
  type pfx_unit_t
    integer(kind=4)     :: iband    ! receiver processed by unit
    integer(kind=4)     :: sb_code   ! sideband processed by unit
    integer(kind=4)     :: bb_code   ! baseband processed by unit
    integer(kind=4)     :: pol_code  ! polar processed by unit
    character(len=5)    :: label     !
    integer(kind=4)     :: n_modes   ! number of existing modes
    integer(kind=4)     :: imode      ! used mode
    type(pfx_mode_t)    :: mode(m_backmodes)
  end type pfx_unit_t
  !
  type pfx_t
    character(len=50) :: name
    real(kind=8)      :: if2lim(2) ! IF2 limits of the signal processed by the unit
    integer(kind=4)   :: n_units
    type(pfx_unit_t), allocatable  :: unit(:)
  contains
    procedure, public :: free => pfx_free
    procedure, public :: reallocate => pfx_reallocate
    procedure, public :: getmode => pfx_getmode
  end type pfx_t
  !
contains
  subroutine pfx_reallocate(pfx,n_units,error)
    use gkernel_interfaces
    ! Reallocate pfx%unit if needed
    class(pfx_t), intent(inout) :: pfx
    integer(kind=4), intent(in) :: n_units
    logical, intent(inout)      :: error
    !
    character(len=*), parameter :: rname='PFX>REALLOCATE'
    integer(kind=4) :: ier
    ! First deallocate if needed
    call pfx%free(error)
    if (error) return
    ! Allocate to right size
    allocate(pfx%unit(n_units),stat=ier)
    if (failed_allocate(rname,'PFX units',ier,error))  return
    !
    pfx%n_units=n_units
    !
  end subroutine pfx_reallocate
  !
  subroutine pfx_free(pfx,error)
    ! Deallocate pfx%unit
    class(pfx_t), intent(inout) :: pfx
    logical, intent(inout)      :: error
    !
    if (allocated(pfx%unit)) deallocate(pfx%unit)
    !
  end subroutine pfx_free
  !
  subroutine pfx_getmode(pfx,amode,error)
    use gbl_message
    ! Get the mode of pfx
    class(pfx_t), intent(inout) :: pfx
    character(len=*), intent(inout) :: amode
    logical, intent(inout)      :: error
    ! Local
    character(len=*), parameter :: rname='PFX>GETMODE'
    integer(kind=4) :: iu,im,nm,modes(m_backmodes)
    !
    nm=0
    do im=1,m_backmodes
      modes(im)=0
    enddo
    do iu=1,pfx%n_units
      if (pfx%unit(iu)%imode.eq.-1) cycle
      im=pfx%unit(iu)%imode
      modes(im)=modes(im)+1
    enddo
    !
    do im=1,m_backmodes
      if (modes(im).eq.0) cycle
      nm=nm+1
    enddo
    im=0
    if (nm.le.0) then
      call astro_message(seve%e,rname,'No mode defined')
      error=.true.
      return
    else if (nm.eq.1) then
      do iu=1,pfx%n_units
        if (pfx%unit(iu)%imode.gt.0) then
          im=pfx%unit(iu)%imode
          amode=pfx%unit(iu)%mode(im)%modename
          exit
        endif
      enddo
    else
      amode='MultiMode'
    endif
    !
  end subroutine pfx_getmode
  !
end module astro_pfx_types
