module clic_file
  use classic_params
  use classic_types   
  !
  ! Classic objects
  type(classic_file_t), save :: i, o, d              ! File objects
  type(classic_recordbuf_t)  :: ibuff, obuff, dbuff  ! Observation buffers
  type(classic_recordbuf_t)  :: ibufi, obufi, dbufi  ! Index buffers
  type(classic_entrydesc_t)  :: e, de                ! Entry descriptor
  !
  ! File variables
  integer(kind=4) :: number_trys   ! Number of try before time out in NEW_DATA
  real(kind=4)    :: interval      ! Interval between tries in NEW_DATA
  logical         :: modify        ! Current observation opened for modify
  integer(kind=8) :: old_ixnext    ! Last known data in input file
  !
  ! Observation version
  integer(kind=4),save :: version_current = 6 ! Current observation number
  integer(kind=4) :: version_last = 6 ! Latest observation version number
  integer(kind=4) :: max_rf_file = 20 ! Max number of RF solutions in file
  integer(kind=4) :: scan_offset = 1000000 ! Offset in scan number for RF
end module clic_file
!
module clic_title
  !
  ! Version 1 of observation title
  integer(kind=4), parameter :: vind_v1 =  1 ! Title version
  integer(kind=4), parameter :: lind_v1 = 32 ! Title length     [4-bytes]
  type title_v1_t
    sequence
    integer(kind=4)  :: bloc       !  1   : observation address [records]
    integer(kind=4)  :: num        !  2   : observation number
    integer(kind=4)  :: ver        !  3   : observation version  
    integer(kind=4)  :: sourc(3)   !  4- 6: source name
    integer(kind=4)  :: line(3)    !  7- 9: line name
    integer(kind=4)  :: teles(3)   ! 10-12: telescope name
    integer(kind=4)  :: dobs       ! 13   : observation date    [class_date]
    integer(kind=4)  :: dred       ! 14   : reduction date      [class_date]
    real(kind=4)     :: off1       ! 15   : lambda offset       [radian]
    real(kind=4)     :: off2       ! 16   : beta offset         [radian]
    integer(kind=4)  :: typec      ! 17   : coordinates types
    integer(kind=4)  :: kind       ! 18   : data kind
    integer(kind=4)  :: qual       ! 19   : data quality
    integer(kind=4)  :: scan       ! 20   : scan number
    integer(kind=4)  :: proc       ! 21   : procedure type
    integer(kind=4)  :: itype      ! 22   : observation type
    real(kind=4)     :: houra      ! 23   : hour angle          [radian]
    integer(kind=4)  :: project    ! 24   : project name
    integer(kind=4)  :: pad1       ! 25   : unused word
    integer(kind=4)  :: bpc        ! 26   : baseline bandpass cal status
    integer(kind=4)  :: ic         ! 27   : instrumental cal status
    integer(kind=4)  :: recei      ! 28   : receiver number
    real(kind=4)     :: ut         ! 29   : UT                  [s] 
    integer(kind=4)  :: pad2(3)    ! 30-32: padding to 32 4-bytes word
  end type title_v1_t
  !
  ! Version 2 of observation title
  integer(kind=4), parameter :: vind_v2 =  2 ! Title version
  integer(kind=4), parameter :: lind_v2 = 32 ! Title length     [4-bytes]
  type title_v2_t
    sequence
    integer(kind=8)  :: bloc       !  1- 2: observation address [records]
    integer(kind=4)  :: word       !  3   : address offset      [4-bytes]
    integer(kind=4)  :: ver        !  4   : observation version  
    integer(kind=8)  :: num        !  5- 6: observation number
    integer(kind=4)  :: sourc(3)   !  7- 9: source name
    integer(kind=4)  :: line(3)    ! 10-12: line name
    integer(kind=4)  :: teles(3)   ! 13-15: telescope name
    integer(kind=4)  :: dobs       ! 16   : observation date    [class_date]
    integer(kind=4)  :: dred       ! 17   : reduction date      [class_date]
    real(kind=4)     :: off1       ! 18   : lambda offset       [radian]
    real(kind=4)     :: off2       ! 19   : beta offset         [radian]
    integer(kind=4)  :: typec      ! 20   : coordinates types
    integer(kind=4)  :: kind       ! 21   : data kind
    integer(kind=4)  :: qual       ! 22   : data quality
    integer(kind=4)  :: scan       ! 23   : scan number
    integer(kind=4)  :: proc       ! 24   : procedure type
    integer(kind=4)  :: itype      ! 25   : observation type
    real(kind=4)     :: houra      ! 26   : hour angle          [radian]
    integer(kind=4)  :: project(2) ! 27   : project name
    integer(kind=4)  :: bpc        ! 29   : baseline bandpass cal status
    integer(kind=4)  :: ic         ! 30   : instrumental cal status
    integer(kind=4)  :: recei      ! 31   : receiver number
    real(kind=4)     :: ut         ! 32   : UT                  [s] 
  end type title_v2_t
  !
  ! Index in memory is v2
  type(title_v2_t):: title         ! Observation title format v2 in memory
  integer(kind=4) :: tbuf(lind_v2) ! Buffer in which CLASSIC reads titles.
  ! 
  ! '    ' chain
  integer(kind=4) :: fourblanks    ! To verify project(2) if writing v1
end module clic_title
!
module clic_index
  use classic_params
  !
  ! Index sizes
  integer,parameter          :: m_ix = 1000000
  integer,parameter          :: m_ox = 1000000
  integer,parameter          :: m_dx = 1000000
  integer,parameter          :: m_cx = 1000000
  !
  ! Input observation title index 
  integer(kind=entry_length) :: ix_num  (m_ix) ! Observation number
  integer(kind=8)            :: ix_bloc (m_ix) ! Record where entry starts
  integer(kind=4)            :: ix_word (m_ix) ! First word in record
  integer(kind=4)            :: ix_ver  (m_ix) ! Observation version
  integer(kind=4)            :: ix_kind (m_ix) ! Data kind
  integer(kind=4)            :: ix_qual (m_ix) ! Data quality
  integer(kind=4)            :: ix_itype(m_ix) ! Object type
  integer(kind=4)            :: ix_scan (m_ix) ! Scan number
  integer(kind=4)            :: ix_rece (m_ix) ! Receiver number
  integer(kind=4)            :: ix_proc (m_ix) ! Procedure type
  integer(kind=4), allocatable   :: ix_aflag(:,:) ! Memory flags
  integer(kind=4), allocatable   :: ix_bflag(:,:) ! Memory flags
  !
  ! Output observation title index
  integer(kind=entry_length) :: ox_num  (m_ox) ! Observation number
  integer(kind=8)            :: ox_bloc (m_ox) ! Record where entry starts
  integer(kind=4)            :: ox_word (m_ox) ! First word in record
  integer(kind=4)            :: ox_ver  (m_ox) ! Observation version
  integer(kind=4)            :: ox_scan (m_ox) ! Scan number
  integer(kind=4)            :: ox_rece (m_ox) ! Receiver number
  real(kind=4)               :: ox_ut   (m_ox) ! UT
  !
  ! Data observation title index
  integer(kind=8)            :: dx_bloc (m_dx) ! Record where entry starts
  integer(kind=4)            :: dx_word (m_dx) ! First word in record
  integer(kind=4)            :: dx_scan (m_dx) ! Scan number 
  integer(kind=4)            :: dx_dobs (m_dx) ! Observation date
  integer(kind=4)            :: dx_rece (m_dx) ! Receiver number
  real(kind=4)               :: dx_ut   (m_dx) ! UT
  !
  ! Current observation title index
  integer(kind=entry_length) :: cx_num  (m_cx) ! Observation number
  integer(kind=entry_length) :: cx_ind  (m_cx) ! Input index entry number
  integer(kind=8)            :: cx_bloc (m_cx) ! Record where entry starts
  integer(kind=4)            :: cx_word (m_cx) ! First word in record
  integer(kind=4)            :: cx_ver  (m_cx) ! Observation version
  !
  !
  integer(kind=entry_length) :: cxnext         ! Next free current index entry
  integer(kind=entry_length) :: knext          ! Current obs. for GET
  integer(kind=entry_length) :: nindex         ! Current index length
end module clic_index
!
module clic_find
  !
  ! Search flags
  logical                    :: last       ! Search observation last version
  logical                    :: fnum       ! Search by observation number 
  logical                    :: fver       ! Search by observation version
  logical                    :: fsourc     ! Search by source name
  logical                    :: fline      ! Search by line name
  logical                    :: fteles     ! Search by telescope name
  logical                    :: fdobs      ! Search by observation date
  logical                    :: fdred      ! Search by reduction date
  logical                    :: foff1      ! Search by lambda offset
  logical                    :: foff2      ! Search by beta offset
  logical                    :: fscan      ! Search by scan number
  logical                    :: fproc      ! Search by procedure type
  logical                    :: fexcl      ! Exclude procedure type
  logical                    :: fitype     ! Search by object type (O,P)
  logical                    :: fhoura     ! Search by hour angle
  logical                    :: fut        ! Search by UT time
  logical                    :: fproject   ! Search by project name
  logical                    :: fbpc       ! Search by passband cal status
  logical                    :: fic        ! Search by time cal status
  logical                    :: fpol       ! Search by polar type
  logical                    :: fmod       ! Search by correlator mode
  logical                    :: fload      ! Search by load type
  logical                    :: fskip      ! Skip the autocorrelations
  logical                    :: fcorr      ! Search by correlator
  !
  ! Procedures
  integer,parameter          :: m_proc=10      ! Max for procedures
  integer,parameter          :: m_excl=10      ! Idem for exclusions
  ! For command SET PROCEDURE / SET EXCLUDE
  integer*4                  :: nproc          ! Number of procedure
  integer*4                  :: ssproc(m_proc) ! Procedure id 
  integer*4                  :: nexcl          ! Number of procedure
  integer*4                  :: ssexcl(m_excl) ! Procedure id 
  ! For command FIND /PROCEDURE /EXCLUDE
  integer*4                  :: xnproc         ! Number of procedure
  integer*4                  :: xsproc(m_proc) ! Procedure id 
  integer*4                  :: xnexcl         ! Number of procedure
  integer*4                  :: xsexcl(m_excl) ! Procedure id 
  !
  ! Sources
  integer,parameter          :: m_sour=20      ! Max for procedures
  ! For command SET SOURCE
  integer*4                  :: nsour          ! Number of sources 
  integer*4                  :: sisour(m_sour) ! Source name length 
  character*12               :: sssour(m_sour) ! Source name 
  ! For command FIND /SOURCE
  integer*4                  :: xnsour         ! Number of sources 
  integer*4                  :: xisour(m_sour) ! Source name length 
  character*12               :: xssour(m_sour) ! Source name 
  !
  ! Observation date
  integer*4                  :: xdobs          ! Starting obs. date
  integer*4                  :: ydobs          ! Ending obs. date
  !
  ! Reduction date        
  integer*4                  :: xdred          ! Starting red. date
  integer*4                  :: ydred          ! Ending red. date
  !
  ! Observation number
  integer*4                  :: xnum           ! Starting obs. number
  integer*4                  :: ynum           ! Ending obs. number
  !
  ! Observation version (not implemented)
  integer*4                  :: xver           ! Starting obs. version
  integer*4                  :: yver           ! Ending obs. version
  !
  ! Hour angle
  real*4                     :: xhoura         ! Starting hour angle
  real*4                     :: yhoura         ! Ending hour angle
  !
  ! UT
  real*4                     :: xut            ! Starting UT
  real*4                     :: yut            ! Ending UT
  !
  ! Observation kind
  integer*4                  :: xkind          ! Starting kind
  integer*4                  :: ykind          ! Ending kind
  !
  ! Data quality
  integer*4                  :: xqual          ! Maximum data quality
  !
  ! Scan number
  integer,parameter          :: m_scan = 100    ! Maximum number of scan ranges
  ! For FIND /SCAN command
  integer*4                  :: xnscan          ! Actual number of scan ranges
  integer*4                  :: xscan(m_scan)   ! Starting scan number
  integer*4                  :: yscan(m_scan)   ! Ending scan number
  ! For SET SCAN command
  integer*4                  :: snscan          ! Actual number of scan ranges
  integer*4                  :: sscan1(m_scan)  ! Starting scan number
  integer*4                  :: sscan2(m_scan)  ! Ending scan number
  !
  ! Type
  integer*4                  :: xitype          ! Researched type (O/P/R)
  !
  ! Bandpass calibration status
  integer*4                  :: xbpc            ! BP calibration status
  !
  ! Instrumental calibration status
  integer*4                  :: xic             ! Instr. cal. status
  !
  ! Receiver band number
  integer*4                  :: xrecei          ! Receiver band number
  !
  ! Polarisation
  integer,parameter          :: xmpol = 17      ! Maximum number of pol states
  ! For FIND /POL command
  integer*4                  :: xnpol           ! Actual number of pol states
  integer*4                  :: xpol(xmpol)     ! Polarisation keyword index
  ! For SET FINDPOL command
  integer*4                  :: snpol           ! Actual number of pol states
  integer*4                  :: spol(xmpol)     ! Polarisation keyword index
  !
  ! Correlator mode (auto/cross)
  integer*4                  :: xmod            ! Correlator mode
  !
  ! Load type (HOT/COLD/SKY)
  integer*4                  :: xload           ! Load type
  !
  ! Position offsets
  real*4                     :: xoff1           ! starting lambda ofset
  real*4                     :: yoff1           ! ending lambda ofset
  real*4                     :: xoff2           ! starting beta ofset
  real*4                     :: yoff2           ! ending lambda ofset
  ! 
  ! Line name
  integer*4                  :: iline           ! Line name length
  character*12               :: xcline          ! Line name
  ! 
  ! Telescope name
  integer*4                  :: iteles          ! Telescope name length
  character*12               :: xctele          ! Telescope name
  ! 
  ! Project name
  integer*4                  :: iproject        ! Project name length
  character*8                :: xcproject       ! Project name
  !
  ! for SET SKIP ON|OFF
  integer*4                  :: iskip           ! Skip auto in corr
  !
  ! Correlator
  integer*4                  :: xcorr           ! Correlator number
end module clic_find

module clic_virtual
  use gildas_def
  use clic_index
  ! Headers
  logical,allocatable :: got_header(:)                        ! the header has been read
  integer(kind=address_length),allocatable :: v_header(:)     ! address of data header
  integer(kind=data_length),allocatable :: v_header_length(:) ! length of data header
  ! data
  logical,allocatable :: got_data(:)                          ! the data has been read
  integer(kind=address_length),allocatable :: v_data(:)       ! address of the data section
  integer(kind=data_length),allocatable ::   v_data_length(:) ! length of data section
  ! memory regions
  integer*4 :: m_region                 ! max number of regions
  parameter (m_region = 8)
  integer*4 :: n_regions =0             ! number of regions
  integer*4 :: current_region           ! current region
  integer(kind=address_length) :: region(m_region)  ! region addresses
  integer(kind=address_length) :: region_length(m_region)  ! region lengths
  integer(kind=address_length) :: next_offset    ! next offset in current region
end module clic_virtual
