!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
begin procedure q-browse-default
  if .not.exist(browse%default) define structure browse%default /global
  go\load 'browse%cube%id' /unit          /into browse%default%unit global
  go\load 'browse%cube%id' /axis freq abs /into browse%default%freq global
  go\load 'browse%cube%id' /axis velo abs /into browse%default%velo global
  go\load 'browse%cube%id' /axis imag abs /into browse%default%imag global
  !
  @ l-header-load 'browse%cube%id' browse%header
  !
  ! Define exact frequency extrema. This avoids truncating half the channels
  ! at boundaries. ZZZ this should be part of LOAD /AXIS
  define double f1 f2
  let f1                       (0.5-browse%default%freq%ref)*browse%default%freq%inc+browse%default%freq%val
  let f2 (browse%default%freq%n+0.5-browse%default%freq%ref)*browse%default%freq%inc+browse%default%freq%val
  if browse%default%freq%inc.gt.0 then
    let browse%cube%fmin f1
    let browse%cube%fmax f2
  else
    let browse%cube%fmin f2
    let browse%cube%fmax f1
  endif
  !
  @ q-browse-default-xcenter
  @ q-browse-default-xwidth
  let browse%zoom%ytotal yes
  !
  @ q-browse-line-file
  @ q-browse-line-read
end procedure q-browse-default
!
begin procedure q-browse-default-xwidth
  ! if (user%width.ne.0) then
  !   let browse%zoom%xwidth user%width
  ! else
    let browse%zoom%xwidth abs(browse%default%freq%inc)*browse%default%freq%n/8.
  ! endif
end procedure q-browse-default-xwidth
!
begin procedure q-browse-default-xcenter
  ! if (user%center.ne.0) then
  !   let browse%zoom%xcenter user%center
  ! else
    let browse%zoom%xcenter (browse%default%freq%coord[1]+browse%default%freq%coord[browse%default%freq%n])/2.
  ! endif
end procedure q-browse-default-xcenter
!
begin procedure q-browse-line-file
  !---------------------------------------------------------------------
  ! Set up the line catalog file name
  !---------------------------------------------------------------------
  if cubego%catalog%file.eq." " then
    let browse%line%file gag_data:`gag_molecules`
  else
    let browse%line%file 'cubego%catalog%file'
  endif
end procedure q-browse-line-file
!
begin procedure q-browse-line-read
  !---------------------------------------------------------------------
  ! Read the line catalog file and store the lines in the internal
  ! structure
  !---------------------------------------------------------------------
  sic\compute browse%line%n lines 'browse%line%file' /blank
  if exist(browse%line%freq) then
    del /var browse%line%freq browse%line%name
  endif
  define double browse%line%freq[browse%line%n] /global
  define character*24 browse%line%name[browse%line%n] /global
  sic\accept browse%line%freq browse%line%name /column 'browse%line%file'
  let browse%line%freq browse%line%freq*1000  ! From GHz to MHz
end procedure q-browse-line-read
!
begin procedure q-browse-init
  if exist(browse%aaa) then
     delete /var browse
  endif
  if .not.exist(browse) then
     define structure browse /global
     !
     define structure browse%cube /global
     define integer browse%cube%id /global
     define double browse%cube%fmin browse%cube%fmax /global
     define structure browse%pixel /like cubego%pixel /global
     !
     @ l-header-def browse%header
     !
     define structure browse%panel /global
     define integer browse%panel%ifull browse%panel%izoom /global
     !
     define structure browse%zoom /global
     define double browse%zoom%xcenter browse%zoom%xwidth /global
     define double browse%zoom%fmin browse%zoom%fmax /global
     define logical browse%zoom%ytotal /global
     define real browse%zoom%ymin browse%zoom%ymax /global
     !
     define structure browse%line /global
     define character*256 browse%line%file /global
     define integer browse%line%n /global
  endif
  !
  if ((page_x.ne.30).or.(page_y.ne.21)) then
     greg1\set plot landscape
     message w browse "Ensure a landscape plot page"
  endif
  !
  @ l-ctrl-master-register-panel "full" 0.12 1.35 0.10  0.30 browse%panel%ifull
  @ l-ctrl-master-register-panel "zoom" 0.12 1.35 0.425 0.80 browse%panel%izoom
  !
  let browse%cube%id cubego%cubes%id[1]
  let browse%pixel%  cubego%pixel%
  !
  @ q-browse-default
end procedure q-browse-init
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
begin procedure q-browse-header-draw
  gtvl\change directory "<greg<"'ctrlmast%pan%name[browse%panel%izoom]'
  @ l-header-draw-cubeid browse%header 0 5.5 5 0 8
  @ l-header-draw-desc   browse%header 0 4.0 5 0 8
end procedure q-browse-header-draw
!
begin procedure q-browse-zoom-range
  ! Convert from xcenter & xwidth to min-max frequencies and channels
  ! Note they can extend beyond the spectrum limits, this is a desired
  ! feature
  let browse%zoom%fmin browse%zoom%xcenter-browse%zoom%xwidth
  let browse%zoom%fmax browse%zoom%xcenter+browse%zoom%xwidth
end procedure q-browse-zoom-range
!
begin procedure q-browse-plot-full
  on error return
  @ l-ctrl-master-panel-update-bound 'browse%panel%ifull' *
  @ q-browse-plot-any 'browse%cube%fmin' 'browse%cube%fmax' yes
  ! Legend
  greg1\draw text 0 -2 "Rest Frequency [MHz]" 5 /char 2
end procedure q-browse-plot-full
!
begin procedure q-browse-plot-zoom
  on error return
  @ l-ctrl-master-panel-update-bound 'browse%panel%izoom' *
  @ q-browse-plot-any 'browse%zoom%fmin' 'browse%zoom%fmax' 'browse%zoom%ytotal'
end procedure q-browse-plot-zoom
!
begin procedure q-browse-plot-zoom-lines
  greg1\pencil /col red
  !
  gtvl\change directory "<greg<"'ctrlmast%pan%name[browse%panel%ifull]'
  @ l-draw-vertical-line-at 'browse%zoom%fmin'
  gtvl\change directory "<greg<"'ctrlmast%pan%name[browse%panel%izoom]'
  greg1\draw line user_xmin user_ymin /user
  !
  gtvl\change directory "<greg<"'ctrlmast%pan%name[browse%panel%ifull]'
  @ l-draw-vertical-line-at 'browse%zoom%fmax'
  gtvl\change directory "<greg<"'ctrlmast%pan%name[browse%panel%izoom]'
  greg1\draw line user_xmax user_ymin /user
  !
  greg1\pencil /col foreground
end procedure q-browse-plot-zoom-lines
!
begin procedure q-browse-plot-any
  define double fmin fmax
  define logical ytotal
  let fmin   &1  ! [MHz] Min frequency
  let fmax   &2  ! [MHz] Max frequency
  let ytotal &3  ! [bool] Total Y scale or custom?
  !
  ! Convert frequencies to channels
  define double cmin cmax
  let cmin (fmin-browse%default%freq%val)/browse%default%freq%inc+browse%default%freq%ref
  let cmax (fmax-browse%default%freq%val)/browse%default%freq%inc+browse%default%freq%ref
  ! Convert channels to velocities
  define double vmin vmax
  let vmin (cmin-browse%default%velo%ref)*browse%default%velo%inc+browse%default%velo%val
  let vmax (cmax-browse%default%velo%ref)*browse%default%velo%inc+browse%default%velo%val
  ! Convert float channels to proper integer channels
  define integer first last
  if browse%default%freq%inc.gt.0 then
    let first max(nint(cmin),1)
    let last  min(nint(cmax),browse%default%freq%n)
  else
    let first max(nint(cmax),1)
    let last  min(nint(cmin),browse%default%freq%n)
  endif
  !
  ! Load the spectrum min-max
  go\load 'browse%cube%id' /into myspec -
    /pixel 'browse%pixel%l' 'browse%pixel%m' 'browse%pixel%type' 'browse%pixel%unit'
  define real specmin specmax
  if ytotal then
    sic\compute specmin min myspec[first:last]
    sic\compute specmax max myspec[first:last]
  else
    let specmin browse%zoom%ymin
    let specmax browse%zoom%ymax
  endif
  !
  ! Velocity based
  greg1\limits vmin vmax specmin specmax /margin 0 5
  greg1\axis xu /label p
  !
  ! Frequency based
  greg1\limits fmin fmax specmin specmax /margin 0 5
  greg1\axis xl /label p
  greg1\axis yl /label o
  greg1\axis yr /label n
  greg1\histogram browse%default%freq%coord[first:last] myspec[first:last]
  !
  ! Legend
  greg1\draw text -3 0 'browse%default%unit' 5 90 /char 4
  !
  ! Leave procedure with X unit = frequency
end procedure q-browse-plot-any
!
begin procedure q-browse-display-value
  !---------------------------------------------------------------------
  ! &1: absolute frequency
  ! &2: intensity
  !---------------------------------------------------------------------
  define double freq temp
  let freq &1
  let temp &2
  ! Convert back to floating-point channel (to avoid rounding)
  define double chan velo imag
  let chan (freq-browse%default%freq%val)/browse%default%freq%inc+browse%default%freq%ref
  let velo (chan-browse%default%velo%ref)*browse%default%velo%inc+browse%default%velo%val
  let imag (chan-browse%default%imag%ref)*browse%default%imag%inc+browse%default%imag%val
  !
  say "   Velocity            : " 'velo' " km/s"               /format a 1pg19.12 a
  say "   Rest Frequency      : " 'freq' " MHz"                /format a 1pg19.12 a
  say "   Image Frequency     : " 'imag' " MHz"                /format a 1pg19.12 a
  say "   Channel number      : " 'chan'                       /format a 1pg19.12
  say "   Antenna Temperature : " 'temp' 'browse%default%unit' /format a 1pg19.12 a
end procedure q-browse-display-value
!
begin procedure q-browse-list-lines
  !---------------------------------------------------------------------
  ! Use the CDMS catalog to list the line within 5 MHz
  !---------------------------------------------------------------------
  define double freq
  let freq &1
  use in cdms
  select /freq 'freq-2.5' 'freq+2.5'
  l\list
end procedure q-browse-list-lines
!
begin procedure q-browse-line-annotate
  gtvl\change directory "<greg<"'ctrlmast%pan%name[browse%panel%izoom]'
  define double ypos
  let ypos user_ymin+0.95*(user_ymax-user_ymin)
  greg1\pencil /col red
  for iline 1 to browse%line%n
     greg1\draw text 'browse%line%freq[iline]' ypos 'browse%line%name[iline]' 4 90 /user /clip
  next iline
  greg1\pencil /col foreground
end procedure q-browse-line-annotate
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
begin procedure l-ctrl-zoom-width
  let browse%zoom%xwidth browse%zoom%xwidth/1.414214
  if browse%zoom%xwidth.lt.abs(browse%default%freq%inc) then
    ! At least 2 channels displayed (avoid no range in X error), knowing
    ! xwidth is half the zoom range.
    let browse%zoom%xwidth abs(browse%default%freq%inc)
  endif
end procedure l-ctrl-zoom-width
!
begin procedure l-ctrl-unzoom-width
  let browse%zoom%xwidth browse%zoom%xwidth*1.414214
  if browse%zoom%xwidth.gt.abs(browse%default%freq%inc)*browse%default%freq%n/2 then
    ! At most the full range, knowing xwidth is half the zoom range
    let browse%zoom%xwidth abs(browse%default%freq%inc)*browse%default%freq%n/2
  endif
end procedure l-ctrl-unzoom-width
!
begin procedure l-ctrl-shift-xcenter
  let browse%zoom%xcenter browse%zoom%xcenter&10.5*browse%zoom%xwidth
  if browse%zoom%xcenter.lt.browse%cube%fmin then
    let browse%zoom%xcenter browse%cube%fmin
  else if browse%zoom%xcenter.gt.browse%cube%fmax then
    let browse%zoom%xcenter browse%cube%fmax
  endif
end procedure l-ctrl-shift-xcenter
!
begin procedure l-browse-zoom-y
  ! Always from the zoom box:
  gtvl\change directory "<greg<"'ctrlmast%pan%name[browse%panel%izoom]'
  say "Type any char in zoom box to set Y lower and upper limits"
  greg1\draw relo
  let browse%zoom%ymin use_curs[2]
  say "Y1 = " browse%zoom%ymin /format A5 F8.3
  greg1\draw relo
  let browse%zoom%ymax use_curs[2]
  say "Y2 = " browse%zoom%ymax /format A5 F8.3
  let browse%zoom%ytotal no
end procedure l-browse-zoom-y
!
begin procedure l-browse-ctrl-full-loop
  gtvl\change directory "<greg<"'ctrlmast%pan%name[browse%panel%ifull]'
  @ l-browse-ctrl-any-loop
end procedure l-browse-ctrl-full-loop
!
begin procedure l-browse-ctrl-zoom-loop
  gtvl\change directory "<greg<"'ctrlmast%pan%name[browse%panel%izoom]'
  @ l-browse-ctrl-any-loop
end procedure l-browse-ctrl-zoom-loop
!
begin procedure l-browse-ctrl-any-loop
  greg1\draw relo * *
  if ((cursor_code.eq." ").or.(cursor_code.eq."R")) then
     let browse%zoom%xcenter use_curs[1]
  else if (cursor_code.eq."V") then
     @ q-browse-display-value 'use_curs[1]' 'use_curs[2]'
  else if (cursor_code.eq."L") then
     @ q-browse-list-lines 'use_curs[1]'
  endif
end procedure l-browse-ctrl-any-loop
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
begin procedure l-ctrl-slave-init
  @ q-browse-init
end procedure l-ctrl-slave-init
!
begin procedure l-ctrl-slave-action
  gtvl\clear
  @ q-browse-zoom-range
  @ q-browse-plot-full
  @ q-browse-plot-zoom
  @ q-browse-plot-zoom-lines
  @ q-browse-line-annotate
  @ q-browse-header-draw
  gtvl\change directory <greg
end procedure l-ctrl-slave-action
!
begin procedure l-ctrl-slave-loop
  if (cursor_code.eq."Z") then
    @ l-ctrl-zoom-width
  else if (cursor_code.eq."U") then
    @ l-ctrl-unzoom-width
  else if (cursor_code.eq."N") then
    @ l-ctrl-shift-xcenter "+"
  else if (cursor_code.eq."P") then
    @ l-ctrl-shift-xcenter "-"
  else if (cursor_code.eq."B") then
    @ q-browse-default-xwidth
  else if (cursor_code.eq."D") then
    @ q-browse-default-xwidth
    @ q-browse-default-xcenter
  else if (cursor_code.eq."Y") then
    @ l-browse-zoom-y
  else if (cursor_code.eq."T") then
    let browse%zoom%ytotal yes
  else if (ctrlmast%pan%icurr.eq.browse%panel%ifull) then
    @ l-browse-ctrl-full-loop
  else if (ctrlmast%pan%icurr.eq.browse%panel%izoom) then
    @ l-browse-ctrl-zoom-loop
  else if (ctrlmast%pan%icurr.eq.ctrlmast%pan%iout) then
    ! Out of the boxes: no action
    continue
  else
    message w browse "Should not be here: ctrlmast%pan%icurr = "'ctrlmast%pan%icurr'
  endif
end procedure l-ctrl-slave-loop
!
begin procedure l-ctrl-slave-exit
  continue
end procedure l-ctrl-slave-exit
!
begin procedure l-ctrl-slave-help-position-independent
  say "   Left  click: Center zoom at cursor location"
  say "   Press SPACE key: Center zoom at cursor location"
  say "   Press   Z   key: Zoom at cursor location"
  say "   Press   U   key: Unzoom at cursor location"
  say "   Press   B   key: Reset zoom factor to default"
  say "   Press   D   key: Default zoom width and location"
  say "   Press   V   key: Values at cursor location"
  say "   Press   N   key: Shift forward  the zoom window by half its size"
  say "   Press   P   key: Shift backward the zoom window by half its size"
  say "   Press   Y   key: Zoom Y axis scale (intensity)"
  say "   Press   T   key: Back to full scale for Y axis"
  say "   Press   L   key: Use the CDMS catalog to list the line within 5 MHz"
end procedure l-ctrl-slave-help-position-independent
!
begin procedure l-ctrl-slave-help-position-dependent
  say "   <none>"
end procedure l-ctrl-slave-help-position-dependent
!
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
! Definitions
@ l-draw.cube
@ l-header.cube
! Action
@ l-ctrl-master
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
