!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
! (re)allocation routines
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
subroutine reallocate_fits_logi_1d(kind,n,fitsarray,error)
  use gkernel_interfaces
  use imbfits_interfaces, except_this=>reallocate_fits_logi_1d
  use imbfits_messaging
  use imbfits_types
  !-------------------------------------------------------------------
  ! @ private
  !-------------------------------------------------------------------
  character(len=*),     intent(in)    :: kind
  integer(kind=4),      intent(in)    :: n
  type(fits_logi_1d_t), intent(inout) :: fitsarray
  logical,              intent(inout) :: error
  ! Local
  character(len=*), parameter :: rname='REALLOCATE>FITS>LOGI>1D'
  logical :: alloc
  character(len=message_length) :: mess
  integer(kind=4) :: ier
  !
  call imbfits_message(seve%t,rname,'Welcome')
  !
  if (n.lt.0) then
    write(mess,'(A,I0,3A)')  'Array size can not be negative (got ',  &
      n,' for column ''',trim(kind),''')'
    call imbfits_message(seve%e,rname,mess)
    error = .true.
    return
  endif
  !
  alloc = n.gt.0  ! 0 rows in tables is tolerated
  if (associated(fitsarray%val)) then
     if (fitsarray%n.eq.n) then
        write(mess,'(a,a,i0)')  &
          kind,' already associated at the right size: ',n
        call imbfits_message(iseve%alloc,rname,mess)
        alloc = .false.
     else
        write(mess,'(a,a,a)') 'Pointer ',kind,  &
          ' already associated but with a different size => Freeing it first'
        call imbfits_message(iseve%alloc,rname,mess)
        call free_fits_logi_1d(fitsarray,error)
        if (error)  return
     endif
  endif
  !
  if (alloc) then
     allocate(fitsarray%val(n),stat=ier)
     if (failed_allocate(rname,kind,ier,error)) then
        call free_fits_logi_1d(fitsarray,error)
        return
     endif
     write(mess,'(a,a,a,i0)') 'Allocated ',kind,' fits_logi_1d of size: ',n
     call imbfits_message(iseve%alloc,rname,mess)
  endif
  !
  ! Allocation success => Initialize
  fitsarray%key = kind
  fitsarray%n = n
  !
end subroutine reallocate_fits_logi_1d
!
subroutine reallocate_fits_inte_1d(kind,n,fitsarray,error)
  use gkernel_interfaces
  use imbfits_interfaces, except_this=>reallocate_fits_inte_1d
  use imbfits_messaging
  use imbfits_types
  !-------------------------------------------------------------------
  ! @ private
  !-------------------------------------------------------------------
  character(len=*),     intent(in)    :: kind
  integer(kind=4),      intent(in)    :: n
  type(fits_inte_1d_t), intent(inout) :: fitsarray
  logical,              intent(inout) :: error
  ! Local
  character(len=*), parameter :: rname='REALLOCATE>FITS>INTE>1D'
  logical :: alloc
  character(len=message_length) :: mess
  integer(kind=4) :: ier
  !
  call imbfits_message(seve%t,rname,'Welcome')
  !
  if (n.lt.0) then
    write(mess,'(A,I0,3A)')  'Array size can not be negative (got ',  &
      n,' for column ''',trim(kind),''')'
    call imbfits_message(seve%e,rname,mess)
    error = .true.
    return
  endif
  !
  alloc = n.gt.0  ! 0 rows in tables is tolerated
  if (associated(fitsarray%val)) then
     if (fitsarray%n.eq.n) then
        write(mess,'(a,a,i0)')  &
          kind,' already associated at the right size: ',n
        call imbfits_message(iseve%alloc,rname,mess)
        alloc = .false.
     else
        write(mess,'(a,a,a)') 'Pointer ',kind,  &
          ' already associated but with a different size => Freeing it first'
        call imbfits_message(iseve%alloc,rname,mess)
        call free_fits_inte_1d(fitsarray,error)
        if (error)  return
     endif
  endif
  !
  if (alloc) then
     allocate(fitsarray%val(n),stat=ier)
     if (failed_allocate(rname,kind,ier,error)) then
        call free_fits_inte_1d(fitsarray,error)
        return
     endif
     write(mess,'(a,a,a,i0)') 'Allocated ',kind,' fits_inte_1d of size: ',n
     call imbfits_message(iseve%alloc,rname,mess)
  endif
  !
  ! Allocation success => Initialize
  fitsarray%key = kind
  fitsarray%n = n
  !
end subroutine reallocate_fits_inte_1d
!
subroutine reallocate_fits_real_1d(kind,n,fitsarray,error)
  use gkernel_interfaces
  use imbfits_interfaces, except_this=>reallocate_fits_real_1d
  use imbfits_messaging
  use imbfits_types
  !-------------------------------------------------------------------
  ! @ private
  !-------------------------------------------------------------------
  character(len=*),     intent(in)    :: kind
  integer(kind=4),      intent(in)    :: n
  type(fits_real_1d_t), intent(inout) :: fitsarray
  logical,              intent(inout) :: error
  ! Local
  character(len=*), parameter :: rname='REALLOCATE>FITS>REAL>1D'
  logical :: alloc
  character(len=message_length) :: mess
  integer(kind=4) :: ier
  !
  call imbfits_message(seve%t,rname,'Welcome')
  !
  if (n.lt.0) then
    write(mess,'(A,I0,3A)')  'Array size can not be negative (got ',  &
      n,' for column ''',trim(kind),''')'
    call imbfits_message(seve%e,rname,mess)
    error = .true.
    return
  endif
  !
  alloc = n.gt.0  ! 0 rows in tables is tolerated
  if (associated(fitsarray%val)) then
     if (fitsarray%n.eq.n) then
        write(mess,'(a,a,i0)')  &
          kind,' already associated at the right size: ',n
        call imbfits_message(iseve%alloc,rname,mess)
        alloc = .false.
     else
        write(mess,'(a,a,a)') 'Pointer ',kind,  &
          ' already associated but with a different size => Freeing it first'
        call imbfits_message(iseve%alloc,rname,mess)
        call free_fits_real_1d(fitsarray,error)
        if (error)  return
     endif
  endif
  !
  if (alloc) then
     allocate(fitsarray%val(n),stat=ier)
     if (failed_allocate(rname,kind,ier,error)) then
        call free_fits_real_1d(fitsarray,error)
        return
     endif
     write(mess,'(a,a,a,i0)') 'Allocated ',kind,' fits_real_1d of size: ',n
     call imbfits_message(iseve%alloc,rname,mess)
  endif
  !
  ! Allocation success => Initialize
  fitsarray%key = kind
  fitsarray%n = n
  !
end subroutine reallocate_fits_real_1d
!
subroutine reallocate_fits_dble_1d(kind,n,fitsarray,error)
  use gkernel_interfaces
  use imbfits_interfaces, except_this=>reallocate_fits_dble_1d
  use imbfits_messaging
  use imbfits_types
  !-------------------------------------------------------------------
  ! @ private
  !-------------------------------------------------------------------
  character(len=*),     intent(in)    :: kind
  integer(kind=4),      intent(in)    :: n
  type(fits_dble_1d_t), intent(inout) :: fitsarray
  logical,              intent(inout) :: error
  ! Local
  character(len=*), parameter :: rname='REALLOCATE>FITS>DBLE>1D'
  logical :: alloc
  character(len=message_length) :: mess
  integer(kind=4) :: ier
  !
  call imbfits_message(seve%t,rname,'Welcome')
  !
  if (n.lt.0) then
    write(mess,'(A,I0,3A)')  'Array size can not be negative (got ',  &
      n,' for column ''',trim(kind),''')'
    call imbfits_message(seve%e,rname,mess)
    error = .true.
    return
  endif
  !
  alloc = n.gt.0  ! 0 rows in tables is tolerated
  if (associated(fitsarray%val)) then
     if (fitsarray%n.eq.n) then
        write(mess,'(a,a,i0)')  &
          kind,' already associated at the right size: ',n
        call imbfits_message(iseve%alloc,rname,mess)
        alloc = .false.
     else
        write(mess,'(a,a,a)') 'Pointer ',kind,  &
          ' already associated but with a different size => Freeing it first'
        call imbfits_message(iseve%alloc,rname,mess)
        call free_fits_dble_1d(fitsarray,error)
        if (error)  return
     endif
  endif
  !
  if (alloc) then
     allocate(fitsarray%val(n),stat=ier)
     if (failed_allocate(rname,kind,ier,error)) then
        call free_fits_dble_1d(fitsarray,error)
        return
     endif
     write(mess,'(a,a,a,i0)') 'Allocated ',kind,' fits_dble_1d of size: ',n
     call imbfits_message(iseve%alloc,rname,mess)
  endif
  !
  ! Allocation success => Initialize
  fitsarray%key = kind
  fitsarray%n = n
  !
end subroutine reallocate_fits_dble_1d
!
subroutine reallocate_fits_char_1d(kind,n,fitsarray,error)
  use gkernel_interfaces
  use imbfits_interfaces, except_this=>reallocate_fits_char_1d
  use imbfits_messaging
  use imbfits_types
  !-------------------------------------------------------------------
  ! @ private
  !-------------------------------------------------------------------
  character(len=*),     intent(in)    :: kind
  integer(kind=4),      intent(in)    :: n
  type(fits_char_1d_t), intent(inout) :: fitsarray
  logical,              intent(inout) :: error
  ! Local
  character(len=*), parameter :: rname='REALLOCATE>FITS>CHAR>1D'
  logical :: alloc
  character(len=message_length) :: mess
  integer(kind=4) :: ier
  !
  call imbfits_message(seve%t,rname,'Welcome')
  !
  if (n.lt.0) then
    write(mess,'(A,I0,3A)')  'Array size can not be negative (got ',  &
      n,' for column ''',trim(kind),''')'
    call imbfits_message(seve%e,rname,mess)
    error = .true.
    return
  endif
  !
  alloc = n.gt.0  ! 0 rows in tables is tolerated
  if (associated(fitsarray%val)) then
     if (fitsarray%n.eq.n) then
        write(mess,'(a,a,i0)')  &
          kind,' already associated at the right size: ',n
        call imbfits_message(iseve%alloc,rname,mess)
        alloc = .false.
     else
        write(mess,'(a,a,a)') 'Pointer ',kind,  &
          ' already associated but with a different size => Freeing it first'
        call imbfits_message(iseve%alloc,rname,mess)
        call free_fits_char_1d(fitsarray,error)
        if (error)  return
     endif
  endif
  !
  if (alloc) then
     allocate(fitsarray%val(n),stat=ier)
     if (failed_allocate(rname,kind,ier,error)) then
        call free_fits_char_1d(fitsarray,error)
        return
     endif
     write(mess,'(a,a,a,i0)') 'Allocated ',kind,' fits_char_1d of size: ',n
     call imbfits_message(iseve%alloc,rname,mess)
  endif
  !
  ! Allocation success => Initialize
  fitsarray%key = kind
  fitsarray%n = n
  !
end subroutine reallocate_fits_char_1d
!
subroutine reallocate_imbfits_data_val(nchan,npix,ntime,imbdata,error)
  use gkernel_interfaces
  use imbfits_interfaces, except_this=>reallocate_imbfits_data_val
  use imbfits_messaging
  use imbfits_types
  !-------------------------------------------------------------------
  ! @ private
  ! (re)allocation routine specific for the DATA column
  !-------------------------------------------------------------------
  integer(kind=4),      intent(in)    :: nchan
  integer(kind=4),      intent(in)    :: npix
  integer(kind=4),      intent(in)    :: ntime
  type(imbfits_data_t), intent(inout) :: imbdata
  logical,              intent(inout) :: error
  ! Local
  character(len=*), parameter :: rname='REALLOCATE>IMBFITS>DATA>VAL'
  logical :: alloc
  character(len=message_length) :: mess
  integer(kind=4) :: ier
  !
  call imbfits_message(seve%t,rname,'Welcome')
  !
  if (nchan.le.0 .or. npix.le.0 .or. ntime.le.0) then
    write(mess,'(A,3(I0,A))')  &
      'Array size can not be zero nor negative (got nchan x npix x ntime = ',  &
      nchan,'x',npix,'x',ntime,')'
    call imbfits_message(seve%e,rname,mess)
    error = .true.
    return
  endif
  !
  alloc = .true.
  if (associated(imbdata%val)) then
     if (imbdata%nchan.eq.nchan .and.  &  ! Strict equality
         imbdata%npix .eq.npix  .and.  &  ! Strict equality
         imbdata%ntime.ge.ntime) then     ! Greater or equal
        write(mess,'(a,i0,a,i0,a,i0)')  &
          'DATAVAL already associated at an appropriate size: ',  &
          imbdata%nchan,' x ',imbdata%npix,' x ',imbdata%ntime
        call imbfits_message(iseve%alloc,rname,mess)
        alloc = .false.
     else
        write(mess,'(a,a,a)')  &
          'DATAVAL pointer already associated but with a different size => Freeing it first'
        call imbfits_message(iseve%alloc,rname,mess)
        call free_imbfits_data_val(imbdata,error)
        if (error)  return
     endif
  endif
  !
  if (alloc) then
     ! Nchan contiguous in memory, then Npix, then Ntime. Assume the weight
     ! array is allocated consistently.
     allocate(imbdata%val(nchan,npix,ntime),imbdata%wei(nchan),stat=ier)
     if (failed_allocate(rname,'DATA',ier,error)) then
        call free_imbfits_data_val(imbdata,error)
        return
     endif
     write(mess,'(a,i0,a,i0,a,i0)')  &
       'Allocated DATAVAL array of size: ',nchan,' x ',npix,' x ',ntime
     call imbfits_message(iseve%alloc,rname,mess)
  endif
  !
  ! Allocation success => Initialize
  imbdata%nchan = nchan
  imbdata%npix  = npix
  imbdata%ntime = ntime
  !
end subroutine reallocate_imbfits_data_val
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
! Deallocation routines
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
subroutine free_fits_logi_1d(fitsarray,error)
  use gbl_message
  use imbfits_interfaces, except_this => free_fits_logi_1d
  use imbfits_types
  !-------------------------------------------------------------------
  ! @ private
  !-------------------------------------------------------------------
  type(fits_logi_1d_t), intent(inout) :: fitsarray
  logical,              intent(inout) :: error
  !
  character(len=*), parameter :: rname='FREE>FITS>LOGI>1D'
  !
  call imbfits_message(seve%t,rname,'Welcome')
  !
  fitsarray%n = 0
  if (associated(fitsarray%val))  deallocate(fitsarray%val)
  ! Nullification is implicit with deallocate
  !
end subroutine free_fits_logi_1d
!
subroutine free_fits_inte_1d(fitsarray,error)
  use gbl_message
  use imbfits_interfaces, except_this => free_fits_inte_1d
  use imbfits_types
  !-------------------------------------------------------------------
  ! @ private
  !-------------------------------------------------------------------
  type(fits_inte_1d_t), intent(inout) :: fitsarray
  logical,              intent(inout) :: error
  !
  character(len=*), parameter :: rname='FREE>FITS>INTE>1D'
  !
  call imbfits_message(seve%t,rname,'Welcome')
  !
  fitsarray%n = 0
  if (associated(fitsarray%val))  deallocate(fitsarray%val)
  ! Nullification is implicit with deallocate
  !
end subroutine free_fits_inte_1d
!
subroutine free_fits_real_1d(fitsarray,error)
  use gbl_message
  use imbfits_interfaces, except_this => free_fits_real_1d
  use imbfits_types
  !-------------------------------------------------------------------
  ! @ private
  !-------------------------------------------------------------------
  type(fits_real_1d_t), intent(inout) :: fitsarray
  logical,              intent(inout) :: error
  !
  character(len=*), parameter :: rname='FREE>FITS>REAL>1D'
  !
  call imbfits_message(seve%t,rname,'Welcome')
  !
  fitsarray%n = 0
  if (associated(fitsarray%val))  deallocate(fitsarray%val)
  ! Nullification is implicit with deallocate
  !
end subroutine free_fits_real_1d
!
subroutine free_fits_dble_1d(fitsarray,error)
  use gbl_message
  use imbfits_interfaces, except_this => free_fits_dble_1d
  use imbfits_types
  !-------------------------------------------------------------------
  ! @ private
  !-------------------------------------------------------------------
  type(fits_dble_1d_t), intent(inout) :: fitsarray
  logical,              intent(inout) :: error
  !
  character(len=*), parameter :: rname='FREE>FITS>DBLE>1D'
  !
  call imbfits_message(seve%t,rname,'Welcome')
  !
  fitsarray%n = 0
  if (associated(fitsarray%val))  deallocate(fitsarray%val)
  ! Nullification is implicit with deallocate
  !
end subroutine free_fits_dble_1d
!
subroutine free_fits_char_1d(fitsarray,error)
  use gbl_message
  use imbfits_interfaces, except_this => free_fits_char_1d
  use imbfits_types
  !-------------------------------------------------------------------
  ! @ private
  !-------------------------------------------------------------------
  type(fits_char_1d_t), intent(inout) :: fitsarray
  logical,              intent(inout) :: error
  !
  character(len=*), parameter :: rname='FREE>FITS>CHAR>1D'
  !
  call imbfits_message(seve%t,rname,'Welcome')
  !
  fitsarray%n = 0
  if (associated(fitsarray%val))  deallocate(fitsarray%val)
  ! Nullification is implicit with deallocate
  !
end subroutine free_fits_char_1d
!
subroutine free_imbfits_data_val(imbdata,error)
  use gbl_message
  use imbfits_interfaces, except_this => free_imbfits_data_val
  use imbfits_types
  !-------------------------------------------------------------------
  ! @ private
  ! Free the 'val' array of the input imbfits_data_t instance.
  !-------------------------------------------------------------------
  type(imbfits_data_t), intent(inout) :: imbdata
  logical,              intent(inout) :: error
  !
  character(len=*), parameter :: rname='FREE>IMBFITS>DATA>VAL'
  !
  call imbfits_message(seve%t,rname,'Welcome')
  !
  imbdata%nchan = 0
  imbdata%npix  = 0
  imbdata%ntime = 0
  !
  if (associated(imbdata%val))  deallocate(imbdata%val)
  if (associated(imbdata%wei))  deallocate(imbdata%wei)
  ! Nullification is implicit with deallocate
  !
end subroutine free_imbfits_data_val
