module cfitsio_bintable
  use cfitsio_interfaces
  use cfitsio_messaging
  use cfitsio_status
  !---------------------------------------------------------------------
  ! Routines to provide enhanced API for CFITSIO binary tables
  !---------------------------------------------------------------------
  !
  public :: cfitsio_bintable_read_column_r4
  private
  !
contains
  !
  subroutine cfitsio_bintable_read_column_r4(caller,iunit,colnum,frow,felem,nelem,array,error)
    use, intrinsic :: iso_c_binding, only : c_float,c_int,c_long_long,c_ptr
    !-------------------------------------------------------------------
    ! Custom overlay to CFITSIO routine fits_read_col_flt (ffgcve)
    ! with I*8 arguments.
    !-------------------------------------------------------------------
    character(len=*), intent(in)    :: caller    ! Name of calling procedure
    integer(kind=4),  intent(in)    :: iunit     ! Fortran i/o unit number
    integer(kind=4),  intent(in)    :: colnum    ! Number of the column to read
    integer(kind=8),  intent(in)    :: frow      ! First row to read
    integer(kind=8),  intent(in)    :: felem     ! First element within the row to read
    integer(kind=8),  intent(in)    :: nelem     ! Number of elements to read
    real(kind=4),     intent(out)   :: array(*)  ! Returned array of data values that was read from FITS file
    logical,          intent(inout) :: error     ! Logical error flag
    ! Local
    type(c_ptr) :: fptr
    integer(c_int) :: colnum_c,anynul_c,status_c
    integer(c_long_long) :: felem_c,frow_c,nelem_c
    real(c_float) :: nulval_c
    character(len=message_length) :: mess
    !
    call cfitsio_file_cptr(iunit,fptr,error)
    if (error)  return
    !
    colnum_c = int(colnum,kind=c_int)
    frow_c = int(frow,kind=c_long_long)
    felem_c = int(felem,kind=c_long_long)
    nelem_c = int(nelem,kind=c_long_long)
    nulval_c = -1.0_c_float
    anynul_c = 0_c_int
    status_c = int(0_c_int)
    !
    status_c = fits_read_col_flt(fptr,colnum_c,frow_c,felem_c,nelem_c,nulval_c,  &
                                 array,anynul_c,status_c)
    !
    if (anynul_c.ne.0_c_int .or. status_c.gt.0) then
      call cfitsio_message(seve%e,caller,'Error')
      write(mess,'(A,I0,A,I0)')  &
        'Error while reading column #',colnum,', row #',frow
      call cfitsio_message(seve%e,caller,mess)
      if (anynul_c.ne.0_c_int) then
        call cfitsio_message(seve%e,caller,'Some null values found')
      else
        call cfitsio_errormsg(status_c)
        call ftrprt('STDOUT',status_c)  ! Much verbose for debugging
      endif
      error = .true.
      return
    endif
  end subroutine cfitsio_bintable_read_column_r4
end module cfitsio_bintable
