!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
module file_buffers
  use gbl_message
  use gkernel_types, only: mfile_t
  !
  public :: code_save_model
  public :: code_save_uv
  public :: code_save_beam,code_save_dirty,code_save_primary,code_save_fields
  public :: code_save_mask,code_save_support
  public :: code_save_clean,code_save_resid,code_save_cct
  public :: code_save_sky
  !
  public :: readop_t
  !
  public :: file_buffer
  public :: etype,mtype,mtype_read,vtype
  public :: save_data,optimize,rw_optimize
  private
  !
  integer, parameter :: code_save_uv=1
  integer, parameter :: code_save_beam=2
  integer, parameter :: code_save_dirty=3
  integer, parameter :: code_save_clean=4
  integer, parameter :: code_save_primary=5
  integer, parameter :: code_save_resid=6
  integer, parameter :: code_save_mask=7
  integer, parameter :: code_save_support=8
  integer, parameter :: code_save_cct=9
  integer, parameter :: code_save_model=10
  integer, parameter :: code_save_sky=11
  integer, parameter :: code_save_fields=12
  !
  integer(kind=4), parameter :: mtype=13
  integer(kind=4), parameter :: mtype_read=11  ! Command READ can not read FIELDS nor COVERAGE
  character(len=12) :: vtype(1:mtype) = (/ &
       'UV          ',  &
       'BEAM        ',  &
       'DIRTY       ',  &
       'CLEAN       ',  &
       'PRIMARY     ',  &
       'RESIDUAL    ',  &
       'MASK        ',  &
       'SUPPORT     ',  &
       'CCT         ',  &
       'MODEL       ',  &
       'SKY         ',  &
       'FIELDS      ',  &
       'COVERAGE    ' /)   ! Support keyword for SHOW COVERAGE (no associated buffer)
  !
  character(len=12) :: etype(1:mtype) = (/ &
       '.uvt        ',  &
       '.beam       ',  &
       '.lmv        ',  &
       '.lmv-clean  ',  &
       '.lobe       ',  &
       '.lmv-res    ',  &
       '.msk        ',  &
       '.pol        ',  &
       '.cct        ',  &
       '.uvt        ',  &
       '.lmv-sky    ',  &
       '.fields     ',  &
       '.uvt        ' /)   ! Irrelevant for COVERAGE
  !
  character(len=12) :: ctype ! Mapped to the SIC TYPE variable ***JP: Could be confused with the convolution kernel!
  logical :: save_data(mtype)
  !
  ! Read/Write optimization
  type readop_t
     type(mfile_t) :: modif
     integer :: lastnc(2) = 0
     integer :: change = 0
  end type readop_t
  !
  type (readop_t), save :: optimize(mtype)
  integer :: rw_optimize = 0
  !
  type file_buffer_user_t
   contains
     procedure, public :: init   => file_buffer_user_init
     procedure, public :: sicdef => file_buffer_user_sicdef
     procedure, public :: save   => file_buffer_user_save
  end type file_buffer_user_t
  type(file_buffer_user_t) :: file_buffer
  !
contains
  !
  subroutine file_buffer_user_init(user,error)
    use gkernel_interfaces
    !----------------------------------------------------------------------
    !
    !----------------------------------------------------------------------
    class(file_buffer_user_t), intent(out)   :: user
    logical,                   intent(inout) :: error
    !
    integer :: ier
    !
    ctype = ' '
    rw_optimize = 0
    ier = sic_getlog('MAPPING_OPTIMIZE',rw_optimize)
  end subroutine file_buffer_user_init
  !
  subroutine file_buffer_user_sicdef(user,error)
    use gkernel_interfaces
    !----------------------------------------------------------------------
    !
    !----------------------------------------------------------------------
    class(file_buffer_user_t), intent(inout) :: user
    logical,                   intent(inout) :: error
    !
    logical :: warning
    integer(kind=index_length) :: dim(4) = 0
    !
    dim(1) = mtype
    call sic_def_charn('FILE_TYPE',vtype,1,dim,.true.,error)
    if (error) return
    call sic_def_charn('FILE_EXT',etype,1,dim,.false.,error)
    if (error) return
    !
    ! Delete the TYPE variable defined by define.greg and recreate it
    ! such as it maps 'ctype'
    call sic_delvariable('TYPE',.true.,warning)
    if (error) return
    dim(1) = 0
    call sic_def_char('TYPE',ctype,.false.,error)
    if (error) return
    !
    call sic_def_inte('MAPPING_OPTIMIZE',rw_optimize,0,0,.false.,error)
    if (error) return
  end subroutine file_buffer_user_sicdef
  !
  subroutine file_buffer_user_save(user,error)
    use gildas_def
    use gkernel_interfaces
    !----------------------------------------------------------------------
    !
    !----------------------------------------------------------------------
    class(file_buffer_user_t), intent(inout) :: user
    logical,                   intent(inout) :: error    
    !
    logical :: do_write,noprompt
    integer :: n,itype
    character(len=filename_length) :: answer
    character(len=filename_length) :: autosave='autosave'  ! Default name when saving
    character(len=commandline_length) line
    character(len=message_length) :: chain
    character(len=*), parameter :: rname='BUFFER>USER>SAVE'
    !
    answer = ' '
    error = .false.
    do_write = .false.
    call gmaster_get_exitnoprompt(noprompt)  ! Check for SIC\EXIT /NOPROMPT
    !
    if (any(save_data) .and. .not.noprompt) then
       call map_message(seve%w,rname,'There are unsaved data, should we save them?')
       do while (.true.)
          call sic_wprn('Y)es, N)o, C)ancel exit (default No): ',answer,n)
          call sic_upper(answer)
          if (answer(1:1).eq.'C') then
             error = .true.
             return
          elseif (answer(1:1).eq.'N' .or. answer(1:1).eq.' ') then
             do_write = .false.
          elseif (answer(1:1).ne.'Y') then
             call map_message(seve%e,rname,'Unrecognized answer '//answer)
             cycle
          else 
             do_write = .true.
          endif
          exit
       enddo
    endif
    !
    call sic_delvariable('DIRTY',.false.,error)
    call sic_delvariable('CLEAN',.false.,error)
    call sic_delvariable('RESIDUAL',.false.,error)
    call sic_delvariable('PRIMARY',.false.,error)
    call sic_delvariable('SKY',.false.,error)
    if (.not.do_write) return
    !
    do itype=1,mtype
       answer = ' '
       error = .false.
       do while (save_data(itype))
          write(chain,100) vtype(itype)
          call sic_wprn(trim(chain)//' ',answer,n)
          if (answer.eq.' ') answer = autosave
          line = 'CLEAN'//char(92)//'WRITE '//vtype(itype)//' "'//trim(answer)//'"'
          call exec_command(line,error)
       enddo
    enddo
    !
100 format('Enter a filename for ',a,' (default ''autosave''): ')
  end subroutine file_buffer_user_save
end module file_buffers
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
