!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
! GILDAS "wide" view tool
!   Cloned from p_view_sub.map
! by splitting the spectral boxes in two parts:
!   1) top    : wide spectrum
!   2) bottom : narrow spectrum
!
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
if .not.exist(&1) then
  message E VIEW "Variable &1 does not exist"
  return error
endif
!
! General external controls
! do_loop     : loop with cursor or just display "as is" (e.g. for Hardcopies)
! sblc strc   : from size[2] and center[2]
! do_write    : write mode (external control? or option?) to be implemented
!
if (.not.exist(view%root)) then
  ! view%first is defined at Start by IMAGER
  if exist(view%first) delet /var view
  ! Almost everything is in this structure
  define structure view /global
  ! Name of viewed global variable, with "memory" to optimize
  define character view%root*32 view%previous*32  /global
  let view%previous " "
  define real view%expand /global
  let view%expand 0.8
  !
  ! Code and Names of the Boxes
  define integer view%nbox view%area view%channel view%spec_h view%mean_h view%spec_w view%mean_w view%default /global
  let view%nbox 6
  let view%area 1
  let view%channel 2
  let view%spec_h 4
  let view%mean_h 3
  let view%spec_w 6
  let view%mean_w 5
  let view%default 2
  define char view%names*8[7] /global
  let view%names "area" "channel" "mean" "spectrum" "WMEAN" "WSPECTRUM" "outside" ! New order
  define real view%boxes[4,view%nbox] /global
  ! This must be reset at each Toggle (N key)
  let view%names['view%nbox+1'] "outside"
  !
  ! Name of actions
  define char view%actions*10[19] /global
  !                   1       2         3          4       5       6      7       8        9       10     11     12     13      14      15       16      17     18     19
  let view%actions "flux" "spectrum" "window" "channel" "slice" "movie" "zoom" "unzoom" "extract" "help" "view" "mask" "print" "value"  "write"  "wide" "lines" "mask" "range"
  !
  ! General behaviour
  define double view%range[2] view%jyperk /global
  define integer view%iprint /global
  define logical view%contour view%side /global
  define real view%movie /global         ! Time for movie
  let view%iprint 0
  let view%contour no
  let view%side yes
  let view%movie 0  ! Automatic guess
  !
  ! Contour overlay
  define integer view%rplane /global     ! Reference plane displayed
  define integer view%cplane /global     ! Continuum plane displayed
  define character view%cont*32 /global  ! "Continuum" image name
  define character view%order*3 /global
  let view%rplane 0
  let view%cplane 0
  let view%cont " "
  let view%order 000
  !
  define logical view%first /global
  !
  ! These are the same variables as in the GreG version, for
  ! historical compatibility
  if .not.exist(mspectre) then
    define real velocities[2] xspectre[2] cspectre[2] mspectre[2] /global
    define integer miplane[2] /global   ! Plane range (First to Last)
  endif
  !
  ! Below, variables should be in some working sub-structure of view%
  define structure view%do /global
  define logical view%do%flux view%do%window view%do%extrema view%do%mask view%do%line /global
  define structure view%old view%current view%status view%inte view%chan /global
  ! Old
  define integer view%old%ixy view%old%mxy /global
  let view%old%ixy 0
  let view%old%mxy 0
  ! Status
  define logical view%status%rima view%status%rspe /global ! Relative coordinates (Image and Spectra)
  define logical view%status%kill view%status%unkill view%status%szoom view%status%vzoom /global
  ! Current ranges and values
  define real view%current%min view%current%max  /global          ! Min Max in selected data
  define integer view%current%pixel[2] view%current%plane /global ! Current Pixel and Plane
  define real view%current%area_range[2] /global                  ! Area color scale span (used in strange cases)
  define real view%inte%min view%inte%max /global                 ! Integrated Area color scale (automatic)
  define real view%chan%min view%chan%max /global                 ! Channel color scale (automatic)
  define real view%current%velo view%current%vcent view%current%width /global    ! Velocity: Current, Center and Width
  ! Frequency: Current, Min and Max, Range
  define double view%current%freq view%current%fmin view%current%fmax view%current%frange[2] /global
  !
  ! Velocity Limits (1,2) and Current (3)
  define real view%ulimit[3] /global
  !
  ! Current pixel
  define integer view%ix view%iy /global
  define character*24 view%cx view%cy /global
  let view%do%mask no
  let view%do%line yes
  let view%first yes
  let view%status%kill no
  let view%status%unkill no
  let view%status%szoom no
  let view%status%vzoom no
  let view%status%rima no
  let view%status%rspe no
  let view%current%plane 0
  !
  ! 3rd axis conversion and Unit (VELOCITY if possible)
  define double view%convert[3] /global
  define charac view%unit3*12 /global
endif
if (.not.exist(view%do%write)) then
  define logical view%do%write /global
  let view%do%write no
endif
greg1\set expand view%expand ! Otherwise characters get too big
!
let view%root &1 /upper
!
if ((page_x.ne.30).or.(page_y.ne.21)) then
  greg1\set plot landscape
  say "VIEW: ensure a landscape plot page"
endif
!
if exist(popup) delet /var popup
!
! If re-entering, just view again
if (.not.view%first) then
  !
  @ p_axes &1
  !
  if .not.exist(&1__first) then
   define integer &1__first &1__last /global
   define real &1__size[2] /global
   let &1__first -1
   let &1__size -1
  endif
  !
  if ((&1%dim[3].gt.1).and.((first.ne.last).or.(first.eq.0))) then
    !
    ! 3-D Case
    define char*3 ch
    let ch '&1%x_axis''&1%y_axis''&1%f_axis' 
    if (view%order.ne.ch) then  
      ! Axis ordering has been changed, reset all plotting limits
      message W VIEW "Resetting Ranges and Limits "
      let view%range 0
      ! let view%current%frange 0
      let view%ulimit 0
      let view%order 'ch'
      let view%status%szoom no
      let view%status%vzoom no
      let view%do%flux yes
      let view%do%extrema yes
      if exist(preview) then
        if exist(preview%found) delete /var preview%found
        if exist(preview%nfound) let preview%nfound 0
      endif
      poly /reset
    endif
    let view%do%extrema 'has_changed'
    ! These things should also be set in case of change of view%root...
    if ((&1__first.ne.first).or.(&1__last.ne.last).or.(view%root.ne.view%previous)) then
      let view%do%extrema yes
      let view%do%flux yes
      let view%do%window yes
      let view%do%line yes
      if exist(preview) then
        if exist(preview%found) delete /var preview%found
        if exist(preview%nfound) let preview%nfound 0
      endif
    endif
    if ((&1__size[1].ne.size[1]).or.(&1__size[2].ne.size[2])) then
      let view%do%flux yes
    endif
    !
    if (view%order.ne."123").and.(view%order.ne."213") then
      say 'ansi%red'"W-VIEW,  Data cube is not a LMV or MLV cube, trying anyway..."'ansi%none'
    endif
    !
    @ get_plane 'view%root'
    if (view%do%flux) then
      @ get_corner 'view%root'
    else
      @ get_corner "plot"
    endif
    @ view 'view%root'
    if (do_loop) then
      message I VIEW "Click H for HELP"
      @ loop
    endif
    let &1__first first
    let &1__last last
    let view%status%rspe no ! Change it
    let view%previous 'view%root'
  else
    ! 2-D Case - Fall back on SHOW display
    let old_side show_side /new logical
    let show_side do_loop
    @ p_lmv_map 'view%root' 0 &2 &3
    let show_side old_side
  endif
  let &1__size size
  !
  return
endif
!
let view%do%line yes
!
@ window_tools
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
! General purpose procedures
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
begin procedure view-cross
  if (cross.eq.0) return
  !
  if (box%bunit.eq."Rad") return
  !
  ! In SEC so far
  greg1\draw relo 0 cross*sec /user
  greg1\draw line 0 -cross*sec /user
  greg1\draw relo cross*sec 0 /user
  greg1\draw line -cross*sec 0 /user
end procedure view-cross

begin procedure sub_good_box
  @ p_box label &1
  if pro%narg.eq.2 then
    label 'box%legendx' /X
    label 'box%legendy' /Y
  endif
end procedure sub_good_box
!
begin procedure sub_box
  !
  ! Define the box positions
  define integer ibox
  let ibox &2
  !
  let inter 0
  define real ir0 ir1 ir2 ir3
  let ir0 0.125    ! Left margin
  let ir1 0.625   !  Right margin of left box
  let ir2 0.775   ! Left edge of right box
  let ir3 1.325   ! Right eddge of right box
  !
  let aspect_ratio no
  if (ibox.eq.view%area).or.(ibox.eq.view%channel) then         ! Integrated area or Channel
    ! This should only happen if both axis are similar, i.e. in case it is a Projection
    ! information.
    if (&1%x_axis*&1%y_axis.eq.2) then
      let aspect_ratio yes
      let aspect abs(((itrc[1]-iblc[1]+1)*&1%convert[3,1])/((itrc[2]-iblc[2]+1)*&1%convert[3,2]))
      if (aspect.lt.0.1.or.aspect.gt.10) then
        ! message W VIEW "box aspect ratio > 10: ignored"
        let aspect 1.0
      endif
    endif
    if (ibox.eq.view%area) then
      let position ir0 ir1  0.075 0.49      !! 0.17 0.72 0.075 0.49
    else if (ibox.eq.view%channel) then    ! Local Channel
      let position ir0 ir1  0.54 0.955      !! 0.17 0.72 0.54 0.955
    endif
  else if (view%nbox.eq.4) then
    let aspect_ratio no
    if (ibox.eq.view%mean_h) then    ! Mean spectrum
      let position ir2 ir3  0.075 0.49  !! 0.86 ir3 0.075 0.49
    else if (ibox.eq.view%spec_h) then    ! Current pixel spectrum
      let position ir2 ir3 0.54 0.955   !! 0.86 ir3 0.54 0.955
    else if (ibox.eq.view%mean_w) then    ! Current pixel spectrum
      let position ir2 ir3 0.075 0.49
    else if (ibox.eq.view%spec_w) then  ! Wide version
      let position ir2 ir3 0.54 0.955
    endif
  else
    let aspect_ratio no
    let m 0.020 /new real
    if (ibox.eq.view%mean_h) then    ! Mean spectrum
      let position ir2 ir3  0.075 0.2825-m
    else if (ibox.eq.view%mean_w) then    ! Mean spectrum
      let position ir2 ir3  0.2825+m 0.49
    else if (ibox.eq.view%spec_h) then    ! Current pixel spectrum
      let position ir2 ir3 0.54 0.7475-m
    else if (ibox.eq.view%spec_w) then    ! Wide version
      let position ir2 ir3  0.7475+m 0.955
    endif
  endif
  @ window_xy 1 1 1
  !
  let view%boxes[ibox] 'box_xmin' 'box_xmax' 'box_ymin' 'box_ymax'
  !
end procedure sub_box
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
begin procedure get_corner
  !
  @ p_corner   'view%root' center size
  !
  let do_pol .not.exist(poly%nxy) /new logical
  if (.not.do_pol) let do_pol poly%nxy.lt.3
  !
  if (do_pol) then
    define real my_pol[4,2]
    let my_pol[1] rtrc[1] rtrc[1] rblc[1] rblc[1]
    let my_pol[2] rtrc[2] rblc[2] rblc[2] rtrc[2]
    !
    greg2\polygon my_pol /var
  endif
  if ("&1none".eq."plotnone") then
     gtvl\change directory <greg<channel
     greg2\polygon /plot
     gtvl\change directory <greg<area
     greg2\polygon /plot
!!     sic wait 1 ! Time to see it ?...
  endif
  !
end procedure get_corner
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
begin procedure get_plane
  !! pause "Calling GET_PLANE &1 &2 &3"
  !
  ! Reset full image (What does that mean ???)
  !
  define character dummy*32
  let dummy '&1%unit'"none"
  if (dummy.eq."none") then
    if (view%do%write) then
      MESSAGE R VIEW "Please enter data cube unit"
      let &1%unit
    else
      message W VIEW  "Warning, no data cube unit"
    endif
  endif
  delete /var dummy
  if (&1%ndim.ne.3) then
    message E VIEW "Input image is not a 3D cube"
    return base
  endif
  if ((&1%unit3.eq."velocity").or.(&1%unit3.eq."VELOCITY")) then
    let view%convert &1%convert[3]
    let view%unit3 "VELOCITY"
  else if ((&1%unit3.eq."frequency").or.(&1%unit3.eq."FREQUENCY")) then
    message W VIEW "3rd axis is Frequency"
    !
    ! Change the axis temporarily to Velocity
    let view%convert[3] &1%velres
    let view%convert[2] (&1%restfre-&1%convert[2,3])/&1%restfre*299792.458+&1%veloff
    let view%convert[1] &1%convert[1,3]
    let view%unit3 "VELOCITY"
  else
    message W VIEW  "3rd axis is not Velocity or Frequency, but "'&1%unit3'
    let view%convert &1%convert[3]
    let view%unit3 '&1%unit3'
  endif
  if (view%convert[3].eq.0) then
    message E VIEW "3rd axis increment is equal to 0.0"
    return base
  endif
  !
  ! Find out the channel range if specified by RANGE
  !
  let miplane 1 &1%dim[3]
  if (range[1].ne.0.or.range[2].ne.0) then
    define integer i1 i2
    let i1 1
    let i2 2
    if (range[1].gt.range[2]) then
      if (view%convert[3].gt.0) then
        let i1 2
        let i2 1
      endif
    else if (view%convert[3].lt.0) then
      let i1 2
      let i2 1
    endif
    let miplane[1] (range[i1]-view%convert[2])/view%convert[3]+view%convert[1]
    let miplane[2] (range[i2]-view%convert[2])/view%convert[3]+view%convert[1]
    let miplane[1] max(1,miplane[1])
    let miplane[2] min(&1%dim[3],miplane[2])
    !
    ! Protect against bad input ranges
    if miplane[1].gt.miplane[2] then
      message W VIEW "Invalid input range " range[1] range[2]  /format a F13.2 F13.2 a
      let miplane 1 &1%dim[3]
      if (view%convert[3].gt.0) then
        let range (miplane-view%convert[1])*view%convert[3]+view%convert[2]
      else
        let range[2] (miplane[1]-view%convert[1])*view%convert[3]+view%convert[2]
        let range[1] (miplane[2]-view%convert[1])*view%convert[3]+view%convert[2]
      endif
    endif
  endif
  !
end procedure get_plane
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
begin procedure view
  !
  ! Does not anymore change window position on purpose to ease comparison
  ! of two sessions
  !
  gtvl\change directory <greg
  gtvl\clear directory
  !
  greg1\limits sblc[1] strc[1] sblc[2] strc[2] 'box%bunit' 
  !
  define real rlimit[3] rmin rmax
  define integer imin imax ixy mxy ix iy ibox ocent irmin irmax
  let ixy &1%dim[3] ! Always use the full stuff
  if (ixy.ne.view%old%ixy) then
    delete /var velocities
    define real velocities[ixy] /global
    let view%old%ixy ixy
  endif
  let mxy miplane[2]-miplane[1]+1
  if (mxy.ne.view%old%mxy) then
    delete /var xspectre cspectre mspectre
    define real xspectre[mxy] cspectre[mxy] mspectre[mxy] /global
    let view%old%mxy mxy
  endif
  ! Ranges
  define double frange[2] vrange[2] nrange[2] wrange[2] irange[2]! Frequencies, Velocities, Narrow and Wide, Channel
  define double dv vlimit[3]
  !
  ! Definition of used velocity range
  !
  let velocities[ichan] (ichan-view%convert[1])*view%convert[3]+view%convert[2]
  let vrange[1] min(velocities['miplane[1]'],velocities['miplane[2]'])
  let vrange[2] max(velocities['miplane[1]'],velocities['miplane[2]'])
  let dv (vrange[2]-vrange[1])*0.02
  let vrange[1] vrange[1]-dv
  let vrange[2] vrange[2]+dv
  !
  ! Get the Frequency range
  if (&1%spec.ne.0.and.&1%f_axis.eq.3) then
    if (&1%restfre.gt.0) then
      !  let frange (vrange-&1%convert[2,3])*&1%freqres/&1%convert[3,3]+&1%restfre
      !  Use more general formula (does not assume that restfre == reference pixel)
      let frange -(vrange-&1%veloff)*&1%restfre/299792.458+&1%restfre
      let view%current%fmin min(frange[1],frange[2])
      let view%current%fmax max(frange[1],frange[2])
      let view%current%frange frange
      !
    else
      let frange vrange
    endif
  else
    let frange vrange
  endif
  !
  ! And the spectrum
  let xspectre velocities['miplane[1]':'miplane[2]']
  !
  ! Definition of selected velocity channel
  !
  let vlimit view%ulimit
  if (view%ulimit[1].eq.0.and.view%ulimit[2].eq.0) then
    let vlimit[1] velocities['miplane[1]']
    let vlimit[2] velocities['miplane[2]']
  endif
  if (view%ulimit[3].eq.0) then
    let vlimit[3] (vlimit[1]+vlimit[2])/2
  endif
  let rlimit (vlimit-view%convert[2])/view%convert[3]+view%convert[1]
  let rlimit max(miplane[1],rlimit)
  let rlimit min(rlimit,miplane[2])
  compute rmin min rlimit[1:2]
  compute rmax max rlimit[1:2]
  let imin rmin
  let imax rmax
  let view%current%plane rlimit[3]
  let view%current%velo  vlimit[3]
  !
  ! Reset the ULIMIT to this boundary, just in case, or do Nothing ?
  !
  if (&1%spec.ne.0.and.&1%f_axis.eq.3) then
    ! let view%current%freq  (view%current%plane-&1%convert[1,3])*&1%freqres+&1%restfre
    ! Use more general formula (does not assume that restfre == reference pixel)
    let view%current%freq -(view%current%velo-&1%veloff)*&1%restfre/299792.458+&1%restfre
    say " Channel " view%current%plane   view%current%velo  view%current%freq /format A I6 F10.2 F14.3
  else
    say " Channel " view%current%plane   view%current%velo  /format A I6 F10.2
  endif
  !
  ! Definition of selected pixel
  !
  if (view%current%pixel[1].le.0) then
    let ix (&1%dim[1]+1)/2
  else
    let ix min(&1%dim[1],view%current%pixel[1])
  endif
  if (view%current%pixel[2].le.0) then
    let iy (&1%dim[2]+1)/2
  else
    let iy min(&1%dim[2],view%current%pixel[2])
  endif
  !
  ! Kill or Unkill selected pixel when asked
  !
  if (view%status%kill) then
    let &1[ix,iy,] &1%blank[1]
    let view%do%flux yes
    let view%do%window yes
    let view%do%extrema yes
    let view%status%kill no
  else if (view%status%unkill) then
    let &1[ix,iy,] b[ix,iy,] !What is B ?
    let view%do%flux yes
    let view%do%window yes
    let view%do%extrema yes
    let view%status%unkill no
  endif
  if (view%do%extrema) then
    !
    ! Fast code using compact actions
    say "Computing extrema" /noadvance
    compute view%current%min min &1['iblc[1]':'itrc[1]','iblc[2]':'itrc[2]','miplane[1]':'miplane[2]'] /blank &1%blank[1] &1%blank[2]
    compute view%current%max max &1['iblc[1]':'itrc[1]','iblc[2]':'itrc[2]','miplane[1]':'miplane[2]'] /blank &1%blank[1] &1%blank[2]
    if (any(iblc.eq.1).and.any(itrc.eq.1)) then
      greg2\rgdata &1 /var
    else
      greg2\rgdata &1['iblc[1]':'itrc[1]','iblc[2]':'itrc[2]','miplane[1]'] /var
    endif
    say "... done"
    !
    view%chan%min = view%current%min
    view%chan%max = view%current%max
    let true_scale view%chan%min view%chan%max
    if (color[3].ne.0) @ p_color
  endif
  !
  ! Integrated image
  !
  if (view%do%window) then
    if exist(view_area) then
      delete /var view_area
    endif
    define image view_area * real /like &1[1] /global
    let view_area% &1%
    let view_area%convert[3,3] (imax-Imin+1)*&1%convert[3,3]
    let view_area%freqres      (imax-Imin+1)*&1%freqres
    let view_area%velres       (imax-Imin+1)*&1%velres
    view_area%convert[2,3] = ((imin+imax)/2-&1%convert[1,3])*&1%convert[3,3]+&1%convert[2,3]
    view_area%convert[1,3] = 1.0
    !
    let view_area 0
    !
    ! Fast code using compiled action
    say "Computing AREA "'imin'" "'imax'
    if  &1%blank[2].ge.0 then
      compute view_area sum &1[imin:imax] /blank &1%blank[1] &1%blank[2]
      if (view%convert[3].ne.0.0) then
        let view_area view_area*abs(view%convert[3]) /where abs(view_area-&1%blank[1]).gt.&1%blank[2]
      endif
    else
      compute view_area sum &1[imin:imax]
      if (view%convert[3].ne.0.0) then
        let view_area view_area*abs(view%convert[3])
      endif
    endif
    say " ... done"
    let view%do%window no
  endif
  !
  ! Compute local extrema
  if (view%do%extrema) then
    if .not.exist(area_max) then
      define real area_max area_min /global
    endif
    if (size(view_area).ne.1) then
      compute area_min min view_area['iblc[1]':'itrc[1]','iblc[2]':'itrc[2]'] /blank &1%blank[1] &1%blank[2]
      compute area_max max view_area['iblc[1]':'itrc[1]','iblc[2]':'itrc[2]'] /blank &1%blank[1] &1%blank[2]
    else
      area_min = view_area*0.95
      area_max = view_area*1.05
    endif
    !
    ! This test is UNCLEAR
    if ((view%current%area_range[1].eq.0).and.(view%current%area_range[2].eq.0)) then
      let view%current%area_range[1] area_min
      let view%current%area_range[2] area_max
    endif
    let view%do%extrema no
    !
    ! Should adjust it to have same Zero as All channels
    !
    ! Treat round-off issues
    if (area_max.gt.0) then
      if (abs(area_min/area_max).lt.1E-3) let area_min = 0.
    else
      if (abs(area_max/area_min).lt.1E-3) let area_max = 0.
    endif
    !
    VIEW%INTE%MIN = area_min
    VIEW%INTE%MAX = area_max
    !
    ! Place the Zero at same colour than in Current channel display
    if (area_min.ne.0) then
      if (abs(area_max/area_min).gt.abs(view%current%max/view%current%min)) then
        view%inte%min = view%current%min*area_max/view%current%max
      else
        view%inte%max = view%current%max*area_min/view%current%min
      endif
    else
      view%inte%min = view%current%min*area_max/view%current%max
    endif
  endif
  !
  ! Plot Box 1 (Integrated image)
  gtvl\change directory <greg
  let ibox view%area
  gtvl\create directory 'view%names[ibox]'
  gtvl\change directory 'view%names[ibox]'
  @ sub_box 'view%root' 'ibox'
  define real bound[4]
  let bound (0.5-&1%convert[1,1])*&1%convert[3,1]+&1%convert[2,1] -
            (&1%dim[1]+0.5-&1%convert[1,1])*&1%convert[3,1]+&1%convert[2,1] -
            (0.5-&1%convert[1,2])*&1%convert[3,2]+&1%convert[2,2] -
            (&1%dim[2]+0.5-&1%convert[1,2])*&1%convert[3,2]+&1%convert[2,2]
  if (view%do%mask) then
    greg2\rgdata view_area /var /subset iblc[1] iblc[2] itrc[1] itrc[2]
    greg1\limits /rg
    greg2\plot /scal lin VIEW%INTE%min VIEw%INTE%max
    greg2\levels 'view%current%area_range[1]' 'view%current%area_range[2]'
    greg2\rgmap quiet /abs 1.0
    greg1\limits sblc[1] strc[1] sblc[2] strc[2] 'box%bunit'  ! seconds
    greg2\wedge right /levels
  else
    !
    ! Never contour the Integrated Area image
    greg2\plot view_area /bound bound[1] bound[2] bound[3] bound[4] /scal lin VIEW%INTE%min  VIEw%INTE%max
    greg2\wedge right
  endif
  !
  @ view-cross 'view%root'  ! Draw the cross if needed
  !
  @ view-over ! Overlay
  ! Execute User specified Overlay
  if (exist(view%overlay)) execute 'view%overlay'
  !
  if (&1%f_axis.eq.3) then
    greg1\draw text 4.5 0 "Area ("'&1%unit'".km/s)" 5 90 /CHAR 6
  else
    greg1\draw text 4.5 0 "Area ("'&1%unit'")" 5 90 /CHAR 6
  endif
  if (exist(poly%nxy)) then
    if (poly%nxy.gt.3) then
      greg2\polygon /plot
    endif
  endif
  !
  @ sub_good_box &1 YES 
  ! end integrated area
  !=====================================================================
  !
  ! Selected velocity channel
  !
  gtvl\change directory <greg
  let ibox view%channel
  gtvl\create directory 'view%names[ibox]'
  gtvl\change directory 'view%names[ibox]'
  @ sub_box 'view%root' 'ibox'
  @ view-cross 'view%root' 
  if (view%contour) then
    greg2\rgdata &1[view%current%plane] /var !!  view_area /var /subset iblc[1] iblc[2] itrc[1] itrc[2]
    greg2\rgmap quiet /abs 1
  else
    greg2\plot &1[view%current%plane] /scal lin view%chan%min view%chan%max
    greg2\wedge right
    !
    @ view-over ! Overlay Continuum
  endif
  ! Execute User specified Overlays
  if (exist(view%overlay)) execute 'view%overlay'
  !
  @ sub_good_box &1 ! NO 
  ! end velocity channel
  !=====================================================================
  if (show_color.ne.0)  @ p_color 'show_color'
  !
  ! Current values
  define logical doflux
  let doflux no
  let view%jyperk 0
  if (&1%major.ne.0) then
    define character u_unit*12
    let u_unit '&1%unit' /upper
    let doflux u_unit.eq."JY/BEAM"
    !exa u_unit
    !exa &1%unit
    delete /var u_unit
    if (doflux) then
      let view%jyperk &1%major*&1%minor/4./log(2.0)
      let view%jyperk 2.0*1.38e3*pi*view%jyperk|(2.99792458e8|&1%restfre*1e-6)^2
    endif
!!    if (&1%f_axis.ne.3) let doflux no ! SG
  endif
  !
  ! Display of coordinates and values
  if (view%side.and.do_loop) then
    ! Standard "in page" label
    greg1\draw text 4.5 0 "Flux ("'&1%unit'")" 5 90 /CHAR 6
    !
    ! Side window display or Menu
    @ side
    define character string*16
    !
    if (exist(menu)) then
!!      PAUSE "Panel creation"
      !
      ! This is not nice - MANY issues
      ! 1) text appear only if a LET command is present
      ! 2) text is centered, instead of being left adjusted
      ! 3) the first text has an additional "hide the others" button
      ! which we cannot suppress
      ! 4) There is a bug which make the "Channel" line blank if it does not start with a space
      ! 5) The panel is re-created each time
      ! 6) The panel position cannot be controlled at all,
      ! and 7) worse, it does not stay in place at re-creation
      gui\panel "View panel" no-help.txt
      sic\let name 'name' /prompt "File name "
      say " "
      say " Image values :"  ! Left adjusted, with special "hide the rest" button
      say " Velocity " view%current%velo   " km/s"  /format A12 F16.3 A12
      say " Channel " view%current%plane  "   ."  /format A12  I16  A12  s
      if (&1%spec.ne.0) then
        say " Frequency " view%current%freq " MHz" /format A12 F16.3 A12
      endif
!!      say "Velocity " rx   "    ."  /format A12 F16.3 A12
!!      say " Channel  " 1.0*view%current%plane  " number"  /format A12 F16.0  A12
      ! Pixel  (ix,iy)
      say "Pixel " "("'ix'","'iy'")"  " "  /format A12 A16 A12
      @ get-offset &1 'ix' 'iy' 
      say "Offset "  "("'view%cx'","'view%cy'") "'box%bunit' /format A12 A16 A12
      
      ! Intensity    ("'&1%unit'")"
      say "Value " &1[ix,iy,view%current%plane] " ("'&1%unit'")" /format A12 1PG16.3 A12
      if (doflux) then
        say "Value " &1[ix,iy,view%current%plane]/view%jyperk " (K)" /format A12 1PG16.3 A12
      endif
      gui\go
    else
      !
      ! Graphic window version
      @ p_side_display &1 'ix' 'iy' view%current 'doflux'
      greg1\set expand view%expand
    endif
    ! Clean-up
    gtvl\change direc <greg
  else
    !
    ! Standard "in page" label
    greg1\draw text 4.5 0 "Channel "'view%current%plane'"     Flux ("'&1%unit'")" 6 90 /CHAR 3
    !
    ! Write the alternate Frequency axis
    !! greg1\draw text 5.7 0 "Channel "'view%current%plane' 5 90 /CHAR 6
    if (&1%spec.ne.0) then
      greg1\draw text 5.8 0 '0.01*nint(100*view%current%velo)'" km/s"  6 90 /CHAR 3
      define character string*16
      let string view%current%freq /format F16.3
      greg1\draw text 5.8 0 'string'" MHz"  4 90 /CHAR 9
      delet /var string
    endif
  endif
  ! end  display current values
  !=====================================================================
  !
  ! Plot: Mean spectrum, narrow bandwidth
  !
  gtvl\change directory <greg
  let ibox view%mean_h
  gtvl\create directory 'view%names[ibox]'
  gtvl\change directory 'view%names[ibox]'
  @ sub_box 'view%root' 'ibox'
  if (view%do%mask) then
    define integer local_mask /like view_area
    let local_mask 1
    let local_mask 0 /where view_area.ge.view%current%area_range[1].and.view_area.le.view%current%area_range[2]
  endif
  !
  if (view%do%flux) then
    if (view%do%mask) then
      ! Fast code using compiled action..
      SAY "Using SPECTRUM command -- With Mask"
      if (doflux) then
        spectrum mspectre &1 local_mask /corner 'iblc[1]' 'itrc[1]' 'iblc[2]' 'itrc[2]' -
          /plane miplane[1] miplane[2] /sum
      else
        spectrum mspectre &1 local_mask /corner 'iblc[1]' 'itrc[1]' 'iblc[2]' 'itrc[2]' -
          /plane miplane[1] miplane[2] /mean
      endif
    else
      ! Fast code using compiled action
      SAY "Using SPECTRUM command -- no mask"
      if (doflux) then
        spectrum mspectre &1 /corner 'iblc[1]' 'itrc[1]' 'iblc[2]' 'itrc[2]' -
          /plane miplane[1] miplane[2] /sum
      else
        spectrum mspectre &1 /corner 'iblc[1]' 'itrc[1]' 'iblc[2]' 'itrc[2]' -
          /plane miplane[1] miplane[2] /mean
      endif
    endif
    if (doflux) then
      ! Convert to flux density
      let mspectre mspectre|pi|&1%major|&1%minor*4*log(2)
    endif
    let view%do%flux no
  endif
  !
  ! Velocity / Channel - Plane / Frequency axis
  let wrange vrange  ! Save Wide range
  if all(view%range.eq.0) then
    let nrange wrange
  else
    let nrange view%range
  endif
  let vrange nrange
  !
  if (&1%f_axis.ne.3) let view%status%rspe = yes
  let irange  (vrange-view%convert[2])/view%convert[3]+view%convert[1]
  ! This may be already displaced 
  let irmin min(irange[1],irange[2])
  let irmin max(1,irmin-miplane[1]+1)
  let irmax max(irange[1],irange[2])
  let irmax min(mxy,irmax-miplane[1]+1)        ! This may be already displaced 
  if (irmax.lt.irmin) let irmin irmax
  !
  if (view%status%rspe) then
!!    greg1\limits irange[1] irange[2] * * /var xspectre mspectre
    greg1\limits irange[1] irange[2] * * /var xspectre[irmin:irmax] mspectre[irmin:irmax]
    greg1\box p n
    if (&1%f_axis.eq.3) then
      greg1\label "(channel number)" /X
    else
      greg1\label "("'view%unit3'")" /X
    endif
  else
!!    greg1\limits vrange[1] vrange[2]  * * /var xspectre mspectre
    greg1\limits vrange[1] vrange[2] * * /var xspectre[irmin:irmax] mspectre[irmin:irmax]
    greg1\box p n
    greg1\label "Velocity (km.s\\u-1\\d)" /X
  endif
  greg1\axis yr /label o
  greg1\limits vrange[1] vrange[2]  = = !! /var xspectre mspectre
  if view%nbox.eq.6 then
    let ocent 9
  else
    let ocent 6
  endif
  !
  if (doflux) then
    if (&1%f_axis.eq.3) then    
      greg1\draw text 3 0 "Integrated Flux (Jy)" 5 90 /char ocent
    else
      greg1\draw text 3 0 "Mean Profile ("'&1%unit'")" 5 90 /char ocent
    endif
  else
    greg1\draw text 3 0 "Mean Spectrum ("'&1%unit'")" 5 90 /char ocent
  endif
  !
  ! Shaded histogram in defined velocity range
  define integer kxy
  let kxy imax-imin+1
  define real vv[kxy] ss[kxy]
  let vv velocities[imin:imax]
  define integer jmin jmax
  let jmin imin-miplane[1]+1
  let jmax imax-miplane[1]+1
  let ss mspectre[jmin:jmax]
  greg1\histogram vv ss /fill 5 /base 0
  !
  ! Compute integrated flux
  define real tflux
  define charac cflux*12
  compute tflux sum ss
  if (imax.gt.1) then
    let tflux tflux*abs(velocities[imax]-velocities['imax-1'])
  else
    let tflux tflux*abs(velocities[imin]-velocities['imin+1'])
  endif
  !
  ! To set the integrated area bandwidth
  let view%current%width velocities[imax]-velocities[imin]
  let view%current%vcent (velocities[imax]+velocities[imin])/2.0
  !
  let cflux tflux /format 1PG11.3
  if (doflux) then
    greg1\draw text 0 -1 'cflux'" (Jy.km/s)" 5 0 /char 8
  else
    if (&1%f_axis.eq.3) then
      greg1\draw text 0 -1 'cflux'" ("'&1%unit'".km/s)" 5 0 /char 8
    else
      greg1\draw text 0 -1 'cflux'" ("'&1%unit'")" 5 0 /char 8
    endif
  endif
  !
  greg1\histogram xspectre mspectre
  !
  let vrange wrange ! Back to Wide Range
  !
  if (view%nbox.gt.4) then
    ! Low resolution version of the Mean spectrum
    gtvl\change directory <greg
    let ibox view%mean_w
    gtvl\create directory 'view%names[ibox]'
    gtvl\change directory 'view%names[ibox]'
    @ sub_box 'view%root' 'ibox'
    !
    greg1\limits wrange[1] wrange[2]  * * /var xspectre mspectre
    ! Shaded histogram in defined velocity range
    greg1\histogram vv ss /fill 5 /base 0
    ! Normal histogram
    greg1\histogram xspectre mspectre
    !
    greg1\box n n
    greg1\axis yr /label o
    if (view%nbox.gt.4) then
      greg1\axis xl
    else
      greg1\axis xu /label p
    endif
    !
    ! Vertical lines for expanded spectrum
    greg1\pencil 3
    greg1\draw relo nrange[1] user_ymax /user
    greg1\draw line nrange[1] user_ymin /user
    gtvl\change dir <greg<'view%names[view%mean_h]'
    greg1\draw line nrange[1] user_ymax /user
    !
    gtvl\change dir <greg<'view%names[view%mean_w]'
    greg1\draw relo nrange[2] user_ymax /user
    greg1\draw line nrange[2] user_ymin /user
    gtvl\change dir <greg<'view%names[view%mean_h]'
    greg1\draw line nrange[2] user_ymax /user
    greg1\pencil 0
    !
  endif
  !
  delete /var vv ss
  ! end mean spectrum
  !=====================================================================
  !
  ! Plot Spectrum corresponding to selected pixel
  !
  gtvl\change directory <greg
  let ibox view%spec_h
  gtvl\create directory 'view%names[ibox]'
  gtvl\change directory 'view%names[ibox]'
  @ sub_box 'view%root' 'ibox'
  !
  let cspectre &1[ix,iy,'miplane[1]':'miplane[2]']
  !
  ! Velocity / Channel - Plane / Frequency axis
  let vrange nrange
  if (view%nbox.eq.6) then
!!    greg1\limits vrange[1] vrange[2] * * /var xspectre cspectre
    greg1\limits vrange[1] vrange[2] * * /var xspectre[irmin:irmax] cspectre[irmin:irmax]
  else
    greg1\limits vrange[1] vrange[2] view%current%min view%current%max
  endif
  !
  if (&1%f_axis.ne.3) let view%status%rspe = yes
  if (view%status%rspe) then
!!    let irange  (vrange-view%convert[2])/view%convert[3]+view%convert[1]
    greg1\limits irange[1] irange[2] = =
    greg1\axis xl
    greg1\axis xu
  else
    if (&1%spec.ne.0.and.&1%f_axis.eq.3) then
      if (&1%restfre.gt.0) then
        !  let frange (vrange-&1%convert[2,3])*&1%freqres/&1%convert[3,3]+&1%restfre
        !  Use more general formula (does not assume that restfre == reference pixel)
        let frange -(vrange-&1%veloff)*&1%restfre/299792.458+&1%restfre
      else
        let frange vrange
      endif
    else
      let frange vrange
    endif
    greg1\limits frange[1] frange[2] = =   !Frequency
    greg1\axis xl
    greg1\axis xu
  endif
  if (view%jyperk.ne.0) then
    ! Right axis
    greg1\limits = = user_ymin|view%jyperk user_ymax|view%jyperk  !Frequency
    if view%nbox.eq.6 then
      greg1\draw text +3 0 "T\\dmb\\u (K)" 5 90 /char 9
    else
      greg1\draw text +3 0 "T\\dmb\\u (K)" 5 90 /char 6
    endif
    greg1\axis yr /label o
    greg1\limits = = user_ymin*view%jyperk user_ymax*view%jyperk  !Frequency
  else
    greg1\axis yr /label n
  endif
  !
  ! Back to velocity & flux
  greg1\limits vrange[1] vrange[2] = =
  greg1\axis yl /label o    ! Left axis
  !
  ! Write down the selected pixel coordinates
  greg1\draw text -1 -1 "("'ix'","'iy'")" 1 /char 9
  @ get-offset &1 'ix' 'iy'
  greg1\draw text 1 -1 "("'view%cx'","'view%cy'")" 3 /char 7
  !
  ! Vertical line to indicate selected velocity channel
  if ((vlimit[3]-user_xmin)*(vlimit[3]-user_xmax).lt.0) then
    greg1\pencil 2
    greg1\draw relo vlimit[3] user_ymin /user
    greg1\draw line vlimit[3] user_ymax /user
    greg1\pencil 0
  endif
  greg1\histogram xspectre cspectre
  !
  ! Current spectum, wide bandwdith version
  if (view%nbox.gt.4) then
    ! Wide version of the current spectrum
    gtvl\change directory <greg
    let ibox view%spec_w
    gtvl\create directory 'view%names[ibox]'
    gtvl\change directory 'view%names[ibox]'
    @ sub_box 'view%root' 'ibox'
    !
    greg1\limits wrange[1] wrange[2]  view%current%min view%current%max /var xspectre cspectre
    greg1\histogram xspectre cspectre
    greg1\box n n n
    greg1\axis yl /label o  ! Left axis
    !
    ! Convert to Tb scale now, and back
    if (doflux) then
      greg1\limits = = user_ymin|view%jyperk user_ymax|view%jyperk
      greg1\axis yr /label o  !Right axis
      greg1\limits = = user_ymin*view%jyperk user_ymax*view%jyperk
    endif
    !
    ! Labeling in Frequency if possible
    if (&1%spec.ne.0.and.&1%f_axis.eq.3) then
      if (&1%restfre.gt.0) then
        !  let frange (vrange-&1%convert[2,3])*&1%freqres/&1%convert[3,3]+&1%restfre
        !  Use more general formula (does not assume that restfre == reference pixel)
        let frange -(wrange-&1%veloff)*&1%restfre/299792.458+&1%restfre
      else
        let frange wrange
      endif
    else
      let frange wrange
    endif
    greg1\limits frange[1] frange[2] = =
    greg1\axis xl
    greg1\axis xu
    !
    ! Plot spectral lines if any
    if (exist(preview%found)) then
      @ view-drawlines
    endif
    !
    greg1\limits wrange[1] wrange[2] = =
    !
    ! Vertical line for current channel
    greg1\pencil 2
    greg1\draw relo vlimit[3] user_ymin /user
    greg1\draw line vlimit[3] user_ymax /user
    !
    ! Vertical lines for expanded spectrum
    greg1\pencil 3
    greg1\draw relo nrange[1] user_ymax /user
    greg1\draw line nrange[1] user_ymin /user
    gtvl\change dir <greg<'view%names[view%spec_h]'
    greg1\draw line nrange[1] user_ymax /user
    !
    gtvl\change dir <greg<'view%names[view%spec_w]'
    greg1\draw relo nrange[2] user_ymax /user
    greg1\draw line nrange[2] user_ymin /user
    gtvl\change dir <greg<'view%names[view%spec_h]'
    greg1\draw line nrange[2] user_ymax /user
    greg1\pencil 0
    !
  endif
  !
  !
  ! Lines to indicate the selected pixel
  !
  ! Here, we use the "global" spectrum window, encompassing
  ! the High and Low resolution sub-boxes
  !
  ! a) Towards Channel
  define real bx[3] by[3]
  gtvl\change directory <greg<'view%names[view%spec_h]'
  greg1\draw relo user_xmin user_ymin /user
  let bx[1] x_pen
  let by[1] y_pen
  gtvl\change directory <greg<'view%names[view%channel]'
  greg1\draw relo (ix-&1%convert[1,1])*&1%convert[3,1]+&1%convert[2,1] -
            (iy-&1%convert[1,2])*&1%convert[3,2]+&1%convert[2,2] /user
  let bx[2] x_pen
  let by[2] y_pen
  if (view%nbox.gt.4) then
    gtvl\change directory <greg<'view%names[view%spec_w]'
  else
    gtvl\change directory <greg<'view%names[view%spec_h]'
  endif
  greg1\draw relo user_xmin user_ymax /user
  let bx[3] x_pen
  let by[3] y_pen
  gtvl\change dir <greg
  gtvl\create dir over
  gtvl\change dir over
  greg1\set box 0 page_x 0 page_y
  greg1\draw relo bx[1] by[1]
  greg1\draw line bx[2] by[2]
  greg1\draw line bx[3] by[3]
  !
  ! b) Towards Mean
  gtvl\change directory <greg<'view%names[view%mean_h]'
  greg1\draw relo user_xmin user_ymin /user
  let bx[1] x_pen
  let by[1] y_pen
  gtvl\change directory <greg<'view%names[view%area]'
  greg1\draw relo (ix-&1%convert[1,1])*&1%convert[3,1]+&1%convert[2,1] -
            (iy-&1%convert[1,2])*&1%convert[3,2]+&1%convert[2,2] /user
  let bx[2] x_pen
  let by[2] y_pen
  if (view%nbox.gt.4) then
    gtvl\change directory <greg<'view%names[view%mean_w]'
  else
    gtvl\change directory <greg<'view%names[view%mean_h]'
  endif
  greg1\draw relo user_xmin user_ymax /user
  let bx[3] x_pen
  let by[3] y_pen
  gtvl\change dir <greg<over
  greg1\set box 0 page_x 0 page_y
  greg1\draw relo bx[1] by[1]
  greg1\draw line bx[2] by[2]
  greg1\draw line bx[3] by[3]
  !
  ! c) back
  gtvl\change directory <greg
  greg1\draw relo 0 0
  !
  ! A default box to put the global labels now.
  let position 0.17 1.30 0.075 0.955
  let aspect_ratio no
  @ window_xy 1 1 1
  define character text*256
  let text "  \\iS:\\i "'&1%source'
  let text 'text'"  \\iL:\\i "'&1%line'
  let text 'text'"  "'1d-6*nint(&1%restfre*1000)'" GHz"
  define char vframe*20
  if (&1%vtype.eq.1) then
    let vframe "LSR"
  else if (&1%vtype.eq.2) then
    let vframe "Hel"
  else if (&1%vtype.eq.3) then
    let vframe "Obs"
  else if (&1%vtype.eq.4) then
    let vframe "Ear"
  else if (&1%vtype.eq.0) then
    let vframe "Unk"
  else
    let vframe "(not recognized)"
  endif
  if (&1%f_axis.eq.3) then
    let text 'text'" @ "'nint(&1%veloff*10)/10'" km/s "'vframe'
  else
    let text 'text'" plane "
  endif
  !
  if (&1%major.ne.0) then
    define double imajor iminor ipa
    if (&1%minor/sec.gt.1.0) then
      let imajor 0.1*nint(&1%major/sec*10)
      let iminor 0.1*nint(&1%minor/sec*10)
      let ipa nint(&1%pa*180.0/pi)
    else
      let imajor 0.01*nint(&1%major/sec*100)
      let iminor 0.01*nint(&1%minor/sec*100)
      let ipa nint(&1%pa*180.0/pi)
    endif
    if (&1%minor.eq.&1%major) then
      let text 'text'"  \\iB:\\i "'imajor'
    else
      let text 'text'"  \\iB:\\i "'imajor'" x "'iminor'" PA "'ipa'"^"
    endif
  endif
  !
  if exist(redshift) then
    if (redshift.ne.0) then
      let text 'text'"  \\iRedshift:\\i "'redshift'
    endif
  endif
  greg1\draw text -1.2 1 'text' 5 /char 8
  greg1\draw text -5.5 0 'header_name_type' 5 90 /char 4
  !
  if (view%do%line) then
    @ view-lines
    let view%do%line no
  endif
end procedure view
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
begin procedure view-help
  say " "
  say "Authors: J.Pety & S.Guilloteau (2003) - Revision 2018-2022 by S.Guilloteau"
  say "Position-independent actions:"
  say "   Press E key: EXIT loop"
  say "   Press H key: HELP display"
  say "   Press P key: PRINT plot in ""ha"" subdirectory"
  say "   Press Q key: QUIT loop"
  say "   Press X key: EXTRACT on disk current zoomed region"
  say "   Press N key: Toggle  Narrow - Wide mode "
  say "Position-dependent actions:"
  say "   Cursor on images:"
  say "      Left  clic: Display spectrum at pointed position"
  say "      Right clic: Define a polygon"
  say "      Press B key: BACK to full field of view"
  say "      Press C key: COORDINATES toggled from absolute to relative and back"
  say "      Press K key: KILL   pointed pixel"
  say "      Press M key: Display MASK if any"
  ! This cannot be used, as R is returned by default by Right Button
  ! say "      Press R key: Select range of values displayed in image"
  say "      Press S key: SLICE definition (velocity-position)"
  say "      Press U key: UNKILL pointed pixel"
  say "      Press V key: Display map coordinates at current position"
  say "      Press W key: WRITE Integrated Area image"
  say "      Press Y key: Select range of values displayed in image"
  say "      Press Z key: ZOOM defined spatial region"
  say "   Cursor on spectra:"
  say "      Left clic in Selected   Spectrum: Display selected velocity channel"
  say "      Left clic in Integrated Spectrum: Define velocity range"
  say "      Press B key: BACK to full velocity range"
  say "      Press C key: COORDINATES toggled from freq/velo to channels and back"
  say "      Press L key: LABEL spectral Lines"   ! This also obtained by Left Button (?)
  say "      Press M key: MOVIE"
  say "      Press W key: WRITE Integrated (and current) Spectrum"
  say "   Cursor outside plots:"
  say "      Press B key: BACK to full velocity range AND full field of view"
  say "      Press C key: Adjust color LUT"
  say "Known problems:"
  say "   1. Velocity range may be wrong when successively using VIEW on 2 different cubes"
  say " "
end procedure view-help
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
begin procedure loop
  !
  ! Main loop using Cursor input - define next action
  define integer ibox jbox jaction
  !
  for /while yes
    gtvl\change directory <greg
    greg1\draw relo
    !exa cursor_code
    let ibox 0
    for i 1 to view%nbox
      if ((x_pen.ge.view%boxes[1,i]).and.(x_pen.le.view%boxes[2,i])) then
        if ((y_pen.ge.view%boxes[3,i]).and.(y_pen.le.view%boxes[4,i])) then
          let ibox i
        endif
      endif
    next
    !
    ! First global behavior, then position-dependant behavior
    !
    !     exa cursor_code
    if ((cursor_code.eq."Q").or.(cursor_code.eq."E")) then
      return  ! Exit the loop and the procedure
    else if (cursor_code.eq."X") then
      let jaction 9   ! extract
    else if (cursor_code.eq."H") then
      let jaction 10  ! help
    else if (cursor_code.eq."N") then
      let jaction 16  ! Toggle Narrow / Wide mode
    else if (cursor_code.eq."P") then
      let jaction 13  ! Print
    else if ((ibox.eq.view%channel).or.(ibox.eq.view%area)) then
      ! Area and Channel map actions
      if (cursor_code.eq."C") then
        let angle_unit -angle_unit      ! Toggle relative coordinate!
        @ p_axes 'view%root'
        let jaction 11                  ! view again
      else if (cursor_code.eq."Z") then
        let view%status%szoom yes
        let jaction 7                   ! Zoom spatially
      else if (cursor_code.eq."B") then
        let view%status%szoom yes
        let jaction 8                   ! Unzoom spatially
      else if (cursor_code.eq."M") then
        let jaction 18   ! Display mask
      else if (cursor_code.eq."K") then
        if (view%do%write) then
          let view%status%kill yes
          let jaction view%default
        else
          say "KILL only possible in DO_WRITE mode"
          let jaction view%default
        endif
      else if (cursor_code.eq."U") then
        if (view%do%write) then
          let view%status%unkill yes
          let jaction view%default
        else
          say "UNKILL only possible in DO_WRITE mode"
          let jaction view%default
        endif
      else if (cursor_code.eq."S") then
        let jaction 5                    ! Slice
      else if (cursor_code.eq."Y") then
        let jaction 19                   ! Range of map values in colour scale
      else if (cursor_code.eq."L") then  ! undocumented
        if (view%do%mask) then           ! Toggle range/norange of colour scale
          let view%do%mask no
        else
          let view%do%mask yes
        endif
        let view%do%flux yes
        let jaction 11                   ! "view"
      else if (cursor_code.eq."*") then  ! Right mouse button
        if (view%do%mask) then
          let jaction 12                 ! mask
        else
          let jaction 1                  ! flux
        endif
      else if (cursor_code.eq."V") then
        let jaction 14                   ! value
      else if (cursor_code.eq."W") then
        let jaction 15 ! Write some of the files...
      else ! Default behavior
        let jaction view%default
      endif
    else if ((ibox.eq.view%mean_h).or.(ibox.eq.view%spec_h)) then
      ! Mean or Spectrum (high resolution)
      if (cursor_code.eq."C") then
        let view%status%rspe .not.view%status%rspe  ! Toggle Channel / Velocity
        let jaction 11                  ! view
      else if (cursor_code.eq."M") then
        let jaction 6   ! movie
      else if (cursor_code.eq."Z") then
        let view%status%vzoom yes
        let jaction 7                   ! zoom
      else if (cursor_code.eq."B") then
        let view%status%vzoom yes
        let jaction 8                   ! unzoom
      else if (cursor_code.eq."W") then
        let jaction 15  ! Write some of the files...
      else ! Default behavior
        let jaction ibox                ! view%Actions and view%Names match
      endif
    else if ((ibox.eq.view%mean_w).or.(ibox.eq.view%spec_w)) then
      ! Mean or Spectrum (wide band)
      if (cursor_code.eq."C") then
        let view%status%rspe .not.view%status%rspe  ! Toggle Channel / Velocity
        let jaction 11
      else if (cursor_code.eq."Z") then
        let view%status%vzoom yes
        let jaction 7
      else if (cursor_code.eq."B") then
        let view%status%vzoom yes
        let jaction 8
      else if (cursor_code.eq."L") then
        let jaction 17                  ! Label lines
      else if (cursor_code.eq."W") then
        let jaction 15                  ! Write some of the files...
      else if (cursor_code.eq."M") then
        let jaction 6   ! movie
      else ! Default behavior
        let jaction ibox-2  ! Beware that view%Actions and view%Names match properly
        !exa jaction
      endif
    else if (ibox.eq.0) then
      ! 0: outside plotting area
      if (cursor_code.eq."B") then      ! Unzoom
        let view%status%vzoom yes
        let view%status%szoom yes
        let jaction 8
      else if (cursor_code.eq."C") then
        let color[3] /Prompt "Enter color smoothing "
        @ p_color
        let jaction 0
      else ! Ignore ...
        let jaction 0
      endif
    else
      say "Should not be here: ibox = "'ibox'
    endif
    if (jaction.ne.0) then
      if (ibox.eq.0) then
        let jbox view%nbox
      else
        let jbox ibox
      endif
      say "Box "'ibox'" "'view%names[jbox]'";  Action "'view%actions[jaction]'
      ! Pass view%root as well
      @ view-'view%actions[jaction]' 'view%root' 'ibox' 'jaction'
    endif
  next
  !
end procedure loop
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
! Specific action procedures
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
begin procedure view-value
  !
  ! Draw current pixel value
  ! presumably, it is already guaranteed to be in the "Channel" or
  ! Area windows
  define integer test
  let test 0&2
  gtvl\change directory <greg<'view%names[test]'
  greg1\draw value * *
end procedure view-value
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
begin procedure view-channel
  !
  ! Select a new channel
  define integer test
  let test 0&2
  if (test.eq.0) then
     gtvl\change directory <greg<spectrum
     say "Select current channel"
     greg1\draw relo
  else
     gtvl\change directory <greg<'view%names[test]'
     greg1\draw relo * *
  endif
  let view%ulimit[3] use_curs[1]
  @ view 'view%root'
  !
end procedure view-channel
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
begin procedure view-view
  @ view 'view%root'
end procedure view-view
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
begin procedure view-flux
  !
  ! Compute integrated Flux
  define integer test
  let test 0&2
  if (test.eq.0) then
     gtvl\change directory <greg<area
  else
     gtvl\change directory <greg<'view%names[test]'
     greg1\draw relo * *
  endif
  say "Define polygon"
  greg2\polygon
  let view%do%flux yes
  @ view 'view%root'
  !
end procedure view-flux
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
begin procedure view-mask
  !
  ! Overlay the mask in the "area" and "channel" panels
  !
  ! This is obtained by Cursor M, in these panels
  !
  if .not.exist(mask) return
  !
  if (mask%dim[3].eq.1) then
    greg2\rgdata mask /var
    gtvl\change directory <greg<area
    greg2\levels 0.9
    greg2\rgmap quiet
    gtvl\change directory <greg<channel
    greg2\levels 0.9
    greg2\rgdata mask /var
    greg2\rgmap quiet
  else
    define image m_mask * real /like mask[1]
    ! I would need the current IRANGE and Channel
    compute m_mask sum mask['miplane[1]':'miplane[2]']
    let m_mask% mask%
    let m_mask 1 /where m_mask.ne.0
    gtvl\change directory <greg<area
    greg2\rgdata m_mask /var
    greg2\levels 0.9
    greg2\rgmap quiet
    !
    gtvl\change directory <greg<channel
    greg2\rgdata mask[view%current%plane] /var
    greg2\rgmap quiet
  endif
  !
  !
end procedure view-mask
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
begin procedure view-window
  !
  ! Select 3rd axis window to compute the integrated area
  define integer test
  let test 0&2
  ! We should use here the appropriate Window ...
  gtvl\change directory <greg<'view%names[&2]'
  if (test.eq.0) then
     say "Select lower limit"
     greg1\draw relo
  else
     greg1\draw relo * *
  endif
  let view%ulimit[1] use_curs[1]
  say "Set upper limit"
  greg1\draw relo
  let view%ulimit[2] use_curs[1]
  let view%do%window yes
  let view%do%extrema yes
  @ view 'view%root'
  !
end procedure view-window
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
begin procedure view-zoom
  !
  ! Either spatial or velocity zoom
  ! will need to be modified for the "browse" mode along 3rd axis
  !
  define integer test
  define double lrange[2]
  let test 0&2
  define logical local_loop
  let local_loop yes
  if (view%status%vzoom) then
    gtvl\change directory <greg<'view%names[test]'
    for /while local_loop
      say "Select lower limit"
      greg1\draw relo
      let lrange[1] use_curs[1]
      say "Set upper limit"
      greg1\draw relo
      let lrange[2] use_curs[1]
      if (lrange[1].ne.lrange[2]) then
        let local_loop no
      else
        say "Window size must be > 0.0."
      endif
    next
    if (view%nbox.eq.4) then
      ! Re-initialize with different velocity range
      let range lrange
      @ get_plane 'view%root'
    else
      !
      ! Change only the Narrow range
      let view%range lrange
    endif
    let view%do%flux yes
    let view%status%vzoom no
  else if (view%status%szoom) then
    @ get_szoom 'view%root' 'test'
  endif
  let view%do%extrema yes
  @ view 'view%root'
  !
end procedure view-zoom
!
begin procedure get_szoom
  !
  ! Spatial zoom definition
  !
  define integer trc[2] blc[2] pix_size[2] pix_cent[2]
  gtvl\change directory <greg<'view%names[&2]'
  define logical local_loop
  let local_loop yes
  for /while local_loop
    say "Select top, right corner"
    greg1\draw relo
    let trc pix_curs
    say "Select bottom, left corner"
    greg1\draw relo
    let blc pix_curs
    if ((blc[1].ne.trc[1]).and.(blc[2].ne.trc[2])) then
      let local_loop no
    else
      say "Area of zoom rectangle must be > 0.0."
      RETURN
    endif
  next
  !
  let pix_size (trc-blc)
  let pix_cent (trc+blc)/2
  let view%current%pixel pix_cent
  !
  let center &1%convert[2,1:2]+(pix_cent-&1%convert[1,1:2])*&1%convert[3,1:2]
  let size   abs(pix_size*&1%convert[3,1:2])
  let size size/box%aunit
  let center center/box%aunit
  !
  @ get_corner "plot"
  let view%do%flux yes
  let view%status%szoom no
end procedure get_szoom
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
begin procedure view-unzoom
  !
  ! 3 possibilities: velocity, spatial or both unzoom
  !
  if (view%status%vzoom) then
    let range 0
    let view%range 0
    @ get_plane 'view%root'
    let view%do%window yes
    let view%status%vzoom no
  endif
  if (view%status%szoom) then
    let size 0
    let center 0
    @ get_corner
    let view%status%szoom no
  endif
  let view%do%flux yes
  let view%do%extrema yes
  @ view 'view%root'
  !
end procedure view-unzoom
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
begin procedure view-spectrum
  !
  ! Select a new pixel to get the spectrum
  define integer test
  let test 0&2
  if (test.eq.0) then
     gtvl\change directory <greg<channel
     say "Select current spectrum"
     greg1\draw relo
  else
     gtvl\change directory <greg<'view%names[test]'
     greg1\draw relo * *
  endif
  let view%current%pixel pix_curs
  @ view 'view%root'
  !
end procedure view-spectrum
!
begin procedure view-wide
  !
  ! Toggle the Narrow / Wide mode
  if view%nbox.eq.4 then
    let view%names "area" "channel" "mean" "spectrum" "WMEAN" "WSPECTRUM" "outside" ! New order
    let view%nbox 6
  else
    let view%names[5] "outside" ! New order
    let view%nbox 4
  endif
  !
  for i 3 to 6
    @ sub_box dummy 'i'
  next
  @ get_plane 'view%root'
  @ get_corner
  @ view 'view%root'
end procedure view-wide
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
begin procedure view-slice
  !
  say " "
  say "Position-velocity diagram"
  say " "
  define integer test
  !
  let test 0&2
  if (test.eq.0) then
    gtvl\change directory <greg<channel
  else
    gtvl\change directory <greg<'view%names[test]'
  endif
  !
  define real slc[2,2]
  say "Select lower slice limit"
  greg1\draw relo
  let slc[1] use_curs
  say "Select upper slice limit"
  greg1\draw line
  let slc[2] use_curs
  display\slice &1 'slc[1,1]' 'slc[2,1]' 'slc[1,2]' 'slc[2,2]' RADIAN
  !
  gtvl\gtv search <slice
  if (.not.gtv%exist) then
    gtvl\create direct <slice /plot_page 20 20 /geometry 512 512
  endif
  gtvl\change dir <slice
  gtvl\clear dir
  greg1\set box square
  !
  greg1\limits /rgdata SLICED
  greg2\plot SLICED
  !
  greg1\set expand 1.0
  greg1\box n n n
  greg1\axis yl
  greg1\axis yr
  !
  greg1\axis xl /unit 'box%bunit'
  greg1\axis xu /unit 'box%bunit'
  greg1\label "Offset "'box%gunit' /X
  greg1\draw text -3 0 "Velocity (km.s\\u-1\\d)" 5  90 /char 4
  greg1\set expand view%expand
  !
  gtvl\change dir <greg
  !
  ! Restore appropriate Projection
  greg2\rgdata &1[view%current%plane] /var !!  view_area /var /subset iblc[1] iblc[2] itrc[1] itrc[2]
  !
end procedure view-slice
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
begin procedure view-movie
  !
  define integer ilast jlast wiplane[2]
  define real rwait
  !
  if (view%range[1].ne.0).or.(view%range[2].ne.0) then
    if (view%convert[3].gt.0) then
      let wiplane[1] (view%range[1]-view%convert[2])/view%convert[3]+view%convert[1]
      let wiplane[2] (view%range[2]-view%convert[2])/view%convert[3]+view%convert[1]
    else
      let wiplane[1] (view%range[2]-view%convert[2])/view%convert[3]+view%convert[1]
      let wiplane[2] (view%range[1]-view%convert[2])/view%convert[3]+view%convert[1]
    endif
    let wiplane[1] max(1,wiplane[1])
    let wiplane[2] min(&1%dim[3],wiplane[2])
  else
    let wiplane miplane
  endif
  if (view%movie.ne.0) then
    ! Elapsed time as specified by user
    let rwait view%movie/(abs(wiplane[2]-wiplane[1])+1)
  else
    ! 5 seconds in total, or per chunk of 128 channels
    let rwait 5.0/min(128,(abs(wiplane[2]-wiplane[1])+1))
  endif
  let ilast wiplane[1]
  let jlast ilast-wiplane[1]+1
  !
  for i wiplane[1] to wiplane[2]
    gtvl\change directory <greg<channel
    greg2\plot &1[i] /scal lin view%chan%min view%chan%max ! Scaling
    gtvl\change directory <greg<spectrum
    greg1\pencil /col 8
    greg1\draw relo velocities[ilast] user_ymin /user
    greg1\draw line velocities[ilast] cspectre[jlast] /user
    greg1\pencil /col 0
    let ilast i
    let jlast ilast-miplane[1]+1
    greg1\draw relo velocities[ilast] user_ymin /user
    greg1\draw line velocities[ilast] cspectre[jlast] /user
    if (rwait.ge.0.01) then
      sic wait rwait
    endif
  next
  greg1\pencil /col 8
  greg1\draw relo velocities[ilast] user_ymin /user
  greg1\draw line velocities[ilast] cspectre[jlast] /user
  greg1\pencil /col 0
  !
  ! Restore the defined channel
  !
  if (view%current%plane.ne.0) then
    gtvl\change directory <greg<channel
    sic wait rwait
    greg2\plot &1[view%current%plane] /scal lin view%chan%min view%chan%max
    @ sub_good_box &1
  endif
  gtvl\change directory <greg
  @ view 'view%root'
  !
end procedure view-movie
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
begin procedure view-extract
  !
  define logical doit
  define integer irange[2] tmp
  !
  if (view%range[1].ne.0.or.view%range[2].ne.0) then
    let irange  (view%range-view%convert[2])/view%convert[3]+view%convert[1]
    if view%convert[3].lt.0 then
      let tmp irange[1]
      let irange[1] irange[2]
      let irange[2] tmp
    endif
  else
    let irange miplane
  endif
  let doit (iblc[1].eq.1).and.(iblc[2].eq.1).and.(irange[1].eq.1)
  let doit doit.and.(itrc[1].eq.&1%dim[1]).and.(itrc[2].eq.&1%dim[2]).and.(irange[2].eq.&1%dim[3])
  if (doit) then
    message w VIEW "Extracted cube will be identical to original one => abort"
    return
  else
    message w VIEW "Extracting from SIC variable "'view%root'
    display\extract 'view%root' 'iblc[1]' 'iblc[2]' 'irange[1]'  'itrc[1]' 'itrc[2]' 'irange[2]'
  endif
  !
end procedure view-extract
!
begin procedure view-write
  if 'pro%arg[2]'.eq.view%area then !  Mean area
    say "Saving integrated area file in view-area.gdf"
    define image a view-area.gdf real /like view_area
    let a% &1%
    let a view_area
    if (view%convert[3].ne.0.0) then
      let a%unit '&1%unit'".km/s"
      let a%freqres = a%freqres*view%current%width/a%velres
      let a%velres = view%current%width
      let a%convert[1,3] = 1.0d0
      let a%convert[2,3] = view%current%vcent
      let a%veloff = view%current%vcent
    endif
    delete /variable a
    vector\header view-area.gdf /extrema
  else if ('pro%arg[2]'.ne.view%channel) then
    if (view%old%mxy.eq.0) return
    say "Saving integrated & current spectrum table in view-spectre.tab"
    define table a[view%old%mxy,3] view-spectre.tab real
    let a[1] xspectre
    let a[2] mspectre
    let a[3] cspectre
  endif
end procedure view-write
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
begin procedure view-print
  !
  if .not.file(ha) then
    sic mkdir ha
  endif
  let view%iprint view%iprint+1
  gtvl\hardcopy "ha/view-"'view%iprint' /dev eps color
  say " "
  say "go view: EPS file available as ha/view-"'view%iprint'".eps"
  say " "
  !
end procedure view-print
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
begin procedure view-lines
  if 'view%root'%f_axis.ne.3 return
  if (view%nbox.gt.4) then
    gtvl\change dir <greg<wspectru
    @ preview_lines view%current%fmin view%current%fmax !! Not user_xmin user_xmax
    @ view-drawlines
  endif
  gtvl\change dir <greg
end procedure view-lines
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
begin procedure view-drawlines
  if preview%nfound.eq.0 return
  !
  define real ypos[2]
  define double vrange[2] f_scale
  let vrange user_xmin user_xmax
  !
  ! Allow for a global Redshift by introducing a scale factor
  ! on frequencies f_scale
  if exist(redshift) then
    f_scale = 1.d0+redshift
  else
    f_scale = 1.d0
  endif
  greg1\limits view%current%frange[1]*f_scale view%current%frange[2]*f_scale = =
  compute ypos[1] min cspectre
  let ypos[1] max(0.,ypos[1])
  let ypos[2] user_ymin+0.95*(user_ymax-user_ymin)
  greg1\set expand 0.8*view%expand
  greg1\pencil 1
  for klines 1 to preview%nfound
    greg1\draw relo preview%found%freq[klines] user_ymin /user
    greg1\draw line preview%found%freq[klines] ypos[1] /user
    greg1\draw text preview%found%freq[klines] ypos[2] 'preview%found%lines[klines]' 4 90 /user
  next
  ! Restore limits
  greg1\limits vrange[1] vrange[2] = =
  greg1\set expand view%expand
  greg1\pencil 0
end procedure view-drawlines
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
begin data gag_scratch:view-slice.init
  !
  ! Parameter file for SLICE task
  !
  task\file "Input file name" INPUT_MAP$ 'name'.'type'
  task\file "Output file name" OUTPUT_MAP$ 'name'.xy
  task\character "Starting point" START$ 'view%slc[1,1]'" "'view%slc[2,1]'
  task\character "Ending point" END$ 'view%slc[1,2]'" "'view%slc[2,2]'
  task\go
  !
end data gag_scratch:view-slice.init
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
begin data gag_scratch:view-extract.init
  !
  ! Parameter file for EXTRACT task
  !
  task\file "Input file name"  Y_NAME$ 'name'"."'type'
  task\file "Output file name" X_NAME$ 'name'"-ext."'type'
  task\integer "Bottom left corner" BLC$[4] 'iblc[1]' 'iblc[2]' 'miplane[1]' 0
  task\integer "Top right corner"   TRC$[4] 'itrc[1]' 'itrc[2]' 'miplane[2]' 0
  task\integer "Position of one pixel in input image"   PIXEL_IN$[4]  'iblc[1]' 'iblc[2]' 'miplane[1]' 1
  task\integer "Position of this pixel in output image" PIXEL_OUT$[4] 1 1 1 1
  task\logical "Initialize output image" INITIALIZE$ YES
  SAY "If YES, Fill information Below"
  task\integer "Dimensions of output image" X_DIM$[4]  0 0 0 0
  task\logical "Initialize with input file's blanking value" BLANKOUT$ YES
  task\real "Initialization value [1 real]" INITVAL$ 0
  task\go
  !
end data gag_scratch:view-extract.init
!
begin procedure view-over
  define integer cplane
  if (exist('view%cont')) then
    if ('view%cont'%ndim.eq.2).or.(view%cplane.eq.0) then
      greg2\rgdata 'view%cont' /var
    else if ('view%cont'%ndim.eq.3) then
      cplane = max(view%cplane,1)
      cplane = min('view%cont'%dim[3],cplane)
      greg2\rgdata 'view%cont'[cplane] /var
    else
      return ! Quiet return
    endif
  else if (view%rplane.ne.0) then
    cplane = max(view%rplane,1)
    cplane = min('view%root'%dim[3],cplane)
    greg2\rgdata 'view%root'[cplane] /var
  else
    return
  endif
  greg2\levels 1 to 9 by 2
  greg2\rgmap /per 10
  !
  ! Restore the proper RGDATA to get coordinates properly
  greg2\rgdata 'view%root'[view%current%plane] /var
  !
end procedure view-over
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
begin procedure view-range
  !
  !    @ view-range 'view%root' 'ibox' 'jaction'
  !
  ! Select the range of displayed integrated intensity values
  ! - move to area plot
  ! - modify the limits so that they match the colour scale in Y
  ! - select the min and max by the user
  ! - view again
  !
  ! This was only obtained by Cursor *, if view%do%mask is active
  !
  ! New behaviour:
  !   if in area, re-define area_min  and area_max from colour scale
  !   if in current plane, do the same for the overall spectral scale
  !   match zeros to have good colors.
  !
  define integer test
  let test 0&2
  if (test.eq.view%area) then
    gtvl\change directory <greg<area
    define double umin umax
    umin = user_ymin
    umax = user_ymax
    greg1\limits = = view%INTE%min view%INTE%max
    define real tlim[2]
    say "Select lower limit"
    greg1\draw relo
    let tlim[1]  use_curs[2]
    say "Set upper limit"
    greg1\draw relo
    let tlim[2]   use_curs[2]
    ! Restore the limits
    limits = = umin umax
    !
    if (tlim[1].eq.tlim[2]) then
      ! Back to full scale, automatic
      let view%inte%min area_min
      let view%inte%max area_max
      let view%chan%min view%current%min
      let view%chan%max view%current%max
      let true_scale view%chan%min view%chan%max
    else
      compute view%INTE%Min min tlim
      compute view%INTE%Max max tlim
      !
      ! Here the Spectra flux scale should also be recentered to have
      ! the same zero
      !
      @ inte_to_chan
    endif
  else if (test.eq.view%channel) then
    SAY "Do not know yet RANGE in Channel panel"
!
    let view%do%extrema YES
  else
    SAY "Invalid call to view-range "'test'
  endif
  ! ...
  ! DAMAGING -- Not needed ?! let view%do%flux yes
  gtvl\change directory <greg
  SAY "Quitting view-range"
  @ view 'view%root'
  !
end procedure view-range
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
begin procedure inte_to_chan
  ! Place the Zero at same colour than in Current channel display
  !     This can be tricky because
  !        1) min & max may have same sign
  !        2) One may want to cut either the positive of the negative side
  view%chan%min = view%current%min
  view%chan%max = view%current%max
  define real r
  !
  if (view%inte%min.lt.0) then
    if (view%inte%max.gt.0) then
      ! Min - 0 - Max
      r = -view%inte%max/view%inte%min
      if (r.gt.1) then
        ! Min - 0 - MAX                ! Adjust on MAX
        view%chan%min = -view%chan%max/r
      else
        ! MIN - 0 - Max                ! Adjust on MIN
        view%chan%max = -r*view%chan%min
      endif
    else if (view%inte%max.lt.0) then
      ! Both negative - Adjust on MIN
      r = view%inte%min/view%inte%max  ! > 1
      view%chan%max = r*view%chan%min
    else
      view%chan%max = 0
    endif
  else if (view%inte%min.gt.0) then
    ! Both positive  - Adjust on MAX
    r = view%inte%max/view%inte%min  ! > 1
    view%chan%min = view%chan%max/r
  else
    view%chan%min = 0
  endif
  ! True_scale is the variable used for COLOR command
  let true_scale view%chan%min view%chan%max
  if (color[3].ne.0) @ p_color
end procedure
!
begin procedure get-offset
  define double rx ry
  ! Offset
  let rx (&2-&1%convert[1,1])*&1%convert[3,1]+&1%convert[2,1]
  let ry (&3-&1%convert[1,2])*&1%convert[3,2]+&1%convert[2,2]
  let view%cx rx/box%aunit /format f0.2
  let view%cy ry/box%aunit /format f0.2
end procedure get-offset
!
let view%first no
@ p_axes &1
!
! Initialize the view%nboxes
for i 3 to 6
  @ sub_box dummy 'i'
next
!
if .not.exist(&1__first) then
  define integer &1__first &1__last /global
  define real &1__size[2] /global
endif
SAY "First initialisation"
if ((&1%dim[3].gt.1).and.((first.ne.last).or.(first.eq.0))) then
  let view%do%extrema yes
  let view%do%flux yes
  let view%do%window yes
  let view%order '&1%x_axis''&1%y_axis''&1%f_axis'
  @ view-help
  if (view%order.ne."123").and.(view%order.ne."213") then
    say 'ansi%red'"W-VIEW,  Data cube is not a LMV or MLV cube, trying anyway..."'ansi%none'
  endif
  @ get_plane 'view%root'
  @ get_corner
  @ view 'view%root'
  if (do_loop) then
    @ loop
  endif
  &1__first = first
  &1__last = last
  let view%previous 'view%root'
else
  let beam_type " "
  let extra " "
  let old_side show_side /new logical
  let show_side do_loop
  @ p_lmv_map 'view%root' 0 &2 &3
  let show_side old_side
  &1__first = -1
  &1__last = -1
endif
&1__size = size
return
!
!
!=======================================================================
! Quick Programming Documentation
Procedure view-help       Re-act to the HELP instruction (H key)
Procedure view-value      Get current pixel value ?
Procedure view-channel    Display current channel
Procedure view-view       Re-view (Simply calls "view")
Procedure view-flux       Compute integrated flux
Procedure view-mask       Overlay the current mask
Procedure view-window     Define the velocity window for integrated area
Procedure view-zoom       Zoom in velocity
Procedure view-unzoom     Unzoom in velocity
Procedure view-spectrum   Current spectrum extraction
Procedure view-wide       Wide velocity window
Procedure view-slice      Compute and display a SLICE
Procedure view-movie      Make a movie
Procedure view-extract    Extract a sub-cube
Procedure view-write      Write the sub-cube
Procedure view-print      Print a hardcopy
Procedure view-lines      Draw spectral lines
Procedure view-drawlines    (support routines)
Procedure view-range    ! Center zero color
!
Procedure loop          ! Main loop
Procedure sub_box       ! Define the Box positions
Procedure get_corner    ! Define the Area boundaries and Polygon
Procedure get_plane     ! Define the plotted velocity range
Procedure side          ! Create or Open the "Side" graphic window
Procedure view          ! Main routine
Procedure get_szoom     ! Spatial zoom definition
Procedure inte_to_chan  ! Center the Zero at similar positions in Area and Channel map displays
!
! To force recomputation
!
let view%do%flux YES
let view%do%window YES
let view%do%extrema YES
!
