!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
begin procedure q-view-define-axis
  define structure view%&1 /global
  define double view%&1%first view%&1%last view%&1%position /global
end procedure q-view-define-axis
!
begin procedure q-view-z-window2channel
  define integer iloc[2] ione itwo
  sic\compute iloc location view%default%velo%coord view%z%window[1] 
  let ione iloc[1]
  sic\compute iloc location view%default%velo%coord view%z%window[2] 
  let itwo iloc[2]
  let view%z%imin min(ione,itwo)
  let view%z%imax max(ione,itwo)
end procedure q-view-z-window2channel
!
begin procedure q-view-xy-range2poly
  ! *** JP: This one is a work-around the fact that STACK has no /SIZE /CENTER keys
  if exist(view%poly%xy) then
     delete /var view%poly%xy
  endif
  define real view%poly%xy[4,2] /global
  let view%poly%xy[1,1:2] 'view%x%first' 'view%y%first'
  let view%poly%xy[2,1:2] 'view%x%last'  'view%y%first'
  let view%poly%xy[3,1:2] 'view%x%last'  'view%y%last'
  let view%poly%xy[4,1:2] 'view%x%first' 'view%y%last'
end procedure q-view-xy-range2poly
!
begin procedure q-view-topology2view
  ! *** JP: I need to split the image and spectrum part!
  topology 'view%cube%id'
  if ((view%scale[1].eq.0).and.(view%scale[2].eq.0)) then
     let view%scale[1] 'topology%extrema%min%value'
     let view%scale[2] 'topology%extrema%max%value'
  endif
  let view%aspect abs((topology%x%last-topology%x%first)/(topology%y%last-topology%y%first))
  let view%x%first topology%x%first*sec
  let view%x%last  topology%x%last*sec
  let view%y%first topology%y%first*sec
  let view%y%last  topology%y%last*sec
  let view%z%first topology%z%first
  let view%z%last  topology%z%last
  let view%z%window[1] view%z%first
  let view%z%window[2] view%z%last
  let view%z%position 0.5*(view%z%first+view%z%last)
  @ q-view-xy-range2poly
  @ q-view-z-window2channel
end procedure q-view-topology2view
!
begin procedure q-view-default
  if .not.exist(view%default) define structure view%default /global
  load 'view%cube%id' /axis velo abs /into view%default%velo global
  load 'view%cube%id' /unit /into view%default%unit global
  !
  @ q-view-topology2view
  let view%compute%mean yes
  let view%compute%area yes
  let view%created%mean no
  let view%created%area no
  let view%created%mask no
  load 'view%cube%id' /velocity /into vsys
  let view%z%position 'vsys%value'
end procedure q-view-default
!
begin procedure q-view-init
  if exist(view%thres_mode) then
     delete /var view
  endif 
  if .not.exist(view) then
     define structure view /global
     define structure view%cube /global
     define integer view%cube%id /global
     define structure view%panel /global
     define integer view%panel%ichan view%panel%ispec view%panel%iarea view%panel%imean /global
     define structure view%poly /global
     @ q-view-define-axis x
     @ q-view-define-axis y
     @ q-view-define-axis z
     define integer view%z%imin view%z%imax /global
     define double view%z%window[2] /global
     define double view%center[2] view%size[2] view%scale[2] view%aspect /global
     define structure view%compute /global
     define logical view%compute%area view%compute%mean /global
     define structure view%created /global
     define logical view%created%area view%created%mask view%created%mean /global
     @ l-header.cube
     @ l-header-def view%header
  endif
  !
  if ((page_x.ne.30).or.(page_y.ne.21)) then
     greg1\set plot landscape
     message w view "Ensure a landscape plot page"
  endif
  !
  @ l-ctrl-master-register-panel "channel"  0.17 0.72 0.540 0.955 view%panel%ichan
  @ l-ctrl-master-register-panel "area"     0.17 0.72 0.075 0.490 view%panel%iarea
  @ l-ctrl-master-register-panel "spectrum" 0.86 1.30 0.540 0.955 view%panel%ispec
  @ l-ctrl-master-register-panel "mean"     0.86 1.30 0.075 0.490 view%panel%imean
  !
  @ l-spectrum-init
  let view%scale 0 ! Must be reset for each new cube.
  let view%cube%id cubego%cubes%id[1]
  let spectrum%cubeid 'view%cube%id'
  !
  @ q-view-default
end procedure q-view-init
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
begin procedure q-view-header
  change directory <greg
  panel 1 /nxy 1 1 /position 0.17 1.30 0.075 0.955 /aspect *
  @ l-header-load 'view%cube%id' view%header
  @ l-header-draw-desc view%header -1.2 1 5 0 8
  @ l-header-draw-cubeid view%header -5.5 0 5 90 4
end procedure q-view-header
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
begin procedure q-view-compute-image-area
  if (.not.view%compute%area) return
  on error return
  if (view%created%area) remove *:stacked,image
  stack 'view%cube%id' /image /range 'view%z%window[1]' 'view%z%window[2]' ! *** JP here I should have /size /center
  let view%compute%area no
  let view%created%area yes
end procedure q-view-compute-image-area
!
begin procedure q-view-plot-image-markers
  greg1\pen 0 /col negative
  @ l-draw-cross-at 'view%x%position' 'view%y%position'
  @ l-draw-poly view%poly
  greg1\pen 0 /default
end procedure q-view-plot-image-markers
!
begin procedure q-view-plot-image-at-channel
  on error return
  @ l-ctrl-master-panel-update-bound 'view%panel%ichan' 'view%aspect'
  load 'view%cube%id' /channel 'view%z%position' abs *
  g\set angle sec
  limits 'topology%x%first'  'topology%x%last'  'topology%y%first' 'topology%y%last'
  plot /scal lin 'view%scale[1]' 'view%scale[2]'
  @ q-view-plot-image-markers
  box
  wedge
  g\set angle rad ! *** JP So strange that I need to reset to radian to get the correct spectrum plot afterwards!
  greg1\draw text 4 0 "Channel ["'view%default%unit'"]" 5 90 /char 6
end procedure q-view-plot-image-at-channel
!
begin procedure q-view-plot-image-area
  on error return
  @ l-ctrl-master-panel-update-bound 'view%panel%iarea' 'view%aspect'
  load *:stacked,image /unit /into unit
  load *:stacked,image /first image /into area
  g\set angle sec
  limits 'topology%x%first'  'topology%x%last'  'topology%y%first' 'topology%y%last'
  plot /scal lin
  @ q-view-plot-image-markers
  box
  wedge
  g\set angle rad ! *** JP So strange that I need to reset to radian to get the correct spectrum plot afterwards!
  greg1\draw text 4 0 "Area ["'unit'"]" 5 90 /char 6
end procedure q-view-plot-image-area
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
begin procedure q-view-compute-spectrum-mean
  if (.not.view%compute%mean) return
  on error return
  if (view%created%mean) remove *:stacked,spectrum
  if exist(view%poly%xy) then
     if (view%created%mask) remove *:mask
     poly2mask 'view%cube%id' /variable view%poly%xy
     let view%created%mask yes
     stack 'view%cube%id' /spectrum /range 'view%z%first' 'view%z%last' /mask ! *** JP here I should have /size /center
  else
     stack 'view%cube%id' /spectrum /range 'view%z%first' 'view%z%last' ! *** JP does not exist yet! => /size 'view%size[1]' 'view%size[2]' /center 'view%center[1]' 'view%center[2]' rel
  endif
  let view%compute%mean no
  let view%created%mean yes
end procedure q-view-compute-spectrum-mean
!
begin procedure q-view-plot-spectrum-at-pixel
  on error return
  @ l-ctrl-master-panel-update-bound 'view%panel%ispec' 1
  limits 'topology%z%first' 'topology%z%last' 'view%scale[1]' 'view%scale[2]' /margin 0 5
  greg1\box p n
  greg1\axis yr /label o
  @ l-spectrum-load-pixel 'view%x%position' 'view%y%position' view%default%velo
  greg1\histogram x[view%z%imin:view%z%imax] y[view%z%imin:view%z%imax] /base 0 /fill 5
  greg1\histogram
  greg1\draw text 4 0 "Spectrum ["'view%default%unit'"]" 5 90 /char 6
  !
  greg1\pencil 1
  @ l-draw-vertical-line-at 'view%z%position'
  greg1\pencil 0
end procedure q-view-plot-spectrum-at-pixel
!
begin procedure q-view-plot-spectrum-mean
  on error return
  @ l-ctrl-master-panel-update-bound 'view%panel%imean' 1
  load *:stacked,spectrum /unit /into unit
  load *:stacked,spectrum /first spectrum /into ymean
  limits 'topology%z%first' 'topology%z%last' * * /var view%default%velo%coord ymean /margin 0 5
  greg1\box p n
  greg1\axis yr /label o
  greg1\histogram x[view%z%imin:view%z%imax] y[view%z%imin:view%z%imax] /base 0 /fill 5
  greg1\histogram
  greg1\draw text 4 0 "Mean spectrum ["'unit'"]" 5 90 /char 6
end procedure q-view-plot-spectrum-mean
!
begin procedure q-view-plot-spectrum-draw-vertical-line-at
  gtvl\change directory "<greg<"'ctrlmast%pan%name[view%panel%ispec]'
  @ l-draw-vertical-line-at &1
  gtvl\change directory  "<greg<"'ctrlmast%pan%name[view%panel%imean]'
  @ l-draw-vertical-line-at &1
end procedure q-view-plot-spectrum-draw-vertical-line-at
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
begin procedure q-view-out-unzoom
  @ l-view-ctrl-image-unzoom
  @ l-view-ctrl-spectrum-unzoom
end procedure q-view-out-unzoom
!
begin procedure q-view-out-loop
  if (cursor_code.eq."U") then
     @ q-view-out-unzoom
  else if (cursor_code.eq."C") then
!     let view%panel%ispe1 mod(view%panel%ispe1,2)+1
!     let view%panel%imap1 mod(view%panel%imap1,2)+1
  endif
end procedure q-view-out-loop
!
begin procedure q-view-out-help
  say "   Cursor outside plots:"
  say "      Press U key: UNZOOM to the full velocity range AND the full field of view"
end procedure q-view-out-help
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
begin procedure q-view-extract
  on error return
  if ((view%size[1].eq.0).and.(view%size[2].eq.0)) return
  extract 'view%cube%id' /range 'view%z%first' 'view%z%last' /size 'view%size[1]' 'view%size[2]' radian /center 'view%center[1]' 'view%center[2]' rel radian
end procedure q-view-extract
!
begin procedure q-view-movie
  ! *** JP: Unclear whether a movie inside a zoom window should only display the
  ! *** JP: the zoomed region.
  on error return
  @ l-ctrl-master-panel-update-bound 'view%panel%ichan' 'view%aspect'
  load 'view%cube%id' /shape /into n
  for ic 1 to n%c
    load 'view%cube%id' /entry 'ic' image /into image
    plot /scal lin 'view%scale[1]' 'view%scale[2]'
    box /unit sec
  next ! ic
end procedure q-view-movie
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
begin procedure l-ctrl-slave-init
  @ q-view-init
end procedure l-ctrl-slave-init
!
begin procedure l-ctrl-slave-action
  clear
  ! Computation of image area can be long
  ! => Start with this one and plot images on purpose
  @ q-view-compute-image-area
  @ q-view-plot-image-area
  @ q-view-plot-image-at-channel
  @ q-view-header
  ! Restart computation of mean spectrum and then plot spectra
  @ q-view-compute-spectrum-mean
  @ q-view-plot-spectrum-mean
  @ q-view-plot-spectrum-at-pixel
end procedure l-ctrl-slave-action
!
begin procedure l-ctrl-slave-loop
  if (cursor_code.eq."X") then
     @ q-view-extract
  else if (cursor_code.eq."M") then
     @ q-view-movie
  else if ((ctrlmast%pan%icurr.eq.view%panel%iarea).or.(ctrlmast%pan%icurr.eq.view%panel%ichan)) then
     @ l-view-ctrl-image-loop
  else if ((ctrlmast%pan%icurr.eq.view%panel%imean).or.(ctrlmast%pan%icurr.eq.view%panel%ispec)) then
     @ l-view-ctrl-spectrum-loop
  else if (ctrlmast%pan%icurr.eq.ctrlmast%pan%iout) then
     @ q-view-out-loop
  else
     message w view "Should not be here: ctrlmast%pan%icurr = "'ctrlmast%pan%icurr'
  endif
end procedure l-ctrl-slave-loop
!
begin procedure l-ctrl-slave-exit
  if (view%created%area) remove *:stacked,image
  if (view%created%mean) remove *:stacked,spectrum
  if (view%created%mask) remove *:mask
end procedure l-ctrl-slave-exit
!
begin procedure l-ctrl-slave-help-position-independent
  say "   Press M key: Movie"
  say "   Press X key: Extract on disk current zoomed region"
end procedure l-ctrl-slave-help-position-independent
!
begin procedure l-ctrl-slave-help-position-dependent
  @ l-view-ctrl-image-help
  @ l-view-ctrl-spectrum-help
  @ q-view-out-help
end procedure l-ctrl-slave-help-position-dependent
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
! Definitions
@ l-draw.cube
@ l-spectrum.cube
@ l-spectrum-init
@ l-view-ctrl-image.cube
@ l-view-ctrl-spectrum.cube
! Action
@ l-ctrl-master
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
