subroutine display_buffer(comm,line,error)
  use gkernel_interfaces
  use imager_interfaces, only : display_buffer_sub, map_message
  use clean_arrays
  use clean_def
  use clean_types
  use clean_support
  use clean_default
  use uvfit_data
  use gbl_message
  !----------------------------------------------------------------------
  ! @ private
  !*
  ! IMAGER -- Dispatching routine for SHOW Name [/DIRECTORY] and VIEW commands
  ! 
  !   Dispatch the action according to the Name argument.
  !!
  !----------------------------------------------------------------------
  character(len=*), intent(in)  :: comm       !! Command (SHOW or VIEW)
  character(len=*), intent(inout)  :: line    !! Command line
  logical,          intent(out) :: error      !! Logical error flag
  !
  ! Constants
  character(len=1), parameter :: question_mark='?'
  integer, parameter :: o_view_dir=1
  integer, parameter :: o_view_nopause=2
  integer, parameter :: o_view_over=3
  integer, parameter :: o_show_cont=1
  integer, parameter :: o_show_dir=2
  integer, parameter :: o_show_side=4
  integer, parameter :: o_show_over=3
  real(8), parameter :: pi=acos(-1d0)
  integer, parameter :: mnoise=3
  character(len=6), save :: comptype(2)=['PEAK  ','WIDTH ']
  character(len=6), save :: compmode='PEAK'
  character(len=6), save :: vuvfit='RESET '
  character(len=filename_length), save :: sed_file=' '
  !
  ! Local ---
  integer :: o_dir
  type(gildas) :: head
  integer :: o_args, na
  integer(kind=size_length) :: locasize
  type(sic_descriptor_t) :: descr
  type(gildas) :: htmp
  logical :: found, done, err, exist
  logical :: do_insert, do_loop, do_color, do_nopause, cont_do
  integer ntype,nc,is,istart,ic,i, code, iover, nt, narg
  real :: colour
  character(len=filename_length) :: argu,file,chain 
  real(4), save :: sed_freq=0
  character(len=512) :: exec_chain
  character(len=80) :: mess
  character(len=40) :: argu1,argu2,vover, dtype, topic !
  character(len=12) :: dnoise 
  character(len=8) :: cshort
  ! integer :: nnoise
  ! character(len=6) :: vnoise(mnoise)=['DIRTY ', 'CLEAN ', 'SKY   ']
  !
  ! This Boolean indicates if the LUT should be switched back to Dynamic
  ! logical, save :: reset_lut=.false.
  !
  integer :: iarg, kc
  integer :: l_axis, ioff, ier, itype
  real :: soff
  !
  ! Code ----
  o_args = 0
  iarg = 1
  do_nopause = .false.
  cont_do = .false.
  !
  do_loop = .false.
  if (comm.eq.'VIEW') then
    do_loop = view_do_loop
    ! Allow VIEW /NOPAUSE Args    as well as VIEW Args /NOPAUSE
    if (sic_narg(o_view_nopause).gt.0) then
      if (sic_narg(0).ne.0) then
        call map_message(seve%e,comm,'Invalid syntax in VIEW /NOPAUSE command')
        error = .true.
        return
      else
        o_args = o_view_nopause
      endif
      do_nopause = .true.
    else if (sic_narg(o_view_nopause).eq.0) then
      do_nopause = .true.
    endif
    if (sic_present(o_view_over,0)) then
      ! /OVERLAY Variable [Channel]
      ! IVIEW%cplane,  IVIEW%cont and IVIEW%rplane
      vover = 'CONTINUUM'
      call sic_ke(line,o_view_over,1,vover,iover,.false.,error)
      if (error) return
      call sic_let_char('IVIEW%CONT',vover,error)
      iover = 0
      call sic_i4(line,o_view_over,2,iover,.false.,error)
      if (error) return
      call sic_let_inte('IVIEW%CPLANE',iover,error)      
    else
      vover = ' '
      call sic_let_char('IVIEW%CONT',vover,error)
    endif
  else if (comm.eq.'SHOW') then
    ! Allow SHOW Args /SIDE as well as SHOW /SIDE Args
    if (sic_narg(o_show_side).gt.0) then
      if (sic_narg(0).ne.0) then
        call map_message(seve%e,comm,'Invalid syntax in SHOW /SIDE command')
        error = .true.
        return
      else
        o_args = o_show_side
      endif
    endif
    !
    if (sic_present(o_show_over,0)) then
      ! /OVERLAY Variable [Channel]
      ! show%cplane,  show%cont and show%rplane
      call sic_get_logi('DO_CONTOUR',cont_do,err)
      vover = 'CONTINUUM'
      call sic_ke(line,o_show_over,1,vover,iover,.false.,error)
      if (error) return
      call sic_let_char('SHOW%CONT',vover,error)
      iover = 0
      call sic_i4(line,o_show_over,2,iover,.false.,error)
      if (error) return
      call sic_let_inte('SHOW%CPLANE',iover,error)      
    else
      vover = ' '
      call sic_let_char('SHOW%CONT',vover,error)
    endif
    call sic_let_logi('IVIEW%FIRST',.true.,error)
  else
    call sic_let_logi('IVIEW%FIRST',.true.,error)
  endif  
  !
  ! Fall back to last Displayed item if no Argument is given
  if (.not.sic_present(o_args,1)) then
    if (len_trim(last_shown).eq.0) then
      cshort = comm(1:7)
      call map_message(seve%e,comm,'No data to re-'//trim(cshort)//' yet')
      error = .true.
      return
    endif
    argu = last_shown
    iarg = 0
  endif
  !
  ! Parse input line
  if (iarg.ne.0) then
    call sic_ke(line,o_args,iarg,argu,nc,.true.,error)
    if (error) return
  endif
  !
  ! Should we support 
  !   COMM Topic ?  
  ! as equal to 
  !   COMM ? Topic
  !
  topic = ' '
  call sic_ch(line,0,2,topic,nt,.false.,error)
  if (argu(1:1).eq.question_mark) then
    if (nt.gt.0) then
      chain = 'HELP '//comm//topic
      call exec_program(chain)
      return        
    endif
    argu1 = '@ i_'//comm
    call sic_lower(argu1)
    argu1 = trim(argu1) //' '//argu
    call exec_program(argu1) 
    call sic_ambigs_list(comm,seve%i,'Choices are:',vtype,vshow)
    return
  else if ((topic.eq.'?').or.(topic.eq.'??')) then
    call sic_lower(argu)
    chain = 'i_show_'//trim(argu)
    exist = sic_findfile(chain,file,'gag_pro:','.ima')
    if (exist) then
      argu1 = '@ i_show_'//trim(argu)//' '//topic
      call exec_program(argu1)
    else
      chain = 'HELP '//comm//argu
      call exec_program(chain)
    endif
    return
  else if (argu.eq.'UV') then
    argu = 'UV_DATA'    
  endif
!
! Code for non-ambiguous abbreviations (dangerous with variables...)
!      
!  call sic_ambigs(comm,argu,dtype,ntype,vtype,mtype,error)
!  if (error) then
!    error = .false.
!    ntype = 0
!  endif
  !
  ! Code for exact name matching - Will avoid taking an abbreviation
  ! of a keyword in place of a SIC variable...
  !
  dtype = argu
  ntype = 0
  na = len_trim(argu)
  if (argu(na:na).eq.':') then
    ! Short-cut for a CUBE internal name
    dtype = 'CUBE'
    call sic_ch(line,o_args,iarg,argu,na,.true.,error)
  else if (dtype.ne.'PV') then
    do is=1,mtype
      if (argu.eq.vtype(is)) then
        ntype = is
        dtype = vtype(ntype)
        exit
      endif
    enddo
    if (ntype.eq.0) then
      call sic_descriptor (argu,descr,found)    ! Checked
      if ((.not.found).and.(iarg.ne.0)) then
        call sic_ch(line,o_args,iarg,argu,nc,.true.,error)
        found = sic_findfile(argu,file,' ',' ')
        if (found) then
          dtype = 'FILENAME'
        else
          !call map_message(seve%w,comm, &
          !'Cannot '//trim(comm)//' '//trim(file)//' (no such file or SIC variable)')
          dtype = 'CUBE' ! Test for Cube
          ! last_shown = ' '
          ! error = .true.
          ! return
        endif
      endif
    endif
  endif
  !
  !
  ! Special cases first
  do_insert = sic_lire().eq.0
  done = .false.
  do_color = .false.  ! No Color LUT in most actions
  !
  exec_chain = ' '
  !
  select case (dtype)
  case ('UV_FIT')
    if (sic_present(o_args,2)) then
      call sic_ke(line,o_args,2,argu,nc,.false.,error)
      if (error) return
      if (argu(1:1).eq.question_mark) then
        exec_chain = '@ i_plotfit '//argu
      else
        nc = min(nc,6)
        if (argu(1:nc).eq.vuvfit(1:nc)) then
          exec_chain = '@ d_plotfit '
        else
          call map_message(seve%e,comm,'Invalid SHOW UV_FIT argument '//trim(argu))
          error = .true.
          return
        endif
      endif
    else
      if (huvfit%loca%size.eq.0) then
        call map_message(seve%e,comm,'No UV_FIT performed')
        error = .true.
      else 
        exec_chain = '@ p_plotfit UV_FIT'
      endif
    endif
    done = .true. 
  case ('SED')
    call sic_r4(line,0,2,sed_freq,.false.,error)
    if (error) return
    if (sic_present(0,3)) then
      call sic_ch(line,0,3,sed_file,nc,.false.,error)
    else if (sed_file.eq.' ') then
      sed_file = "'sed%name'"
    endif
    if (error) return
    nc = len_trim(sed_file)
    if (nc.eq.0) then
      call map_message(seve%e,comm,'No file name specified')
      error = .true.
      return
    endif
    write(argu2,*) sed_freq
    exec_chain = '@ p_show_sed '//sed_file(1:nc)//argu2//' COLOR'
    done = .true.
  case ('FLUX') 
    ! Pass arguments as they are given - DISPLAY\SHOW FLUX is 18 chars
    exec_chain = '@ p_show_flux '//line(19:)
    done = .true.
  case ('COMPOSITE') 
    argu = ' '
    call sic_ke(line,0,2,argu,nc,.false.,error)
    if (nc.ne.0) then
      kc = min(nc,6)
      if (argu(1:kc).eq.comptype(1)(1:kc)) then
        compmode = comptype(1)
      else if (argu(1:kc).eq.comptype(2)(1:kc)) then
        compmode = comptype(2)
      else
        call map_message(seve%e,comm,'No such mode '//argu(1:nc))
        error = .true.
        return
      endif
    endif
    exec_chain = '@ p_show_composite '//compmode
    done = .true.
  case ('FIELDS') 
    if (hprim%loca%size.eq.0 .or. comm.eq.'SHOW') then
      if (themap%nfields.eq.0) then
        call map_message(seve%e,comm,'No Mosaic loaded')
        error = .true.
      else
        exec_chain = '@ p_plot_fields FIELDS'
        done = .true.
      endif
    else
      call create_fields(error)
      if (error) return
      dtype = 'FIELDS'
    endif
  case ('PRIMARY') 
    !! Print *,'Calling Create Fields'
    call create_fields(error)
    if (error) return
    dtype = 'FIELDS'
    !
  case ('SELFCAL')
    is = sic_start(0,2)
    if (is.eq.0) then
      exec_chain = '@ p_show_selfcal '
    else
      exec_chain = '@ p_show_selfcal '//line(is:)
    endif
    done = .true.
  case('MOMENTS') 
    if (sic_present(o_args,2)) then
      call sic_ke(line,o_args,2,argu,nc,.true.,error)
      if (argu(1:1).eq.'?') then
        exec_chain = '@ i_show_moments '//argu
        done = .true.
        return
      endif
    endif
    exec_chain = '@ p_show_moments '
    done = .true.
    do_color = .false. ! ? unclear here...
  case ('NOISE','INTENSITY','STATISTIC','PV')
    if ((sic_narg(o_args).lt.2).and.(dtype.eq.'PV')) then
      exec_chain = '@ p_show_map PV'
      done = .true.
    else
      !
      dnoise = ' '
      istart = 2
      !
      if (sic_present(o_args,2)) then
        call sic_ke(line,o_args,2,argu,nc,.true.,error)
        if (error) return
        if (argu(1:1).eq.'?') then
          if (dtype.eq.'PV') then
            exec_chain = '@ i_show_pv '//argu
          else 
            exec_chain = '@ i_show_noise '//argu
          endif
          done = .true.
          return
        endif
        !
        if (dtype.eq.'PV') then
          narg = sic_narg(0)
          if (narg.eq.5) then
            dnoise = argu
            istart = 3
          else if (narg.ne.4) then
            call map_message(seve%e,comm,'Missing arguments to '//trim(comm)//' PV')
            error = .true.
            return
          endif
        else 
          dnoise = argu
          istart = 3
        endif
      endif
      !
      if (dnoise.eq.' ') then
        !
        ! Fall back on the last displayed or computed image
        if (last_shown.eq.'CLEAN' .or. last_shown.eq.'DIRTY' .or. last_shown.eq.'SKY') then
          dnoise = last_shown
        else  if (hsky%loca%size.ne.0) then
          dnoise = 'SKY'
        else  if (hclean%loca%size.ne.0) then
          dnoise = 'CLEAN'
        else if (hdirty%loca%size.ne.0) then
          dnoise = 'DIRTY'
        else
          call map_message(seve%e,comm,'No SKY, CLEAN or DIRTY image')
          error = .true.
          return
        endif
      endif
      !
      if (dtype.eq.'PV') then
        ! Next argument must be X or Y
        call sic_ke(line,o_args,istart,argu,nc,.true.,error)
        if (error) return
        if (argu.eq.'X') then
          l_axis = 1
        else if (argu.eq.'Y') then
          l_axis = 2
        else
          call map_message(seve%e,comm,'Invalid axis, must be X or Y')
          error = .true.
          return      
        endif
        !
        ! Then Offset along the other X or Y direction
        istart = istart+1
        call sic_r4(line,o_args,istart,soff,.true.,error)   
        if (error) return   
      else
        if (dtype.eq.'NOISE') then
          noise_type = 0
        else if (dtype.eq.'INTENSITY') then
          noise_type = 1
        else if (dtype.eq.'STATISTIC') then
          noise_type = -1
        endif
        !
        ! RMS plus Standard FIRST + LAST ...
        !
        chain = ' -1'   ! Negative noise guess
        if (sic_narg(o_args).ge.istart) then
          ic = 2
          do i=istart, sic_narg(o_args)
            call sic_ch(line,o_args,i,argu,nc,.true.,error)
            chain(ic:) = argu(1:nc)
            ic = ic+nc+2
          enddo
        endif      
      endif
      !   
      call gildas_null(head) 
      if ((dtype.eq.'PV').and.(hpv%gil%ndim.ne.0)) then
        deallocate(hpv%r2d)
        hpv%gil%ndim = 0
        call sic_delvariable('PV',.false.,error)
        error = .false.
      endif
      !
      if (dnoise.eq.'CLEAN') then
        locasize = hclean%loca%size
        if (dtype.eq.'PV') call gdf_copy_header(hclean,head,error)
        head%r3d => dclean
      else if (dnoise.eq.'SKY') then
        locasize = hsky%loca%size
        if (dtype.eq.'PV') call gdf_copy_header(hsky,head,error)
        head%r3d => dsky
      else if (dnoise.eq.'DIRTY') then
        locasize = hdirty%loca%size
        if (dtype.eq.'PV') call gdf_copy_header(hdirty,head,error)
        head%r3d => ddirty
      else if (sic_varexist(dnoise)) then
        locasize = -1
      else
        locasize = 0
      endif
      if (locasize.eq.0) then
        call map_message(seve%e,comm,'No '//trim(dnoise)//' image')
        error = .true.
        return
      endif
      if (dtype.eq.'NOISE'.or.dtype.eq.'INTENSITY'.or.dtype.eq.'STATISTIC') then
        if (comm.eq.'SHOW') then
          exec_chain = '@ p_show_noise '//dnoise//chain
          done = .true.
        else if (comm.eq.'VIEW') then
          exec_chain = '@ p_view_noise '//dnoise//chain
          done = .true.
        endif
      else if (dtype.eq.'PV') then
        if (locasize.eq.-1) then
          call map_message(seve%e,comm,'PV Only valid for DIRTY, CLEAN or SKY')
          error = .true.
          return
        endif
        !
        ! Extract from current data...
        ioff = (soff*pi/180/3600 - head%gil%val(l_axis)) / head%gil%inc(l_axis) + head%gil%ref(l_axis)
        if (ioff.lt.1 .or. ioff.gt.head%gil%dim(l_axis)) then
          call map_message(seve%e,comm,'Offset out of range')
          error = .true.
          return
        endif
        write(mess,'(A,I0,A,F10.2,A,I0)') 'Extracting along Axis ',l_axis,' at Offset ',soff,'", Plane ',ioff
        call map_message(seve%i,comm,mess)
        call gildas_null(hpv)
        if (l_axis.eq.1) then
          call gdf_transpose_header(head, hpv, '231', error)
          hpv%gil%ndim = 2
          allocate(hpv%r2d(hpv%gil%dim(1),hpv%gil%dim(2)),stat=ier)
          hpv%r2d(:,:) = head%r3d(ioff,:,:)
        else
          call gdf_transpose_header(head, hpv, '132', error)
          hpv%gil%ndim = 2
          allocate(hpv%r2d(hpv%gil%dim(1),hpv%gil%dim(2)),stat=ier)
          hpv%r2d(:,:) = head%r3d(:,ioff,:)
        endif
        hpv%gil%dim(3) = 1
        call sic_mapgildas('PV',hpv,error,hpv%r2d)
        exec_chain = '@ p_show_map PV'   
        !
        done = .true.
      endif
    endif
  case ('SUPPORT') 
    if (supportpol%ngon.ge.2) call greg_poly_plot(supportpol,error) 
    done = .true.
  case ('SNR')
    if (the_method%mosaic) then
      exec_chain = '@ p_snr '//comm
      done = .true.
    else
      call map_message(seve%e,comm,trim(comm)//' SNR only available in Mosaic mode')
      error = .true.
    endif
    do_color = .true.
  case ('SPECTRA') 
    argu = ' '
    call sic_ch(line,o_args,2,argu,nc,.false.,error)
    exec_chain = '@ p_spectra '//argu
    done = .true.
  case ('FILENAME') 
    !
    ! General [First [Last]] channel selection
    argu1 = ' '
    call sic_ch(line,o_args,2,argu1,nc,.false.,error)
    argu2 = argu1
    call sic_ch(line,o_args,3,argu2,nc,.false.,error)
    !
    if (file(1:1).eq.'/') then
      chain = 'DISPLAY\LOAD "'//trim(file)//'"'
    else
      chain = 'DISPLAY\LOAD '//trim(file)
    endif
    call exec_command(chain,error)
    if (error) return
    !!    last_shown = ' ' ! May be Needed ???
    !
    chain = 'DATA '//trim(argu1)//' '//trim(argu2)
    if (comm.eq.'SHOW') then
      nt = len_trim(chain)
      if (nt.ne.4) chain(nt+1:) = ' SCALE'  ! Use default scale in this case
      do_loop  = show_side 
      exec_chain = '@ p_show_map '//chain
      show_side = do_loop 
    else if (comm.eq.'INSPECT_3D') then
      exec_chain = '@ p_3view_map '//chain
    else  
      if (iarg.ne.0) then
        call sic_let_logi('IVIEW%DO%WINDOW',.true.,error)
        call sic_let_logi('IVIEW%DO%EXTREMA',.true.,error)
        call sic_let_logi('IVIEW%DO%FLUX',.true.,error)
        call sic_let_logi('IVIEW%DO%LINE',.true.,error)
        error = .false.
      endif
      if (do_nopause) view_do_loop = .false.
      exec_chain = '@ p_view_map '//chain
    endif
    last_shown = 'DATA'
    done = .true.
    do_color = .true.
  case ('SOURCES') 
    call show_sources_comm(line,error)
    done = .true.
  case ('CLEAN') 
    !
    ! Fall back onto SKY if CLEAN does not exist...
    argu = dtype
    call sic_descriptor (argu,descr,found)    ! Checked
    if (.not.found) then
      argu = 'SKY'
      call sic_descriptor (argu,descr,found)    ! Checked
      if (found) then
        dtype = 'SKY'
        call map_message(seve%w,comm,'No CLEAN data, falling back on SKY')
      endif
    endif
    do_color = .true.
  case ('BEAM')
    argu = dtype
    do_color = .true.
  case ('UV_DATA')
    !
    call gildas_null(htmp,type='UVT')
    call uv_buffer_finduv(code) 
    call gdf_copy_header(huv_current,htmp,error)
    call uvdata_select(comm,error)
    if (error) return
    !
    call display_uv(current_uvdata,line,error)
    done = .true.
    do_color = .false.
    ! Reset the previous UV data pointers
    call uv_buffer_resetuv(code) 
    call gdf_copy_header(htmp,huv_current,err)
  case ('COVERAGE')
    ntype = 1
    done = .false.
  case ('KEPLER')
    argu = ' '
    call sic_ch(line,o_args,2,argu,nc,.false.,error)
    exec_chain = '@ p_kepler_show '//argu
    done = .true.  
  case ('SIMULATION') 
    exec_chain = '@ p_simulate show '
    done = .true.  
  case default
    ! Any unknown variable - We must check what sort of data this is
    ! before calling any script (UV or datacube)
    do_color = .true.
    !
    dtype = 'MYDATA'
    call sub_load_var(comm,line,argu,dtype,itype,error)
    if (error) return
    call sic_descriptor (dtype,descr,found)
    !
    do_color = .true.
    if (associated(descr%head)) then    
      descr%head%file = argu
      if (abs(descr%head%gil%type_gdf).eq.abs(code_gdf_uvt)) then  
        ! This is a SHOW UV like plot...
!        argu1 = ' '
!        call sic_ch(line,o_args,2,argu1,nc,.false.,error)
!        argu2 = argu1
!        call sic_ch(line,o_args,3,argu2,nc,.false.,error)
        !
        chain = trim(dtype)//' '//trim(argu1)//' '//trim(argu2)
        call display_uv(chain,line,error)
        done = .true.
        do_color = .false.
      endif
    endif
  end select
  !
  ! Check error status
  if (error) return
  !
  ! In call cases -- Initialize o_dir
  o_dir = o_view_dir
  if (comm.eq.'SHOW') o_dir = o_show_dir
  !
  if (exec_chain.ne.' ') then
    call get_topdir(line,o_dir)
    call exec_program(exec_chain)
  endif
  if (comm.eq.'VIEW') view_do_loop = do_loop
  !
  if (.not.done) then
    if (comm.eq.'VIEW') then
      if (iarg.ne.0) then
        call sic_let_logi('IVIEW%DO%WINDOW',.true.,error)
        call sic_let_logi('IVIEW%DO%EXTREMA',.true.,error)
        call sic_let_logi('IVIEW%DO%FLUX',.true.,error)
      endif
    endif
    ! Display the buffer if not already done
    call display_buffer_sub(comm,ntype,dtype,line,o_args,o_dir,error)
    if (dtype.eq.'CLEAN' .or. dtype.eq.'DIRTY' .or. dtype.eq.'SKY') then
      last_shown = dtype
    else if (dtype.eq.'DATA') then
      last_shown = 'DATA'
    else if (dtype.eq.'MYDATA') then
      last_shown = 'MYDATA'
    endif
    !
  endif
  !
  ! Set the Color LUT if needed
  if (do_color) then
    call sic_get_real('SHOW_COLOR',colour,error)
    if (colour.ne.0) then
      call sic_let_real('COLOR[3]',colour,error)
      call exec_program('@ p_color')
    endif
  endif
  !
  ! Insert command if needed
  if (do_insert) call sic_insert_log(line)
  !
end subroutine display_buffer
!
subroutine display_buffer_sub(comm,ntype,dtype,line,o_args,o_dir,error)
  use gkernel_interfaces
  use imager_interfaces, only : display_uv, cct_integrate, map_message
  use clean_types
  use clean_arrays
  use clean_default
  use gbl_message
  !----------------------------------------------------------------------
  ! @ private
  !*
  ! IMAGER support routine for commands SHOW or VIEW Name
  !
  ! Display the specified buffer according to its type
  !!
  !----------------------------------------------------------------------
  character(len=*), intent(in) :: comm  !! Command name SHOW or VIEW
  integer, intent(in)  :: ntype         !! Buffer type
  character(len=*), intent(in) :: dtype !! Buffer name
  character(len=*), intent(in) :: line  !! Command line
  integer, intent(in) :: o_args         !! Where are the arguments ?
  integer, intent(in) :: o_dir          !! /DIRECTORY option location
  logical, intent(out) :: error         !! Logical error flag
  !
  ! Constants
  integer, parameter :: o_view_nopause=2
  integer, parameter :: o_show_cont=1
  integer, parameter :: o_show_over=3
  integer, parameter :: o_view_side=3
  integer, parameter :: o_show_side=4
  !
  ! Local ---
  character(len=40) :: argu1,argu2
  character(len=120) :: chain
  integer :: nc,first,last,ic
  logical :: do_loop, do_cont, cont_do, needed, err
  character(len=12) :: xtype,ytype
  !
  ! Code ----
  !
  ! Load into SIC buffer
  if (comm.eq.'SHOW' .and. ntype.eq.1) then
    !
    ! SHOW Coverage
    call sic_get_inte('FIRST',first,error)
    call sic_get_inte('LAST',last,error)
    call sic_get_char('XTYPE',xtype,nc,error)
    call sic_get_char('YTYPE',ytype,nc,error)
    call sic_let_char('XTYPE','u',error)
    call sic_let_char('YTYPE','v',error)
    if (first.eq.0 .and. last.eq.0) then
      ic = huv_current%gil%nchan/3
      call sic_let_inte('FIRST',ic,error)
      call sic_let_inte('LAST',ic,error)
    endif
    chain = 'UV'
    call display_uv (chain,line,error)
    call sic_let_char('XTYPE',xtype,error)
    call sic_let_char('YTYPE',ytype,error)
    call sic_let_inte('FIRST',first,error)
    call sic_let_inte('LAST',last,error)
    return
  endif
  !
  ! General [First [Last]] channel selection
  argu1 = ' '
  call sic_ch(line,o_args,2,argu1,nc,.false.,error)
  argu2 = argu1
  call sic_ch(line,o_args,3,argu2,nc,.false.,error)
  !
  ! Plot SIC buffer with adequate plotting procedure
  if (comm.eq.'SHOW' .or. comm.eq.'UV_FLAG') then
    if (dtype.eq.'UV_DATA') then
      if (argu1.eq."?" .and. argu2.eq.argu1) then
        call exec_program('@ i_show_uv')
        return
      endif
      chain = 'UV '! //trim(argu1)//' '//trim(argu2)
      call display_uv(chain,line,error)
    else if (dtype.eq.'CCT') then
      if (hcct%loca%size.eq.0) then
        call map_message(seve%e,comm,'No CCT buffer')
        error = .true.
        return
      endif
!      argu1 = ' '
!      call sic_ch(line,o_args,2,argu1,nc,.false.,error)
      call get_topdir(line,o_dir)
      call cct_integrate(comm,hcct,dcct,error)
      call exec_program('@ p_show_cct cct '//argu1)
    else if (dtype.eq.'BEAM' .or. dtype.eq.'FIELDS') then
      !
      ! SHOW BEAM [Field F|Plane P] [First Last]
      ! @ p_show_beam BEAM FIELD 16
      !   or
      ! @ p_show_beam BEAM PLANE 1 [First Last]
      !
      if (dtype.eq.'BEAM') then
        if (hbeam%loca%size.eq.0) then
          call map_message(seve%e,comm,'No BEAM buffer')
          error = .true.
          return
        endif
        needed = .false.
        if (hbeam%gil%ndim.eq.4) then
          needed = (hbeam%gil%dim(4).gt.1).and.(hbeam%gil%dim(3).gt.1)
        endif
      else
        if (hfields%loca%size.eq.0) then
          call map_message(seve%e,comm,'No FIELDS buffer')
          error = .true.
          return
        endif
        needed = .false.
        if (hfields%gil%ndim.eq.4) then
          needed = (hfields%gil%dim(4).gt.1).and.(hfields%gil%dim(3).gt.1)
        endif      
      endif
      if (needed.and.sic_narg(0).lt.3) then
        call map_message(seve%e,comm,'Missing PLANE or FIELD key and number')
        error = .true.
        return
      endif
      argu1 = 'PLANE'
      call sic_ke(line,o_args,2,argu1,nc,needed,error)
      argu2 = '1'
      call sic_ch(line,o_args,3,argu2,nc,needed,error)
      if (error) return
      !      
      call get_topdir(line,o_dir)
      call exec_program('@ p_show_beam '//dtype//trim(argu1)//' '//trim(argu2))
    else
      !
      do_loop = show_side
      if (sic_present(o_show_side,0)) show_side = .true.
      call sic_get_logi('DO_CONTOUR',cont_do,err)
      do_cont = cont_do
      if (sic_present(o_show_over,0)) then
        if (sic_present(o_show_cont,0)) call map_message(seve%w,comm, &
          & "Option /SHOW ignored when /OVERLAY present")
        do_cont = .false.
      else if (sic_present(o_show_cont,0)) then
        do_cont = .true.
        call sic_l4(line,o_show_cont,1,do_cont,.false.,error)
        if (error) return
      endif
      call sic_let_logi('DO_CONTOUR',do_cont,err)
      chain = trim(dtype)//' '//trim(argu1)//' '//trim(argu2)
      if (chain.ne.dtype) then
        nc = len_trim(chain)+2
        chain(nc+2:) = 'SCALE'
      endif
      call get_topdir(line,o_dir)
      call exec_program('@ p_show_map '//chain)
      call sic_let_logi('DO_CONTOUR',cont_do,err)
      show_side = do_loop
      !
    endif
  else if (comm.eq.'VIEW') then
    do_loop = view_do_loop
    select case (dtype)
    case ('UV_DATA')
      return
    case ('BEAM','FIELDS','PRIMARY')
      !
      ! VIEW BEAM|FIELDS|PRIMARY [Field F|Plane P] [First Last]
      ! @ p_view_beam BEAM FIELD 16
      !   or
      ! @ p_view_beam BEAM PLANE 1 
      !
      if (hbeam%loca%size.eq.0) then
        call map_message(seve%e,comm,'No BEAM buffer')
        error = .true.
        return
      endif
      needed = .false.
      if ((hbeam%gil%ndim.eq.4).and.(dtype.eq.'BEAM')) then
        needed = hbeam%gil%dim(4)*hbeam%gil%dim(3) .gt.1
      endif
      if (needed.and.sic_narg(0).lt.3) then
        call map_message(seve%e,comm,'Missing PLANE or FIELD key and number')
        error = .true.
        return
      endif
      argu1 = 'PLANE'
      call sic_ke(line,o_args,2,argu1,nc,needed,error)
      argu2 = '1'
      call sic_ch(line,o_args,3,argu2,nc,needed,error)
      if (error) return
      !      
      if (sic_present(o_view_nopause,0)) view_do_loop = .false.
      chain = '@ p_view_beam '//dtype//trim(argu1)//' '//trim(argu2)
    case ('CCT') 
      if (hcct%loca%size.eq.0) then
        call map_message(seve%e,comm,'No CCT buffer')
        error = .true.
        return
      endif
      call cct_integrate(comm,hcct,dcct,error)
      chain = '@ p_view_cct '//dtype//trim(argu1)//' '//trim(argu2)
    case default
      if (sic_present(o_view_nopause,0)) view_do_loop = .false.
      chain = '@ p_view_map '//dtype//trim(argu1)//' '//trim(argu2)
    end select
    !
    call get_topdir(line,o_dir)
    call exec_program(chain)
    view_do_loop = do_loop
  else if (comm.eq.'INSPECT_3D') then
    if (dtype.eq.'UV_DATA') then
      continue
    else if (dtype.eq.'CCT') then
      continue
    else
      chain = '@ p_3view_map '//dtype//trim(argu1)//' '//trim(argu2)
      call get_topdir(line,o_dir)
      call exec_program(chain)
    endif
  endif
  !
end subroutine display_buffer_sub
!
subroutine create_fields(error)
  use gkernel_interfaces
  use clean_arrays
  use clean_types
  use imager_interfaces, only : define_fields
  !----------------------------------------------------------------------
  ! @ private
  !*
  ! IMAGER -- internal routine for command SHOW FIELDS  
  !
  !     Create the FIELDS array (transposed version of the PRIMARY array)
  !!
  !----------------------------------------------------------------------
  logical, intent(out) :: error  !! Logical error flag
  !
  ! Local variables
  character(len=4) :: code
  integer(kind=index_length) :: nfirst,nsecon,nmiddl,nelems,nlast,iblock(5)
  integer :: ier
  logical :: found
  !
  if (hprim%loca%size.eq.0) then
    error = .true.
    return
  endif
  error = .false.
  !
  ! If it is allocated, it should be the right one, but play safe...
  if (allocated(dfields)) then
    found = .true.
    ! !Print *,'dfiels is already allocated ',hfields%loca%size, hprim%loca%size
    if (hfields%loca%size.ne.hprim%loca%size) then
      ! !Print *,'FIELDS is already allocated ',hfields%loca%size, hprim%loca%size
      ! !Print *,'   but it does not have the right size'
      deallocate(dfields)
      !
      found = .false.
    endif
  else
    ! !Print *,'Dfield not allocated '
    found = .false.
  endif
  !
  call gildas_null(hfields)
  !
  code = '231'
  call gdf_transpose_header(hprim,hfields,code,error)
  ! Determine chunk sizes from code and dimensions.
  call transpose_getblock(hprim%gil%dim,gdf_maxdims,code,iblock,error)
  if (error) return
  !
  ! With only one beam per frequency so far
  if (.not.allocated(dfields)) then
    allocate(dfields(hprim%gil%dim(2),hprim%gil%dim(3),hprim%gil%dim(1),hprim%gil%dim(4)),stat=ier)
    if (ier.ne.0) then
      error = .true.
      return
    endif
  endif
  !
  nelems = iblock(1)
  nfirst = iblock(2)
  nmiddl = iblock(3)
  nsecon = iblock(4)
  nlast  = iblock(5)
  call trans4all(dfields,dprim,nelems,nfirst,nmiddl,nsecon,nlast)
  !
  ! Set Type of First Axis
  hfields%gil%inc(3) = 1.0
  hfields%char%code(3) = 'FIELD'
  !
  ! If array was already there, the variables were there too
  if (found) return
  !
  ! That is a little too much. It also destroys other FIELDS% variables...
  ! FIELDS%N, FIELDS%CENTERS[2,Fields%N], and FIELDS%PRIMARY 
  call sic_delvariable('FIELDS',.false.,error)
  ! So re-create them
  call define_fields(themap,error)  
  call sic_mapgildas ('FIELDS',hfields,error,dfields)
  !
end subroutine create_fields
! 
subroutine get_size_factor(factor)
  use clean_default
  !----------------------------------------------------------------------
  ! @ private
  !* 
  ! IMAGER / VIEWER -- Support for the SET ANGLE_UNIT command
  !
  ! Return the Angle_Unit to User coordinates factor
  !!
  !----------------------------------------------------------------------
  real(kind=8), intent(out) :: factor  !! Scale 
  !
  real(kind=8), parameter :: pi=3.14159265358979323846d0
  real(8), parameter :: bunit(4)=[pi/180d0,pi/180.d0/60d0,pi/180d0/3600d0,1.d0]
  !
  factor = bunit(abs(iangle_unit))
end subroutine get_size_factor
!
subroutine display_set_comm(line,comm,error)
  use gkernel_interfaces
  use clean_types
  use clean_default
  use gbl_message
  use imager_interfaces, only : map_message
  !----------------------------------------------------------------------
  ! @ private
  !* 
  ! IMAGER / VIEWER  
  !      Support for the 
  !         SET ANGLE_UNIT command  
  !         SET TRAIL YES|NO  (keep or ignore Trailing column)  
  !         SET FORMAT GILDAS|FITS  
  !         SET COLOR  DARK|WHITE
  ! Fall back to GREG1\SET command for any other argument
  !!
  !----------------------------------------------------------------------
  character(len=*), intent(inout) :: line  !! Command line
  character(len=*), intent(in) :: comm     !! Command name
  logical, intent(inout) :: error          !! Logical error flag
  !
  ! Constants
  real(kind=8), parameter :: pi=3.14159265358979323846d0
  real(8), parameter :: bunit(4)=[pi/180d0,pi/180.d0/60d0,pi/180d0/3600d0,1.d0]
  character(len=8) :: cdark='DARK', cwhite='WHITE'
  character(len=32) :: avoc(4)
  character(len=24) :: aformat(-1:3)
  character(len=12) :: caunit(0:5), cformat(2), cfits(3)
  data caunit /'ABSOLUTE','DEGREE','MINUTE','SECOND','RADIAN','RELATIVE'/
  data avoc /'ANGLE_UNIT ','COLOR_MODEL','FORMAT','TRAIL'/
  data cformat/'GILDAS','FITS'/
  data cfits  /'NATIVE','VELOCITY','FREQUENCY'/  ! Order matters
  data aformat /'CSV','GILDAS','FITS','FITS VELOCITY','FITS FREQUENCY'/
  !
  ! Memory --
  character(len=8), save :: color_old='WHITE'
  !
  ! Local ---
  character(len=32) :: key, qmark
  character(len=12) :: argu
  integer :: ia,n,nq,ounit, narg
  logical :: default
  real(kind=8) :: factor
  character(len=128) :: myline
  !
  ! Code ----
  default = sic_present(1,0)
  narg = sic_narg(0)
  if (default.and.(narg.eq.0)) then
    ! SET /DEFAULT
    !   Reset GreG and Imager defaults
    ounit = abs(iangle_unit)
    iangle_unit = -3 
    factor = bunit(ounit)/bunit(abs(iangle_unit))
    area_size = area_size*factor
    area_center = area_center*factor
    !
    call gr_exec1('SET /DEFAULT')
    return
  endif
  !
  call sic_ke(line,0,1,key,n,.true.,error)
  if (error) return
  qmark = '?'
  call sic_ke(line,0,2,qmark,nq,.false.,error)
  if (error) return
  !
  if (key(1:n).eq.avoc(1)(1:n)) then
    !
    ounit = abs(iangle_unit)
    !
    if (default.and.(narg.eq.1)) then
      iangle_unit = -3
    else 
      !
      if (qmark.eq.'?')  then
        if (iangle_unit.lt.0) then
          call map_message(seve%i,'SET', &
          &   'Current display angle unit is ABSOLUTE if possible, ' &
          &   //caunit(-iangle_unit)//' otherwise')
        else
          call map_message(seve%i,'SET', &
          &   'Current display angle unit is '//caunit(iangle_unit))
        endif
        return
      else 
        key = qmark
        if (default) call map_message(seve%w,'SET', &
          & '/DEFAULT option ignored with argument')
        !
        call sic_ambigs ('SET ANGLE_UNIT',key,argu,n,caunit,6,error)
        if (error) return
        n = n-1
        if (n.eq.0) then
          iangle_unit = -abs(iangle_unit)
        else if (n.eq.5) then
          iangle_unit =  abs(iangle_unit)
        else
          iangle_unit = n
        endif
      endif
    endif
    !
    ! Reset unit and convert SIZE and CENTER
    factor = bunit(ounit)/bunit(abs(iangle_unit))
    area_size = area_size*factor
    area_center = area_center*factor
    !
    ! Reset all conversion formulas and displayed Units
    call exec_program('@ d_box')
  else if (key(1:n).eq.avoc(2)(1:n)) then
    if (qmark.eq.'?') then
      call map_message(seve%i,'SET COLOR',trim(color_model)//' color model')
    else
      call sic_ke(line,0,2,key,n,.false.,error)
      color_old = color_model
      if (key(1:n).eq.cdark(1:n)) then
        color_model = cdark
      else
        color_model = cwhite
      endif
      if (color_old.ne.color_model) call exec_program('@ gag_pro:set-colors '//color_model)
    endif
  else if (key(1:n).eq.avoc(3)(1:n)) then
    if (qmark.eq.'?') then
      call map_message(seve%i,'SET FORMAT','Current format is '//aformat(write_default))
      call map_message(seve%i,'SET FORMAT','Choices are: GILDAS, FITS, FITS VELOCITY, FITS FREQUENCY')
      return
    endif
    key = qmark
    call sic_ambigs ('SET FORMAT',key,argu,n,cformat,2,error)
    if (error) return
    if (key.eq.'GILDAS') then
      write_default = write_gildas
    else
      key = 'NATIVE'
      call sic_ke(line,0,3,key,n,.false.,error)
      if (error) return
      call sic_ambigs ('SET FORMAT',key,argu,n,cfits,3,error)
      if (error) return
      write_default = n
    endif
  else if (key(1:n).eq.avoc(4)(1:n)) then
    if (qmark.eq.'?') then
      if (read_trail) then
        call map_message(seve%i,'SET TRAIL','YES (trailing columns are read by default)')
      else
        call map_message(seve%i,'SET TRAIL','NO  (trailing columns are ignored)') 
      endif
    else
      call sic_l4(line,0,2,read_trail,.false.,error)
    endif
  else
    ! 
    if (key.eq.'?') then
      call sic_ambigs ('DISPLAY\SET',key,argu,n,avoc,3,error)
    endif
    ! GREG\SET fall back
    ia = index(line,' ') 
    myline = 'GREG1\SET'//line(ia:)
    call exec_command(myline,error)
  endif
end subroutine display_set_comm
!
subroutine get_topdir(line,o_dir)
  use gkernel_interfaces
  !----------------------------------------------------------------
  ! @ private
  !!   IMAGER -- Support routine for option /DIRECTORY of DISPLAY\ commands 
  !!    Create and/or move to the specified root directory
  !----------------------------------------------------------------
  character(len=*), intent(in) :: line  !! Command line
  integer, intent(in) :: o_dir          !! /DIRECTORY option number
  !
  ! Local ---
  character(len=64) :: cdir
  integer :: n
  logical :: error
  !
  ! Code ----
  error = .false.
  if (.not.sic_present(o_dir,1)) then
    call exec_string('GTVL\CHANGE DIRECTORY',error)
  else
    !
    call sic_ke(line,o_dir,1,cdir,n,.true.,error)
    if (error) return
    if (cdir(1:1).ne.'<') then
      cdir = '<'//cdir(1:n)
      n =n+1
    endif
    if (.not.gtexist(cdir(1:n))) then
      call exec_string('GTVL\CREATE DIRECTORY '//cdir(1:n),error)
      if (error) return
    endif
    call exec_string('GTVL\CHANGE DIRECTORY '//cdir(1:n),error)
  endif
end subroutine get_topdir
!
