############################################################################
# tkmedie.tcl: UCSD/UCL tkmedit user interface (tcl/tk) -- Marty Sereno
############################################################################
### recent changes
# startup tk/gl windows higher, hide POPGL/readenv line in mini+ (both laptop)
# remove trace zf for enable/disable contupdate (always bind B1-Motion)
# redefine abs_imstem (=mfname): .../T1/COR- -> .../T1
# update mri2mpg.tcl (bound to F12): save rgb's, linearflag, skip plane w/0,0
# make no-Alt arrow keys work right in tk window (working glwin keys are Xlib)
# SAVEIMGS -> testrepl/save same imgtype as editable (COR->COR, mgz/mgh->mgz)
# rename fthresh->bwmid fsquash->bwslope, re-use fthresh as in tksurfer
# F1->rm, F2->F1, F2->inclcmplxstats, F3->same, F4->same
# real/complex colscale 3D overlay controls, Gauss-SMOOTH stats, bind redraws
# add GO/ED script bot overlay panel, mk phasemovie work w/medit, fix setfile
# add bi color scale
# added 20 R-click help panels (funct overlay, include read mgz code for now)
# catch/warn/block attempt to display overlay without overlay loaded
# expand stats:  rgb field, squish histogram, BRw -> BR
# squish: truncphase onto revphase line, PLANEFILTER onto WMTRUNC line
# fix which/editor once again...
# 3D FILL and toggle view label (labelflag), contrast/midpoint -> contr/midpt
# ROI/label entry replaces outim in def mini2,macro, no ROI/label in mini,macro
# add testreplace roi/val, jam in cpx/m buttons, auto-read/write complex subsamp
# rm SAGMIRROR/HISTOG, move READ 2nd img to left of COMPARE button
# subsamp stat mask "R","W" line plus check -> currently all no-op!
# unlabeled tiff/rgb check on rgb line, resets current suff
# "T" write_roi_timecourses (check suff, cp C-strhandling for test overwrite)
# 17 new help pop-ups
# catch missing label/regdat/rawdata before C does
# change outim->im, abs_imstem->inoutim (tkmedit2000 ignores), allow READ
# test_read_images for query read new editable with unsaved edits
# overlayflag toggles SMOOTH STATS <=> SMOOTHSTRUCT for Gauss smooth editable
# create COR dir before write if it doesn't exist
# pixvaltitle updates window-right direction (left,anterior,left) in titlebar
# separate setsmoothtype, just look at overlay flag at startup
# fix Alt/Cmd mess (TODO: restrict here/X11 to Mac Cmd(=Meta) useable keys)
# harmonize/Mac-safe-ify tk/glx key bindings, fix help/medit
# synchronize helpwins w/new code, add Talairach/pixcoords popups
# touch native/Talairach *after* traces (new bug from gathering traces at end)
# detect/report .mgz/.mgh vs. COR at close w/editedimage
# zoomflag->"z" (mini,mini2: all2views->all3) (not mini3,macro), hack TODO:HOR
# unset all3views unsets/disappears zoomflag
# re-read "im:" displays first buffer if second currently shown
# checkbutton "2" next to "R" surf: read second surface
# rm'd untested bak compat (go back to tkmedit26j.tcl if needed)
# hack to mv/update cursor position at brainstem zoom/unzoom (zoomflag)
# zoomflag: disable wrong (!) intrinsic/Talairach coords, SEND/GOTO
# "val:"<->"reg:" re-{read,register,subsample} native stats, both bfloat, BRIK
# help for val:"<->"reg:"
# sphnormflag: 4pt piecewise linear -> spherical linear ramp to current click
# check/auto-swap LSB input BRIK (assume bfloat OK), set overlayflag statread
# change val:"<->"reg:" to vals:"<->"valn:", change startup default to native 
# mskn:"<->"msks:", startup def native, valn/vals/mskn/msks: chk files exist
# add "h" next to fthresh->fthr for hardstatfthreshflag (next: removed)
# rm hardstatfthreshflag, overlaymaskflag toggles vis of s{fthresh/fmid/fslope}
# fadef/ipsiyel->1line, color LUT line + interpolatelut check, group trunc/lims
# help panels for new mask behavior, sfthresh/sfmid/sfslope, color LUT
# mk def colorLUT from ~/mri/talairach.label_intensities.txt, im2lutoverlayflag
# "READ"->"R", "la" toggles disp overlay lab, detectshowlabel->tick la/COMPARE
# add unlabeled button to save bitmap w/o redraw for timecourse graph
# getmghvolindex: tmp right-click popup yTal to get MGH tkmedit Volume index
# put MGH vol index into tk window title to avoid need for click
# csurf tkmedit -> MGH tkmedit intrinsic coords mapping:
#    COR P/A -> 3rd "Volume index": n
#    SAG R/L -> 1st "Volume index": n
#    HOR I/S -> 2nd "Volume index": 255 - n
# MGH tkmedit Talairach, Volume index in different order, S/I flip:
#    Volume index  R/L  S/I  P/A
#    Talairach     R/L  P/A  I/S
# stop Return's in Talairach fields from changing plane
# trunc Talairach to 1 decimal place
# R-click bottom talaiarch label to goto Talairach zero
# squish lower left buttons to make room for fillrad entry
# update roi_fill, roi_rad help
# add cmd-period for toggle WMTRUNC, cmd-K for toggle no cursor
# help for read second surface checkbutton, im (!)
# block COR<->.mgz convert for now
# add labelmaskflag "m" to cause ROI/label to mask activation with label=0
# move rev{phaseflag} to left of angleoffset->angoff like csurf/tksurfer
# rename all subsamp/substat/vals/masks var/fun/widg upsamp/upstat/valup/maskup
# put var renames in a bunch of help panels
# run_wmfilter: std/trunc or gau wmfilter, load output editable or 2nd buff
# PFILTER -> right-click PF,PFGAU -> to editable, middle-click -> to COMPARE
# Shift-{left,middle} click on PFGAU adds truncate to {editable,COMPARE}
# F4: rm bwflag, flossflag, spackleflag, comment out SMOOTH 3D NN button
# F4: add {im,im2} 2D color controls, toggle 2D color overlay and redraw logic
# 2D Col Conjunct controls popup (parallel to F4): right-click "im2:"
# add "OP" button plus entry to run imim2op's in F3-panel
# force show update checks: read surf, redraw-reset-of-failed-2dcol-flag
# change uplevel setfile ... in procs -> add global abbrev to proc
# resolv val2rgblutsub -> val2rgblut in setfile (subjdir MGH lut)
# fscolormap2lut defaults lut if MGH talaiarch labels file missing
# wmfilter in bg, new pidnamerunning proc to test bgproc finished
# purple button feedback for long-running PF/PFGAU, purple kill
# imim2 and im2lut flag unset each other (both off OK)
# rm unnecessary back slashes in curly brace -command args and cmd logic
# report GaussPlaneFilter kfwhm, report correct order regular Trunc+PlaneFilter
# middle-click on TRUNC button applies trunc to editable buffer
# planefilter done popup explains how to save, warns infix name change
# check tmp wmfilter outfile exists before create, rm when done
# catch attempt to add second infix
# clean up run_wmfilter (model for cmdline prog plugin)
# if -pf,-tr infix already there, force overwrites
# rm xhost+ req send inter-process tcl cmd and findsendto from SEND PNT
# tkmeditlogflag, enabledisablelog, setfile does logcmd
# rm canwriteormake, foundbywhich (now in wrappers.tcl)
# rm sendupdate/sendgoto using insecure X11 interprocess comm
# turn off incorrect pixval when zoomed (TODO: fix, turn back on)
# logcmd procs: setfile,test_{write,read}_images,run_wmfilter,check*,def*
# logcmd procs: {read,write}{native,upsamp}{mask,stats},gettseries,do_imim2op
# logcmd all button/entry/check/radio
# bold "tcl:" while recording tcl commands to tkmedit.log, also if start with
# rm unused setsession
# match new tkmedit.c name: $session->$isession (incl's "image")
# fix incorrect entry read on read native mask (was reading native valfile!)
# roi: add combobox dropdown loaded w/BRIK
# valn/valup entry: add combobox dropdown loaded w/BRIK,bfloat
# mskn/mskup entry: add combobox dropdown loaded w/BRIK,bfloat
# read{native,upsamp}mask: better err if select imaginary of complex pair
# block attempt to read non-conforming (non-256/512^3) as upsamp stat/mask/ROI
# readnativemask fixed: mk dbl entries, set overlaymaskflag before do_upsamp
# fix_statpatt_m_if_bfloat before readnativemask
# add CLR button to left of interpolatelut to clear up-sampled buffers
# set valn/valup/mskn/mskup combos to passed-by -real/-upread/-mask/-upmask 
# view right end of value in valn/mskn entries (just init load)
# set roi combo to passed-by -label (MY_AREA+orig.BRIK), see suffix
# combobox for LUT, load w/default lut if none found in scandir
# change startup interface position to match new tighter tkmedit.c glxwin{x,y}0
# wm geometry now uses exported glxwin{x,y,h,w} vs. abs numbers
# ---- csurfsrc-140607.tgz ----
# fix bug in read curv setfile
# TEST1=>TEST (now norm all slices to im2), ALL=>APPLY (now flip to editable)
# Oct2014: fix Return bindings TEST1=>TEST (sorry)
# ---- csurfsrc-150220.tgz ----
# add long/thin fn-F5 micro interface
# add dup "surf" tick on F5 panel (N.B.: must load surf before goto F5)
# ---- csurfsrc-150425.tgz ----
# update to new trace syntax
# ---- csurfsrc-150513.tgz ----
# fix bug in error message, add help for read non-conforming ROI
# rename $label->$uplabel, add $rawlabel
# toggle roin/roiup state (native vs. upsamp) of 3D ROI label line
# readnativeroi: read_native_roi, do_regupsamp_roi, labelflag, redraw
# re-enable SEND/GOTO if turn off all3 while zoomed
# read native stats (valn): accept *.mgz, *.mgh, load into valn dropdown
# middle-click COMPARE swaps *contents* of editable and COMPARE buffers
# middle-click F3 TEST runs locnorm_allslices hack (median, histmax)
# ---- csurfsrc-150728.tgz ----
# tkmedit.tcl: try TextEdit first
# ---- csurfsrc-150910.tgz ----
# popup from im2 now left-click, add R-click help, make action label bold
# respect new helpfiles name: label-> seglabel
# new script_record helpwin
# bold {x,y,z}Tal labels, change to left click
# ---- csurfsrc-150922.tgz ----
# force show "roi" tick on read upsamp roi
# ---- csurfsrc-151010.tgz ----
# small upper left "h" button for tkmedit help
# ---- csurfsrc-151120.tgz ----
# open xterm and run tail -f tkmedit.log in it on record tcl script
# fix log report for sag/hor move, sag/hor tal/native coords
# log GL win arrowkeys (tcl changeslice call from do_one_glx_event)
# log tk win arrowkeys (arrow bindings)
# ---- csurfsrc-151230.tgz ----
# add mac app nap hack
# add combo w/listcmd to "surf:" w/surfs for both hemis, curr first
# add combo w/listcmd to "im:" (for vols written interactively)
# add combo w/listcmd to "im2:" (for vols written interactively)
# add listcmd to "roiup:" combo (for ROIs written interactively)
# add listcmd to "valup:" combo (for upsamp val BRIKs written interactively)
# add listcmd to "mskup:" combo (for upsamp mask BRIKs written interactively)
# add listcmd to "lut:" combo (for luts written interactively)
# localize all help bindings (easier to rearrange)
# copy C/tcl functions/vars into comments
# [see NOTES for combobox listbox fix details]
# 2 sm: -listwidth <pix> *and* listbox.width: surf,im2
# 8 lg: -listwidth <pix>: im,roiup,roin,valup,valn,mskup,mksn,lut
# ---- csurfsrc-160411.tgz ----
# add "m" tick under SMOOTH STATS for $smoothoverlaymaskflag
# make cursor big twice after GOTO for change plane (same plane 2x big OK)
# add surftmp to dropdown list
# ---- csurfsrc-160624.tgz ----
# shift-middle-TRUNC to run countvox (use white_lolim, white_hilim, to log)
# ---- csurfsrc-170320.tgz ----
# fix run_wmfilter non-combobox entry get (had disabled PF,PFGAU Apr2016)
# better log commands for hand normalize, regular and sphere norm
# overload "sph" tick with $gaussnormflag (autoset $sphnormflag)
# overload "COMPARE" button (shift-mid-click) with im2wmedits_to_im
# overload "CORONAL" button (middle-click) with flip_corview_xyz popup
# before flip, if not CORONAL, warn/force CORONAL/center
# ---- csurfsrc-170621.tgz ----
# ---- csurfsrc-171018.tgz ----
# ---- csurfsrc-180125.tgz ----
# put "fm:" READ function into "fs:" READ like tksurfer
# add "annot:" READ: read_mgh_annot
# warn no surface for SURFPAINT curv/fs/annot
# "an:" entry to allow draw only one annot idnum
# <Return> in $oneidnum uses goto_idnum()
# make "annot:" a live-loaded combo dropdown
# ---- csurfsrc-180621.tgz ----
# add "tran" entry to control overlayalpha on large F4 interface
# help message if turn on im2lutoverlayflag with im2 visible
# read second image uses read_sort_mghval2rgblut if FreeSurferColorLUT.txt
# auto-back to first buffer on read MGH segmentation overlay to show it
# F4 interface tick to disable double click
# small "i" left of SAGITTAL to get interface resizing toolbar
# overload "T" on "roiup:" line to run write_segid_timecourses
# overload "W" button on "roiup:" line with write_allsegids
# ---- csurfsrc-190208.tgz ----
# path spaces: listcmd_{surf,ims}: set "$list $memb" => lappend list $memb
# ---- csurfsrc-190722.tgz ----
# middle-click "i" to toggle invert contrast ($midpt => -$midpt)
# popup interface button bar if already there
# macappnaphackflag can force/unforce hack
# ---- csurfsrc-191216.tgz ----
# middle-click overload FILL button: clear_rois
# shift-left-click overload FILL button: vol_rois
# ---- csurfsrc-200629.tgz ----
# parallelize find editor
# ---- csurfsrc-210614.tgz ----
# increase appnap xterm 300->800 msec
# increase appnap xterm 800->2000 msec, fix uncover window
# SAVEIMGS ignores post-startup change to $inoutim (write originally read-in)
# ---- csurfsrc-220324.tgz ----
# fix load tix on IRIX64
# ---- csurfsrc-221002.tgz ----
# 4th overload COMPARE button with visible_to_im (contrast-adj'd to editable)
# mid-click "contr:" label toggles linearflag
# R-clk "PieceWiseLinNorm" F3 interface to control constrast{nochange,slope}
# ctrl-mid-TRUNC cp im->im2 replacing $white_lolim-$white_hilim with $gray_hilim
# SAVEIMG (to orig images name) warns when another images set read in over orig
# 5th overload TRUNC button to replace color range with single color
# new helpfile for TRUNC,PF entries: truncparms
# overload "la" tickbox with toggle $im2boundsflag
# TEST now also writes to tcl cmd log
# add toggle circleflag to "rad" label, fix lib/help/tkmedit/brush
#  [tmp release]
# ctrl-R-click TRUNC for crop_im_using_im2cols_save()
# button bar for overloaded TRUNC button, also put up bounds popup, move it up
# TRUNC popup: disable/gray-out second struct-saving bounds unless im2boundsflag
# fixed introduced mispelled "constrastslop"
#  [tmp release]
# "un" tickbox R of CORONAL to enable/disable undo
# proc editfile pre-deletes any stranded script swapfiles
# TRUNC/PF/PFGAU external program run_wmfilter does saveim_for_undo
# bind tools window cmd-z to undo (edit_pixel 3) -> fix to extracted undo_edit
# add imim2op help to F4 panel ellipse parms
#  [tmp release]
# update cmd-z/Z for extracted saveim's
# ---- csurfsrc-240426.tgz ---- (28mj)
# section dividers for readability
# convert TRUNC butt bind's to procs (rm event generate hacks)
# add buttonbar for CORONAL button (event gen hack to keep binds like SAG/HOR)
# add buttonbar for F3 TEST button (event gen hack to keep binds like SAG/HOR)
# add buttonbar for COMPARE button, change bind's to proc's
# add toggle linearflag button to COMPARE buttonbar
#  [tmp release]
# COMPARE/TRUNC: 'after 1' to fix butt state race after bind -> proc, Mac/Linux
# warn/help for COMPARE with second image not loaded
# add buttonbar for FILL button (event gen hack for compactness)
#  [tmp release]
# add buttonbar for PF, PFGAU buttons (event gen hack for compactness)
# add buttonbar for SMOOTHSTRUCT / SMOOTH STATS button, incl calc grad x/y/z
# rm do_imim2op arg
# add imim2op colspace ellipse to TRUNC button bar (no hotkey), OP ctrls, too
# move up imim2 ctrls to un-overlap TRUNC buttonbar (but not if from OP butt)
# tkmedit.c,tcl: search " invoke" of "buttons $f SOMEBUTTON { }" -> event gen
# COMPARE hotkeys: invoke -> event generate (b/c def now empty cmd, only bind)
# COMPARE hotkeys: add alt/cmd-C for COMPARE
# change invoke to event generate: SMOOTHGAUSS, TRUNC, CORONAL, TEST
#  [tmp release]
# COMPARE: event generate -> call proc, cleanup/compact TRUNC/PF/PFGAU
# "im2:" label popup: better description (test vs. apply)
# "152" tickbox for $xform_mni_305to152_flag under SAGITTAL
# do 305->152 xform if $xform_mni_305to152_flag (6 fwd's, 1 inv)
# ---- csurfsrc-240426.tgz ---- (28mk ??)
# add CsurfMaps1, MY_ANNOT to 'mgh'seglabstemlist to autodetect parcellation mgz
# im2 read *.mgz parcellation also calls seq_num_lut if match Csurf*
# detect {HCP-MMP1,Csurf}ColorLUT-both.txt, remove seq_renum_lut (already seq'd)
# save imgs with "w" warns/allows save to new name ims read in over startup ims
#  [tmp release]
# turn off appnap for all apple silicon (kernvers=BigSur20+)
# ---- csurfsrc-250507.tgz ---- (28mk)
# ---- csurfsrc-250917.tgz ---- (28mk)



# INPROG: colors for HCP-MMP1: both R_ and L_ areas have same idnum!
# INPROG: no way to combine into both-hemis!
# INPROG: either hemi-specific BRIKs, or special purpose tkmedit color lookup


#TODO: tcl log return in intrinsic or Tal coords
#TODO: xxxxxxx -- allow read nonconforming float mgz/mgh
#TODO: add tkmedit-like mask line to tksurfer (replace fieldsign w/mask entry)
#TODO: use/understand scale cmds: coords,get,identify,set to force odd trough

# ~120 places to click in F2

############################################################################
# checks, setup
############################################################################
### block direct run
if ![info exists named_rgbdir] {  ;# tkmedit.c-defined unlikely there bare run
  puts "tkmedit.tcl: ### tk/tix interface:\
        designed for loading by tkmedit binary (28mk)"
  exit
}

### less sloppy/variable first draw on Mac
wm withdraw .

### require tix
if {[exec uname] == "Linux"}  {load libTix8.4.3.so}    ;# LD_LIBRARY_PATH
if {[exec uname] == "Darwin"} {load libTix8.4.3.dylib} ;# DYLD_LIBRARY_PATH
if {[exec uname] == "IRIX" || [exec uname] == "IRIX64"} {
  load libTix8.4.3.so                                  ;# LD_LIBRARYN32_PATH
}

### restore old look
if { $tcl_version == "8.5" } {
  puts "tkmedit.tcl: restore old look"
  ::tk::classic::restore
}
#set tk_strictMotif 1

### source standard widget wrapper code (fonts/colors/popups)
set program tkmedit   ;# find helpfiles
source $env(CSURF_DIR)/lib/tcl/wrappers.tcl

### horrible tmp hack gives 20x draw speedup (Yosemite+ 5sec->250ms, AppNap?)
set mac_appnap_hack 0
if { [exec uname] == "Darwin" } {
  set kernvers [file rootname [file rootname [exec uname -r]]]
  # SnowLeop=10,Yosem=14,ElCap=15,Catalina=19,BigSur=20,Sequoia=24
  #if { $kernvers > 13 } { set mac_appnap_hack 1 }
  if { $kernvers > 13 && $kernvers < 20 } { set mac_appnap_hack 1 }
  unset kernvers
}
if {$macappnaphackflag == -1} { ; }  ;# let this tk decide
if {$macappnaphackflag == 0}  { set mac_appnap_hack 0 }  
if {$macappnaphackflag == 1}  { set mac_appnap_hack 1 }
#set mac_appnap_hack 0  ;# uncomment forces disable hack, overriding all
#set mac_appnap_hack 1  ;# uncomment forces enable hack, overriding all

############################################################################
# globals
############################################################################
### so script can determine who called it
set interfacefile tkmedit.tcl
set tkmedittcl_version 28mk

### for send (inter X process auto send commented out)
#set thisapp [tk appname]   ;# maybe multiple copies

### tkmedit.c: C/tcl functions defined at startup (copied 24 Jan 2016)
# functions:
#   open_window resize_window_intstep move_window raise_window redraw
#   upslice downslice rotate_brain_x rotate_brain_y rotate_brain_z
#   translate_brain_x translate_brain_y translate_brain_z
#   read_images write_images write_dipoles write_decimation goto_point
#   goto_point_coords write_point coords_to_talairach talairach_to_coords
#   read_invert_mni_tal read_invert_12_tal read_hpts read_htrans write_htrans
#   print3dhist save_rgb save_rgb_named_orig set_scale mirror
#   read_fieldsign read_fsmask read_binary_curv calcgradampdd calcgradamp
#   smooth_3d smooth_3d_dx smooth_3d_dy smooth_3d_dz smooth_3d_nn
#   flip_corview_xyz read_second_images
#   read_binary_surface read_binary_surface2 # norm_slice norm_allslices
#   norm_allslices_toim2 locnorm_allslices swap_imim2 imim2op 
#   smooth_stats_3d find_retin_borders fill_roi write_roi write_roi_label
#   read_roi read_rawdata read_val2rgblut write_val2rgblut
#   write_roi_timecourses read_native_roi read_native_stat do_regupsamp_roi
#   do_regupsamp_stat clear_upsamp_stat write_regupsamp_stat
#   read_regupsamp_stat count_voxels left_click
#   write_segid_timecourses write_allsegids

### tkmedit.c: C/tcl vars defined at startup
# boolean:
#   maxflag surfflag surfloaded surf2loaded editflag fieldsignflag curvflag
#   drawsecondflag inplaneflag linearflag truncflag circleflag promptflag
#   followglwinflag all3flag changeplanelock truncphaseflag revphaseflag
#   phasecontourflag phasecontourmodflag phasecontoursflag
#   overlayflag overlayloaded complexvalflag labelflag labelmaskflag
#   overlaymaskflag overlaymaskloaded overlaymasknativeloaded im2loaded
#   zoomflag tiffoutflag writeallCORflag bigcursorflag nocursorflag
#   opencursorflag asciifromtagsflag doublebufferflag tkmeditlogflag
#   sphnormflag interpolatelutflag im2lutoverlayflag imim2elloverlayflag
#   showavgcycflag openglwindowflag
# int:
#   zf xdim ydim imnr1 plane imc ic jc prad pradlast dip_spacing
#   editedimage surflinewidth white_lolim white_hilim gray_hilim 
#   lim3 lim2 lim1 lim0 selectedpixval cursorgb editimgtype colscale
#   phasecontour_bright phasecontours stimcycles glxdepth 
#   stat_xdim stat_ydim stat_zdim overlayalpha wmfillthresh
#   glxwinx glxwiny glxwinw glxwinh
# double:
#   bwslope bwmid fsthresh fscale ffrac3 ffrac2 ffrac1 ffrac0
#   xtalairach ytalairach ztalairach
#   fthresh fmid fslope sfthresh sfmid sfslope angle_cycles angle_offset
#   fadef ipsiyellowfact phasecontour_min phasecontour_max phasecontoursfrac
#   truncphasemin truncphasemax minstatcolscale maxstatcolscale cslope cmid
#   fillrad imcolcent im2colcent imcolrad im2colrad gradampfac gradpddfac
# string:
#   home isession scandir subject imtype imtype2 surface inoutim sfname
#   subjtmpdir dip dec hpts htrans rgb named_rgbdir fs fm curv insurf
#   transform script regdat rawdata rawlabel uplabel label2
#   statpatt_r statpatt_i statpatt_m statpatt
#   upstatpatt_r upstatpatt_i upstatpatt_m upstatpatt
#   val2rgblut tkmeditinterface genstrret_1k

### slider sizing
set sclenx 150
set scleny 140

### literal subdirs for setfile (scandir is exported C var)
set bemdir bem
set labeldir label
set rgbdir rgb
set surfdir surf
set fsdir fs
set scriptsdir scripts
set mridir mri

### file lists for setfile
set sessionfiles { val label uplabel rawlabel val2rgblut
                   statpatt upstatpatt statpatt_m upstatpatt_m }
set mrifiles { inoutim val2rgblutsub }
set surffiles { insurf curv }
set fsfiles { fs fm }
set scriptsfiles { script }
set bemfiles { dip dec hpts htrans }
set labelfiles { anlabel }
set rgbfiles { rgb }
set rgbdirs { named_rgbdir num_rgbdir }   ;# not files but same expansions

### list of mri dir im's (all *.mgz matched)
set surflooklist { orig white smoothwm graymid pial surftmp } ;# patt* -> .reg
set cordirlooklist { orig T1 T2 PD brain wm filled }

### list .mgz's (incl byte and int) to autoload as segmentation overlay
set mghseglabstemlist { aseg aseg.auto aseg.auto_noCCseg
                    aparc+aseg wmparc wm.asegedit wm.seg
                    ribbon lh.ribbon rh.ribbon
                    aparc.a2005s+aseg aparc.a2009s+aseg
                    CsurfMaps1 MY_ANNOT HCP-MMP1 }

### default transform
set xrot 0
set yrot 0
set zrot 0
set xtrans 0
set ytrans 0

### default norm direction
set normdir 1

### default brush
set circleflag 1
set inplaneflag 1
set selectedpixval 1

### save panel
set userok 0
set inoutim_orig $inoutim
set inoutim_curr $inoutim

### slice (slider!) limits
set cormax [expr $imnr1-1]
set cormin 0
set sagmax [expr $xdim/$zf-1]
set sagmin 0
set hormax [expr $ydim/$zf-1]
set hormin 0
set newimc 127
set newic 127
set newjc 127
set dontzoom FALSE
set parallelupdate TRUE

### slice planes
set cor 0
set hor 1
set sag 2
set changeplanelock 0

### editimgtype
set noimage -1
set cordir   0
set mghfile  1
set mgzfile  2

### default Gaussian smooth (FWHM=sigma*2.35) (TODO: tkmedit.c export)
set kcnt 5      ;# Gaussian kernel cell width
set kfwhm 1.5   ;# Gaussian kernel FWHM

### default flip (none)
set flip_curr_x_to  x
set flip_curr_y_to  y
set flip_curr_z_to  z

### non-modal popups
set boundseditctrlswin ""
set contrrampctrlswin ""
set flipctrlswin ""
set intbuttbar ""
set imim2opctrlswin ""
set imim2testctrlswin ""

### default imim2op operation
set imim2opnum 0

### catch zoom/unzoom transitions (because 2 chks call zoomhackscalerescurs)
set lastzoomflag 0

### manage long-running wmfilter in bg (only 1)
set bgpid -1
set wmfilterkilledflag 0

### TODO: freesurfer aseg: decode semantics (now just rand color)
set fscolormap talairach.label_intensities.txt
#set fscolormap aseg.auto_noCCseg.label_intensities.txt
set randlut256flag 0    ;# force full/256 rand LUT rand even if talfile there

### log file to record interface-run tcl cmds (C-functs, vars)
#set tkmeditlogflag 0 ;# dbl-clk script entry toggles, set here biffs tkmed opt

############################################################################
# procedures
############################################################################
proc editfile { file } {   ;# order: (vigterm,vixterm),gedit,nedit,xedit
  global env

  if [info exists env(CSURFEDITORVIGTERM)] {
    set swp [file dirname $file]/.[file tail $file].swp    ;# pre-rm any
    if [file exists $swp] { exec rm -f $swp }
    if [foundbywhich gnome-terminal] {
      exec gnome-terminal --geometry +50+630 --execute vi "$file" >& /dev/null &
    } else {
      exec xterm -geometry +50+630 -e vi "$file" >& /dev/null & ;#nullelse huptk
    }
  } elseif [info exists env(CSURFEDITORVIXTERM)] {
    set swp [file dirname $file]/.[file tail $file].swp    ;# pre-rm any
    if [file exists $swp] { exec rm -f $swp }
    if [foundbywhich xterm] {
      exec xterm -geometry +50+630 -e vi "$file" >& /dev/null & ;#nullelse huptk
    } else { puts "tkmedit.tcl: ### xterm not found" }
  } else {
    foreach editor { /System/Applications/TextEdit.app/Contents/MacOS/TextEdit \
                     /Applications/TextEdit.app/Contents/MacOS/TextEdit \
                     gedit nedit xedit "" } {
      if [foundbywhich $editor] { break }
    }
    if {$editor == ""} {
      puts "tkmedit.tcl: ### no text editor found (tried TextEdit,gedit,xedit)"
    } elseif [string match *TextEdit $editor] {
      if ![file exists $file] { exec touch $file }
      update idletasks
      #exec open -e "$file" >& /dev/null &  ;# N.B.: multiple TextEdits in bg
      exec open -e "$file"
    } else {
      exec $editor "$file" >& /dev/null &
    }
  }
}

### 'set' plus csurf-specific glob
proc setfile { varName value } {  ;# makes "varName"abbrev if it doesn't exist
  upvar $varName localvar               ;# setfile dec */bem/brain3d5-5.dec
  upvar ${varName}abbrev localabbrev    ;# setfile rgb ~/tmp/myrgb
  global home subject                   ;# setfile val /tmp/data.w
  global env                            ;# setfile script local.tcl
  global isession                       ;# setfile named_rgbdir ~/tmp/myrgb
  global sessionfiles                   ;# setfile script #/builtin.tcl
  global imtype
  global surfdir fsdir scriptsdir bemdir labeldir rgbdir mridir scandir
  global surffiles fsfiles scriptsfiles bemfiles labelfiles rgbfiles mrifiles
  global rgbdirs

  logcmd "setfile $varName $value"
  ### set subdir using name of var and premade lists
  if       { [lsearch -exact $surffiles $varName] >= 0 } {
    set subdir $surfdir
  } elseif { [lsearch -exact $fsfiles $varName] >= 0 } {
    set subdir $fsdir
  } elseif { [lsearch -exact $scriptsfiles $varName] >= 0 } {
    set subdir $scriptsdir
  } elseif { [lsearch -exact $bemfiles $varName] >= 0 } {
    set subdir $bemdir
  } elseif { [lsearch -exact $labelfiles $varName] >= 0 } {
    set subdir $labeldir
  } elseif { [lsearch -exact $rgbfiles $varName] >= 0 } {
    set subdir $rgbdir
  } elseif { [lsearch -exact $sessionfiles $varName] >= 0 } {
    set subdir $scandir
  } elseif { [lsearch -exact $mrifiles $varName] >= 0 } {
    set subdir $mridir
    if { $varName == "val2rgblutsub" } {
      set varName val2rgblut     ;# resolve sess/subj ambig
      upvar ${varName}abbrev localabbrev
    }
  } elseif { [lsearch -exact $rgbdirs $varName] >= 0 } {
    set subdir .
  } else {
    puts "bad arg: don't know how to set file type: $varName"
    puts "  setfile {$surffiles} value"
    puts "  setfile {$fsfiles} value"
    puts "  setfile {$scriptsfiles} value"
    puts "  setfile {$bemfiles} value"
    puts "  setfile {$labelfiles} value"
    puts "  setfile {$rgbfiles} value"
    puts "  setfile {$sessionfiles} value"
    puts "  setfile {$mrifiles} value"
    puts "  setfile {$rgbdirs} value"
    prompt
    return
  }
  ### do expansions and make fullname
  if { [string range $value 0 0] == "/"} {
    set fullname $value
  } elseif { [string range $value 0 0] == "~"} {
    if { [string length $value] > 1 && [string range $value 1 1] != "/" } {
      puts "tkmedit: can't reset subject home dir without restarting"
      prompt
      return
    }
    if { [string length $value] < 3 } {
      puts "tkmedit: no filename specified for setfile"
      prompt
      return
    }
    set tildegone [string range $value 2 end]
    set subdir [file dirname $tildegone]      ;# overwrite, may be multilevel
    set filename [file tail $tildegone]
    if { $subdir == "." } {
      set fullname $home/$subject/$filename
    } else {
      set fullname $home/$subject/$subdir/$filename
    }
  } elseif { [string range $value 0 0] == "*"} {
    set stargone [string range $value 2 end]
    set fullname $isession/$stargone
  } elseif { [string range $value 0 0] == "#" } {
    set poundgone [string range $value 2 end]
    set fullname $env(CSURF_DIR)/lib/tcl/$poundgone
  } else {  ;# relative (guess session vs. subjects)
    if { $subdir == $surfdir } {
      set fullname $home/$subject/$subdir/$value
    } elseif {$subdir == $bemdir} {
      set fullname $home/$subject/$subdir/$value
    } elseif { $subdir == $fsdir } {
      set fullname $isession/$subdir/$value
    } elseif { $subdir == $scriptsdir } {
      set fullname [exec pwd]/$value
    } elseif { $subdir == "." } {
      set fullname $isession/$value
    } elseif { $subdir == $mridir } {
      if { $imtype == "local" } {
        set fullname $isession/$value
      } else {
        set fullname $isession/$subdir/$value
      }
    } else {
      set fullname $isession/$subdir/$value
    }
  }
  set localvar $fullname
  #puts $fullname

  ### attempt to re-abbrev (first ~, then *, else set absolute)
  if {$varName != "script"} {
    set homename $home/$subject
    set homelen [string length $homename]
    set endhome [incr homelen -1]
    set begintail [incr homelen 1]
    if { $homename == [string range $fullname 0 $endhome] } {
      set localabbrev ~[string range $fullname $begintail end]
      return
    }
    set sessionlen [string length $isession]
    set endsession [incr sessionlen -1]
    set begintail [incr sessionlen 1]
    if { $isession == [string range $fullname 0 $endsession] } {
      set localabbrev *[string range $fullname $begintail end]
      return
    }
  } else {
    set scripthome $env(CSURF_DIR)/lib/tcl
    set scripthomelen [string length $scripthome]
    set endscript [incr scripthomelen -1]
    set begintail [incr scripthomelen 1]
    if { "$scripthome" == "[string range $fullname 0 $endscript]" } {
      set localabbrev #[string range $fullname $begintail end]
      return
    }
  }
  set localabbrev $fullname
}

proc resettransform { } {
  global xrot yrot zrot xtrans ytrans
  set xrot 0; set yrot 0; set zrot 0
  set xtrans 0; set ytrans 0
}

proc fixdipdecname { name1 name2 op } {
  global dip dec dip_spacing
  global dipabbrev decabbrev
  # read curr abbrev entry
  setfile dip $dipabbrev
  setfile dec $decabbrev
  set diptail [format "brain3d%d.dip" $dip_spacing]
  set dectail [format "brain3d%d.dec" $dip_spacing]
  # work on abs b/c file dirname does its own ~ expand!
  set dip [file dirname $dip]/$diptail
  set dec [file dirname $dec]/$dectail
  # update entry abbrevs
  setfile dip $dip
  setfile dec $dec
}  

proc fixfocus { name1 name2 op } {
  global plane cor hor sag changeplanelock
  if {$changeplanelock} { return }
  if {$plane==$cor} { focus .mri.main.left.view.pan.cor.bot.sc }
  if {$plane==$hor} { focus .mri.main.left.view.pan.hor.bot.sc }
  if {$plane==$sag} { focus .mri.main.left.view.pan.sag.bot.sc }
}

proc zoomcoords { name1 name2 op } { ;# trace nice/tkslice, update real/pix
  global zf newimc newic newjc imc ic jc
  global dontzoom
  if {$dontzoom} { return }
  set imc [expr $newimc*$zf]
  set ic [expr $newic*$zf]
  set jc [expr $newjc*$zf]
}

proc unzoomcoords { } {  ;# calc nice/tkslice from real/pix (stop loop)
  global zf newimc newic newjc imc ic jc
  global dontzoom
  set dontzoom TRUE
  set newimc [expr $imc/$zf]
  set newic [expr $ic/$zf]
  set newjc [expr $jc/$zf]
  set dontzoom FALSE
}

proc talupdate { name1 name2 op } {
  global xtalairach ytalairach ztalairach
  coords_to_talairach
  # next required: touch tcl because trace doesn't report C updates
  set xtalairach [format "%2.1f" $xtalairach]
  set ytalairach [format "%2.1f" $ytalairach]
  set ztalairach [format "%2.1f" $ztalairach]
}

proc pixvaltitle { name1 name2 op } {  ;# 0.2 msec
  global selectedpixval subject plane cor hor sag zoomflag
  if {$plane==$cor} { set note "right=L" }
  if {$plane==$hor} { set note "right=L" }
  if {$plane==$sag} { set note "right=A" }
  set pixval $selectedpixval
  if {$zoomflag} { set pixval "##" }  ;# TODO:
  wm title . "tkmedit: val=$pixval  ($note, MGH: [getmghvolindex])"
}

proc gotoslice { slice } {
  global plane cor hor sag
  global newimc newic newjc
  if {$plane==$cor} { set newimc $slice }
  if {$plane==$hor} { set newic $slice }
  if {$plane==$sag} { set newjc $slice }
  redraw
}

proc changeslice { dir } {  ;# up/downslice is C, changeslice only in do_one_gl
  global zf newimc newic newjc imc ic jc
  global plane cor hor sag
  if {$dir == "up"} { upslice; redraw }
  if {$dir == "down"} { downslice; redraw }
  #if {$plane==$cor} { set newimc [expr $imc/$zf] }
  #if {$plane==$hor} { set newic [expr $ic/$zf] }
  #if {$plane==$sag} { set newjc [expr $jc/$zf] }
  logcmd "set plane $plane"
  if {$plane==$cor} {
    set newimc [expr $imc/$zf]
    logcmd "set newimc $newimc"
    logcmd "redraw"  ;# actually done above
  }
  if {$plane==$hor} {
    set newic [expr $ic/$zf]
    logcmd "set newic $newic"
    logcmd "redraw"
  }
  if {$plane==$sag} {
    set newjc [expr $jc/$zf]
    logcmd "set newjc $newjc"
    logcmd "redraw"
  }
}

proc zoomhackscalerescurs { } { ;# brainstem zoom hacks: scale res, mv cursor
  global zoomflag all3flag lastzoomflag zf tkmeditinterface
  global imc ic jc
  global imnr1 ydim xdim

  if {$zoomflag && !$lastzoomflag} { ;# chg to zoom: curr + scaled dist to cent
    set imc [expr 2*$imc - $zf*$imnr1/2]  ;# ugh: just imnr1 not zf/pix-zoomed
    set ic  [expr 2*$ic  - $ydim/2]
    set jc  [expr 2*$jc  - $xdim/2]
    redraw; unzoomcoords
  }
  if {!$zoomflag && $lastzoomflag} { ;# chg to unzoom: solve for unfixed above
    set imc [expr $imc/2 + $zf*$imnr1/4]
    set ic  [expr $ic/2  + $ydim/4]
    set jc  [expr $jc/2  + $xdim/4]
    redraw; unzoomcoords
  }
  set lastzoomflag $zoomflag

  set f .mri.main.left.view.pan
  set f2 .mri.main.left.head.pnt
  if {$all3flag} {
    if {$zoomflag} { ;# disable wrong (cent,x2) intrinsic/Tal coords, SEND/GOTO
      $f.cor.bot.sc config -resolution 2
      $f.sag.bot.sc config -resolution 2
      #$f.hor.bot.sc config -resolution 2   ;# TODO: even only
      $f.sag.bot.none.e config -state disabled
      $f.cor.bot.none.e config -state disabled
      $f.hor.bot.none.e config -state disabled
      $f.sag.top.xTal.e config -state disabled
      $f.cor.top.yTal.e config -state disabled
      $f.hor.top.zTal.e config -state disabled
      "$f2.aSEND PNT.bu" config -state disabled
      "$f2.aGOTO PNT.bu" config -state disabled
    } else {
      $f.cor.bot.sc config -resolution 1
      $f.sag.bot.sc config -resolution 1
      $f.hor.bot.sc config -resolution 1
      $f.sag.bot.none.e config -state normal
      $f.cor.bot.none.e config -state normal
      $f.hor.bot.none.e config -state normal
      $f.sag.top.xTal.e config -state normal
      $f.cor.top.yTal.e config -state normal
      $f.hor.top.zTal.e config -state normal
      "$f2.aSEND PNT.bu" config -state normal
      "$f2.aGOTO PNT.bu" config -state normal
    }
    .mri.main.left.head.pnt.aall.ck config -text "all3"
    pack .mri.main.left.head.pnt.az -after .mri.main.left.head.pnt.aall
  } else {
    pack forget .mri.main.left.head.pnt.az
    .mri.main.left.head.pnt.aall.ck config -text "all3views"
    if {!$zoomflag} {  ;# enable if unset all3 while zoomed
      $f.cor.bot.sc config -resolution 1
      $f.sag.bot.sc config -resolution 1
      $f.hor.bot.sc config -resolution 1
      $f.sag.bot.none.e config -state normal
      $f.cor.bot.none.e config -state normal
      $f.hor.bot.none.e config -state normal
      $f.sag.top.xTal.e config -state normal
      $f.cor.top.yTal.e config -state normal
      $f.hor.top.zTal.e config -state normal
      "$f2.aSEND PNT.bu" config -state normal
      "$f2.aGOTO PNT.bu" config -state normal
    }
  }
  if {$tkmeditinterface == "mini3" || $tkmeditinterface == "macro" } {
    pack forget .mri.main.left.head.pnt.az
    .mri.main.left.head.pnt.aall.ck config -text "all"
  }
}

proc rotheadpts { angle } {
  global plane cor hor sag

  if {$plane==$cor} { rotate_brain_y [expr $angle*10.0] }
  if {$plane==$hor} { rotate_brain_z [expr -$angle*10.0] }
  if {$plane==$sag} { rotate_brain_x [expr $angle*10.0] }
}

proc transheadpts { dist axis } {
  global plane cor hor sag

  if {$axis=="x"} {
    if {$plane==$cor} { translate_brain_x [expr -$dist] }
    if {$plane==$hor} { translate_brain_x [expr -$dist] }
    if {$plane==$sag} { translate_brain_y $dist }
  }
  if {$axis=="y"} {
    if {$plane==$cor} { translate_brain_z $dist }
    if {$plane==$hor} { translate_brain_y $dist }
    if {$plane==$sag} { translate_brain_z $dist }
  }
}

proc save_rgb_named { name } {   ;# save_rgb_named wrapper for interface update
  global rgb named_rgbdir rel_rgbname

  set rel_rgbname $name                            ;# cp arg->global for uplevel
  uplevel {setfile rgb $named_rgbdir/$rel_rgbname} ;# echo cfunc; update abbrev
  save_rgb_named_orig $rel_rgbname                 ;# cfunc
}

proc enabledisablelog { } {
  global tkmeditlogflag logid ffont ffontb

  if ![canwriteormakefile tkmedit.log] {
    confirmalert "can't write logfile to [pwd]"
    set tkmeditlogflag 0
    set logid -1
    return
  }
  if {$logid != -1} { logclose }
  if {$tkmeditlogflag} {
    confirmalert " turn OFF log interface tcl cmds to:\n\
                   \n    [pwd]/tkmedit.log"
    set tkmeditlogflag 0
  } else {
    confirmalert " turn ON log interface tcl cmds to:\n\
                   \n    [pwd]/tkmedit.log"
    logopen tkmedit.log  ;# N.B. always overwrites
    set tkmeditlogflag 1
    exec xterm -geometry +595+700 -e tail -f [pwd]/tkmedit.log >& /dev/null &
  }
  if {$tkmeditlogflag} {
    .mri.main.right.cmp.im2.la config -font $ffontb
  } else {
    .mri.main.right.cmp.im2.la config -font $ffont
  }
}

proc fix_statpatt_if_bfloat { } {  ;# example bfloat -> printf, before read
  global statpatt statpattabbrev

  if { [string match *_???.bfloat $statpatt] } {
    set stem [string range $statpatt 0 [expr [string length $statpatt] - 12]]
    setfile statpatt ${stem}_%03d.bfloat   ;# also remakes abbrev (=entry)
  }
}

proc fix_statpatt_m_if_bfloat { } {  ;# example bfloat -> printf, before read
  global statpatt_m statpatt_mabbrev

  if { [string match *_???.bfloat $statpatt_m] } {
    set stem \
      [string range $statpatt_m 0 [expr [string length $statpatt_m] - 12]]
    setfile statpatt_m ${stem}_%03d.bfloat   ;# also remakes abbrev (=entry)
  }
}

proc findsendto { } {  ;# ignored unless display NULL
  global fulltksurfer

  set fulltksurfer ""
  catch { set fulltksurfer [lrange [exec ps -af | grep /tksurfer] 7 7] }
}

proc testclose { } {   ;# called from wrappers.tcl, intercept in C event loop 
  global editedimage inoutim bgpid

  if [pidnamerunning $bgpid wmfilter] {
    puts "tkmedit.tcl: ### wmfilter still running in background  ...killed"
    exec kill -9 $bgpid
    set bgpid -1
  }
  if [file exists /tmp/TkmeditTmpHist.txt] {
    set tmphist /tmp/TkmeditTmpHist.txt
    puts "tkmedit.tcl: rm -f $tmphist"
    puts [exec rm -f $tmphist]
  }
  if {$editedimage} {
    if { [string match *.mgz $inoutim] || [string match *.mgh $inoutim] } {
      set filemsg $inoutim 
    } else {
      set filemsg ${inoutim}/COR-[format "%03d..." $editedimage]
    }
    set resp [okclose $filemsg]
    if {$resp > 1} { write_images }
    if {$resp > 0} { exit }
  } else {
    destroy .
    exit        ;# takes GLX window with it
  }
}

proc runscript { { script none } } {
  global env

  set scriptdir $env(CSURF_DIR)/lib/tcl
  if {$script == "none"} {
    puts "permanent scripts in $scriptdir:"
    puts [exec ls -C $scriptdir]
    puts "for tkmedit -> mri2mpg.tcl"
  } else {
    if { [string match ./* $script] || [string match /* $script] } {
      if [file exists $script] {
        uplevel "set userok; source $script" ;# quote:subst here before uplevel
      } else { puts "tkmedit.tcl: ### script $script not found" }
    } else {
      if [file exists $scriptdir/$script] {
        uplevel "set userok; source $scriptdir/$script"
      } else { puts "tkmedit.tcl: ### script $script not found in $scriptdir" }
    }
  }
}

proc test_write_images { newpolicy  } {
  global inoutim editedimage editimgtype mghfile mgzfile cordir writeallCORflag
  global inoutim_curr inoutim_orig

  set edimg $editedimage
  if {$writeallCORflag} { set edimg 1 }
  set imfile ""
  if { $editimgtype == $mghfile || $editimgtype == $mgzfile } {
    if { ![string match *.mgz $inoutim] && ![string match *.mgh $inoutim] } {
      confirmalert "tkmedit won't convert .mgz/.mgh to COR dir"
      return
    }
    set imfile $inoutim
  } elseif { $editimgtype == $cordir } {
    if { [string match *.mgz $inoutim] || [string match *.mgh $inoutim] } {
      confirmalert "tkmedit won't convert COR dir to .mgz/.mgz\
                    \n\nuse mri_convert instead"
      return
    }
    set imfile $inoutim/COR-[format "%03d" $edimg]
    if ![file exists $inoutim] {
      exec mkdir $inoutim
      logcmd "exec mkdir $inoutim"
    }
  } else { }
  if {$imfile == ""} { return }
  if {$newpolicy != "blocknew" && $newpolicy != "allownew"} { return }
  if {$newpolicy == "blocknew"} {
    if { "$inoutim_orig" != "$inoutim_curr" } {
      if ![okreplace "" \
         "Current images:\
      \n\n    $inoutim_curr\
      \n\nwere read in over startup images:\
      \n\n    $inoutim_orig\
      \n\nThe SAVEIMGS button always saves to startup image!\
      \n\nIf you want to save current images to a different name,\
        \nuse the \"W\" button on the \"im:\" line" \
           "Use Original Imageset Name"] {
        confirmalert "Nothing saved"
        return
      }
    }
  }
  if {$newpolicy == "allownew"} {  ;# just warn
    if { "$inoutim_orig" != "$inoutim_curr" } {
      if ![okreplace "" \
         "Current images:\
      \n\n    $inoutim_curr\
      \n\nwere read in over startup images:\
      \n\n    $inoutim_orig\
      \n\nSave to current name in \"im:\" entry?" \
           "Save to current \"im:\" entry name"] {
        confirmalert "Nothing saved"
        return
      }
    }
  }
  testreplace $imfile write_images   ;# writes to current $inoutim
}

proc test_read_images { } {
  global editedimage inoutim drawsecondflag

  if {$editedimage} {
    if ![okreplace $editedimage \
       " Current images are edited:\n\n\
         Discard edits and Read \"[file tail $inoutim]\" anyway?\n\
         (or Cancel, save curr images w/SAVE IMGS, and try again)" \
         "Discard/Read"] {
      confirmalert "New image set: \"[file tail $inoutim]\" not read"
      return
    }
    read_images
    logcmd "read_images"
    set editedimage 0
    logcmd "set editedimage 0"
  } else {
    read_images
    logcmd "read_images"
  }
  #if {$drawsecondflag} { .mri.main.right.cmp.im2.aCOMPARE.bu invoke }
  if {$drawsecondflag} { compare_im_im2 }  ;# b/c invoke won't activate bind
}

proc setsmoothtype { } {
  global overlayflag

  if {$overlayflag} {
    .mri.main.farright.aSMOOTHGAUSS.bu config -text "SMOOTH STATS"
  } else {
    .mri.main.farright.aSMOOTHGAUSS.bu config -text "SMOOTHSTRUCT"
  }
}

proc pidnamerunning { pid name } {
  set psout -1
  # err to pipe for ps setuid/DYLD warning
  if { [exec uname] == "Darwin" || [exec uname] == "Linux" } {
    catch {set psout [exec ps uxww |& grep "$pid " | grep -v grep]} ;#BSD/Linux
  } else {
    catch {set psout [exec ps af |& grep "$pid " | grep -v grep]}   ;#oldsys5
  }
  if [string match *${name}* "$psout"] { return 1 } else { return 0 }
}

proc run_wmfilter { operation targbuf { force 0 } } {  ;# wmfilter wrapper
  global env subject mridir overlayflag inoutim inoutimabbrev editedimage
  global white_lolim white_hilim gray_hilim kfwhm kcnt openglwindowflag
  global bgcol actbgcol runbgcol runactbgcol bgpid wmfilterkilledflag

  ### check inputs
  if {$operation != "stdtrunc" && $operation != "gauss" && \
      $operation != "gausstrunc" && $operation != "justtrunc"} { return }
  if {$targbuf != "to_buf1" && $targbuf != "to_buf2"} { return }
  if ![foundbywhich wmfilter] {
    confirmalert "wmfilter not on path ...plane filter skipped"
    return
  }
  if {!$force && $kcnt != 5 && $kcnt != 7} {
    confirmalert "Bad kernel width (left of fwhm): $kcnt\n\nAllowed:  5 or 7"
    return
  }
  if {$overlayflag} {  ;# TODO: allow for filtering upsampled stats
    confirmalert "Can't plane-filter overlay data"
    return
  }
  if [pidnamerunning $bgpid wmfilter] {
    if {$force} {
      exec kill -9 $bgpid
      puts "tkmedit.tcl: ### killed background wmfilter (pid=$bgpid)"
      set bgpid -1
      set wmfilterkilledflag 1
    } else {
      if ![okreplace "" "PlaneFilter still running in background\n\nKill it?" \
          "Kill PlaneFilter"] {
        return
      } else {
        exec kill -9 $bgpid
        puts "tkmedit.tcl: ### killed background wmfilter (pid=$bgpid)"
        set bgpid -1
        set wmfilterkilledflag 1
        return
      }
    }
  }

  ### setup announcement
  if {$operation == "stdtrunc" && $targbuf == "to_buf1"} {
    set altmsg " Trunc+PlaneFilter+ReTrunc editable image\
                 (kcnt=$kcnt, median-like):\n\n\
                 (N.B.: takes a min)"
  }
  if {$operation == "stdtrunc" && $targbuf == "to_buf2"} {
    set altmsg " Trunc+PlaneFilter+ReTrunc output to im2/COMPARE\
                 (kcnt=$kcnt, median-like):\n\n\
                 (N.B.: takes a min)"
  }
  if {$operation == "gauss" && $targbuf == "to_buf1"} {
    set altmsg " GaussPlaneFilter editable image\
                 (kcnt=$kcnt, fwhm=$kfwhm):\n\n\
                 (N.B.: takes a few min)"
  }
  if {$operation == "gauss" && $targbuf == "to_buf2"} {
    set altmsg " GaussPlaneFilter output to im2/COMPARE\
                 (kcnt=$kcnt, fwhm=$kfwhm):\n\n\
                 (N.B.: takes a few min)"
  }
  if {$operation == "gausstrunc" && $targbuf == "to_buf1"} {
    set altmsg " GaussPlaneFilter+Trunc editable image\
                 (kcnt=$kcnt, fwhm=$kfwhm):\n\n\
                 (N.B.: takes a few min)"
  }
  if {$operation == "gausstrunc" && $targbuf == "to_buf2"} {
    set altmsg " GaussPlaneFilter+Trunc output to im2/COMPARE\
                 (kcnt=$kcnt, fwhm=$kfwhm):\n\n\
                 (N.B.: takes a few min)"
  }
  if {$operation == "justtrunc" && $targbuf == "to_buf1"} {
    set altmsg "SimpleTrunc editable image? (lo=$white_lolim hi=$white_hilim)"
  }
  if {$force} {
    puts "tkmedit.tcl: $altmsg"
  } else {
    set butlab "Run Plane Filter"
    if {$operation == "justtrunc"} { set butlab "Simple Truncate" }
    if ![okreplace $editedimage $altmsg $butlab] { return }
  }

  ### add infix to im entry
  setfile inoutim [.mri.main.right.fi.im.cbx subwidget entry get] ;# read curr
  set infile $inoutim
  set outinfix pf       ;# inserted into "im:" name
  if {$operation == "justtrunc"} { set outinfix tr }
  if {$force} { ;# add infix if not there, else overwrite
    if { [string match *-$outinfix.mgz $inoutim] || \
         [string match *-$outinfix.mgh $inoutim] || \
         [string match *-$outinfix $inoutim] } {
      puts \
       "tkmedit.tcl: ### $inoutim\nalready has infix (-$outinfix): overwriting"
      set outdir [file dirname $inoutim]
      set outstem [file rootname [file tail $inoutim]]
    } else {
      set outdir [file dirname $inoutim]
      set outstem [file rootname [file tail $inoutim]]-$outinfix
    }
  } else {
    if { [string match *-$outinfix.mgz $inoutim] || \
         [string match *-$outinfix.mgh $inoutim] || \
         [string match *-$outinfix $inoutim] } {
      confirmalert " Image name already has infix (-$outinfix):\
                     \n\n    $inoutim\n\n\
                     Remove it to redo planefilter operation"
      return
    }
    set outdir [file dirname $inoutim]
    set outstem [file rootname [file tail $inoutim]]-$outinfix
  }

  if [string match *.mgz $inoutim] {
    set outtail $outstem.mgz
  } elseif [string match *.mgh $inoutim] {
    set outtail $outstem.mgh
  } else {
    set outtail $outstem  ;# COR dir
  }
  set outfile $outdir/$outtail
  if {!$force && [file exists $outfile] } {
    if ![okreplace $editedimage \
           " Outfile to be used for temp filter output:\
             \n\n    $outfile\n\n\
             already exists ...OK to overwrite?" "Overwrite"] { return }
  }

  ### setup/run one of four operations
  if {$operation == "stdtrunc"} {
    set cmd "wmfilter $infile $outfile \
      -gaussflag 0 -kcnt $kcnt \
      -white_hilim $white_hilim -white_lolim $white_lolim \
      -gray_hilim $gray_hilim"
    set bu .mri.main.right.wm.trufil.aPF.bu
    set msg "tkmedit.tcl: run anisotropic wmfilter... \[N.B. takes a few min\]"
  }
  if {$operation == "gauss"} {
    set cmd "wmfilter $infile $outfile -gaussflag 1 -kcnt $kcnt -kfwhm $kfwhm"
    set bu .mri.main.right.wm.trufil.aPFGAU.bu
    set msg "tkmedit.tcl: run anisotropic wmfilter... \[N.B. takes a few min\]"
  }
  if {$operation == "gausstrunc"} {
    set cmd "wmfilter $infile $outfile \
      -gaussflag 1 -kcnt $kcnt -kfwhm $kfwhm \
      -white_hilim $white_hilim -white_lolim $white_lolim"
    set bu .mri.main.right.wm.trufil.aPFGAU.bu
    set msg "tkmedit.tcl: run anisotropic wmfilter... \[N.B. takes a few min\]"
  }
  if {$operation == "justtrunc"} {
    set cmd "wmfilter $infile $outfile \
      -planefilterflag 0 -white_hilim $white_hilim -white_lolim $white_lolim"
    set bu .mri.main.right.wm.trufil.aTRUNC.bu
    set msg "tkmedit.tcl: run simple truncation..."
  }
  # in bg keeps interface live, do ps 1/sec to update purple button
  puts "tkmedit.tcl: $cmd"
  puts $msg
  $bu config -background $runbgcol -activebackground $runactbgcol
  update idletasks
  set bgpid [eval exec $cmd &]
  while { [pidnamerunning $bgpid wmfilter] } {
    after 1000; update; if {$openglwindowflag} { redraw }
  }
  $bu config -background $bgcol -activebackground $actbgcol
  set bgpid -1
  logcmd "eval exec $cmd &"
  # N.B.: curf VOLUME kill -9 tkmedit leaves wmfilter running in bg

  ### read output file back into editable or second buf
  if {$targbuf == "to_buf1"} {
    if {$wmfilterkilledflag} {
      set wmfilterkilledflag 0
    } else {
      puts "tkmedit.tcl: output saved in editable buffer"
      set inoutim $outfile
      setfile inoutim $inoutim  ;# update: global abbrev
      saveim_for_undo  ;# normally tkmedit.c internal, here b/c extern wmfilter
      logcmd "saveim_for_undo"
      if {$force} {
        read_images
        logcmd "read_images"
      } else {
        test_read_images  ;# logs
      }
      if {$openglwindowflag} {
        redraw
        logcmd "redraw"
      }
      set editedimage 1
      logcmd "set editedimage 1"
    }
  }
  if {$targbuf == "to_buf2"} {
    puts "tkmedit.tcl: output saved in second buffer"
    .mri.main.right.cmp.im2.cbx subwidget entry delete 0 end
    .mri.main.right.cmp.im2.cbx subwidget entry insert 0 $outtail
    .mri.main.right.cmp.im2.br invoke
  }

  ### delete read-back-in file
  if { [string match *.mgz $outfile] || [string match *.mgh $outfile] } {
    exec rm -f $outfile
    logcmd "exec rm -f $outfile"
  }
  if [file exists $outfile/COR-001] {
    exec rm -rf $outfile
    logcmd "exec rm -rf $outfile"
  }
  if {!$force && $targbuf == "to_buf1"} {
    confirmalert " Plane Filter finished (operation=$operation)\n\n\
                   To save result, use \"SAVE IMGS\"\n\
                   or \"W\" button on \"im:\" line\n\n\
                   N.B.: infix (-$outinfix) added to image name"
  }
  update idletasks
  logcmd "update idletasks"
}

proc checkoverlay { } {
  global overlayflag overlayloaded tkmeditinterface

  logcmd "set overlayflag $overlayflag"
  if { $overlayflag && !$overlayloaded } {
    confirmalert " No overlay dataset.  Use csurf VOLUME-STATS\n\
                   or restart tkmedit with these additional args:\n\n\
                   -real <format> *or* -complex <fmt_r> <fmt_i>\n\
                   -nslices <num>\n\
                   -statres <x> <y>\n\
                   -regdat <filename>"
    set overlayflag 0
    logcmd "set overlayflag $overlayflag"
  }
  if { $overlayflag && $tkmeditinterface != "mini2" } { mini2 }
  setsmoothtype
  redraw
  logcmd "redraw"
}

proc checksurface { } {
  global surfflag surfloaded surf2loaded tkmeditinterface

  logcmd "set surfflag $surfflag"
  if { $surfflag } {
    if { !$surfloaded && !$surf2loaded } {
      if {$tkmeditinterface == "micro"} {
        confirmalert "No surface loaded\
                      \n\nGo back to F1-F4 interface and\
                      \nand use \"R\" button on \"surf:\" line"
      } else {
        confirmalert "No surface loaded\n\nUse \"R\" button on \"surf:\" line"
      }
      set surfflag 0
      logcmd "set surfflag $surfflag"
    }
  }
  redraw
  logcmd "redraw"
}

proc listcmd_surf { combo } {
  global env subject hemi insurf surfdir surflooklist

  set hemi [string range [file tail $insurf] 0 1]
  if {$hemi == "rh"} { set hems "rh lh" } ;# load curr hemi first (no div)
  if {$hemi == "lh"} { set hems "lh rh" }
  #set fullfilelist ""
  set fullfilelist {}
  foreach hem $hems {
    foreach surf $surflooklist {  ;# match surf's w/suffixes (incl sphere.reg)
      set globsurfs \
        [glob -nocomplain $env(SUBJECTS_DIR)/$subject/$surfdir/$hem.$surf*]
      foreach fullfile $globsurfs {  ;# rm dups, irrelevant
        if { ![string match *.nofix $fullfile] &&
             ![string match *.crv $fullfile] &&
             ![string match *.H $fullfile] &&
             ![string match *.K $fullfile] &&
             ![string match *.mgh $fullfile] } {
          #set fullfilelist "$fullfilelist $fullfile"
          lappend fullfilelist $fullfile
        }
      }
    }
  }
  # manually re-abbreviate vs. clog log with many setfiles
  set abbrevlist ""
  foreach fullfile $fullfilelist {
    set abbrevlist "$abbrevlist ~/$surfdir/[file tail $fullfile]"
  }
  $combo subwidget listbox delete 0 end
  foreach abbrev $abbrevlist { $combo insert end $abbrev }
}

proc listcmd_ims { combo abbrevtype } {
  global env subject mridir cordirlooklist

  if {$abbrevtype != "full" && $abbrevtype != "min"} { set abbrevtype full }
  # ordered set basic volumes (cordir's and/or mgz's) at top
  set fullfilelist {}
  foreach dir $cordirlooklist {
    set fullfile $env(SUBJECTS_DIR)/$subject/$mridir/$dir
    if [file exists $fullfile] { lappend fullfilelist $fullfile }
    set fullfile $env(SUBJECTS_DIR)/$subject/$mridir/$dir.mgz
    if [file exists $fullfile] { lappend fullfilelist $fullfile }
  }
  # omit MGH orig dir if orig.mgz there (contains original non-conforming)
  set foundorigmgz 0
  foreach fullfile $fullfilelist {
    if [string match */orig.mgz $fullfile] { set foundorigmgz 1 }
  }
  set fullfilelist2 {}
  foreach fullfile $fullfilelist {
    if { [string match */orig $fullfile] && $foundorigmgz} { continue }
    lappend fullfilelist2 $fullfile
  }
  # tack on other *.mgz's
  set fullfilelist $fullfilelist2
  set globlist [lsort [glob -nocomplain \
    $env(SUBJECTS_DIR)/$subject/$mridir/*.mgz]] ;# ignore .mgh (usu 1D) for now
  foreach fullfile $globlist {
    set found 0
    foreach fullfile2 $fullfilelist2 {
      if {"$fullfile" == "$fullfile2"} { set found 1 }
    }
    if {$found} { continue }
    if [file exists $fullfile] { lappend fullfilelist $fullfile }
  }
  # manually re-abbreviate (two ways) vs. clog log with many setfiles
  set abbrevlist {}
  foreach fullfile $fullfilelist {
    if {$abbrevtype == "full"} {
      lappend abbrevlist ~/$mridir/[file tail $fullfile]
    }
    if {$abbrevtype == "min"} {  ;# rm ~/mri/ and .mgz for small im2 entry
      lappend abbrevlist [file rootname [file tail $fullfile]]
    }
  }
  $combo subwidget listbox delete 0 end
  foreach abbrev $abbrevlist { $combo insert end $abbrev }
}

proc listcmd_getbriks { combo { opt nobfloat } } {
  global isession scandir

  set fullfilelist [glob -nocomplain $isession/$scandir/*+orig.BRIK]
  if {$opt == "alsobfloat"} {
    set fullfilelist "$fullfilelist\
      [glob -nocomplain $isession/$scandir/*_???.bfloat]"
  }
  # manually re-abbreviate vs. clog log with many setfiles
  set abbrevlist ""
  foreach fullfile $fullfilelist {
    set abbrevlist "$abbrevlist */$scandir/[file tail $fullfile]"
  }
  $combo subwidget listbox delete 0 end
  foreach abbrev $abbrevlist { $combo insert end $abbrev }
}

proc getstatbfloatinfix { bfloatpatt } {   ;# else "notbfloat" or "badinfix"
  # e.g. */phavg-polair-all/polair1-1-vreg+orig_r_%03d.bfloat
  if ![string match *.bfloat $bfloatpatt] { return notbfloat }
  set stem [string range $bfloatpatt 0 [expr [string length $bfloatpatt] - 13]]
  set infix badinfix
  foreach inf { _r _i _x _y _a _d _g _f _e } {
    if [string match *$inf $stem] {
      set stem [string range $stem 0 [expr [string length $stem] - 3]]
      set infix $inf
    }
  }
  return $infix
}

proc getstatbrikinfix { brik } {   ;# else "notbrik" or "badinfix"
  # e.g., */phavg-polair-all/polair1-1-vreg+orig_r+orig.BRIK
  if ![string match *+orig.BRIK $brik] { return notbrik }
  set stem [string range $brik 0 [expr [string length $brik] - 11]]
  set infix badinfix
  foreach inf { _r _i _x _y _a _d _g _f _e } {
    if [string match *$inf $stem] {
      set stem [string range $stem 0 [expr [string length $stem] - 3]]
      set infix $inf
    }
  }
  return $infix
}

proc checkconform { brikorhead } {
  # notfound, notbrik, noheader, brik-256x256x256 (or512), nonconforming-NxNxN
  if ![file exists $brikorhead] { return notfound }
  if { ![string match *+orig.BRIK $brikorhead] && \
       ![string match *+orig.HEAD $brikorhead] } { return notbrik }
  set header $brikorhead
  if [string match *+orig.BRIK $brikorhead] {
    set header [file rootname $brikorhead].HEAD
  }
  if ![file exists $header] { return noheader }
  set id [open $header r]
  set lines [split [read $id] \n]
  set i 0
  close $id
  foreach line $lines {
    if [string match *DATASET_DIMENSIONS* $line] { set i 2; continue }
    if {$i == 2 && [lindex $line 0] == "count"} { set i 1; continue }
    if {$i == 1} {
      set xres [lindex $line 0]
      set yres [lindex $line 1]
      set slices [lindex $line 2]
      set i 0
    }
  }
  if {$xres == 256 && $yres == 256 && $slices == 256} {return brik-256x256x256}
  if {$xres == 512 && $yres == 512 && $slices == 512} {return brik-512x512x512}
  return nonconforming-${xres}x${yres}x${slices}
}

proc readnativeroi { } {
  global rawlabel rawlabelabbrev labelflag

  setfile rawlabel [.mri.main.right.fi.roin.cbx subwidget entry get] ;#update
  if ![string match *+orig.BRIK $rawlabel] {
    confirmalert "Read Native ROI: curr only reads *+orig.BRIK"
    return
  }
  if ![file exists $rawlabel] {
    confirmalert "Read Native ROI: file not found:\n\n$rawlabel"
    return
  }
  read_native_roi
  logcmd "read_native_roi"
  do_regupsamp_roi
  logcmd "do_regupsamp_roi"
  set labelflag 1
  logcmd "set labelflag $labelflag"
  redraw
  logcmd "redraw"
}

proc readupsamproi { } {
  global uplabel uplabel_abbrev labelflag

  setfile uplabel [.mri.main.right.fi.roiup.cbx subwidget entry get]
  if ![string match *+orig.BRIK $uplabel] {
    confirmalert "Read ROI: currently only reads \$stem+orig.BRIK"
    return
  }
  if ![file exists $uplabel] {
    confirmalert "Read ROI: file not found:\n\n$uplabel"
    return
  }
  set briksize [checkconform $uplabel]
  if { $briksize != "brik-256x256x256" && $briksize != "brik-512x512x512" } {
    confirmalert " Read ROI: input file:\n\n\    $uplabel\n\n\
                   not 256^3 or 512^3:  $briksize\n\n\
                   First click \"roiup:\" => \"roin:\" to load this file"
    return
  }
  forcebrikMSBfirst $uplabel
  read_roi
  logcmd "read_roi"
  set labelflag $labelflag  ;# force show tick reset in C code
}

proc readnativestats { } {   ;# read any real, auto-read imag (req std format)
  global complexvalflag statpatt statpattabbrev

  setfile statpatt [.mri.main.right.fi.valn.cbx subwidget entry get] ;#update
  if { ![string match *_%03d.bfloat $statpatt] &&
       ![string match *+orig.BRIK $statpatt] &&
       ![string match *.mgz $statpatt] &&
       ![string match *.mgh $statpatt] } {
    confirmalert "Read Native Stats: only reads (float) formats:\
   \n\n    suffix:  +orig.BRIK\n    suffix:  .bfloat\n    suffix:  .mgz (.mgh)"
    return
  }
  if [string match *_%03d.bfloat $statpatt] {
    set firstbfloat [format $statpatt 0]
    if ![file exists $firstbfloat] {
      confirmalert "Read Native Stats: file not found:\n\n$firstbfloat"
      return
    }
  }
  if { [string match *+orig.BRIK $statpatt] && ![file exists $statpatt] } {
    confirmalert "Read Native Stats: file not found:\n\n$statpatt"
    return
  }
  forcebrikMSBfirst $statpatt
  read_native_stat 0
  logcmd "# next: 0=real, 1=imag, 2=mask"
  logcmd "read_native_stat 0"
  set infix ""
  if {$complexvalflag} {
    if [string match *_%03d.bfloat $statpatt] {
      set infix [getstatbfloatinfix $statpatt]
    }
    if [string match *+orig.BRIK $statpatt] {
      set infix [getstatbrikinfix $statpatt]
    }
    if {$infix == "_r"} {
      set imaginfix "_i"
    } elseif {$infix == "_x"} {
      set imaginfix "_y"
    } elseif {$infix == "_i"} {
      confirmalert " Read Native Stats: select real-valued member\n\
                     of this complex pair (infix: _r)"
      return
    } elseif {$infix == "_y"} {
      confirmalert " Read Native Stats: select real-valued member\n\
                     of this complex pair (infix: _x)"
      return
    } else {
      confirmalert " Read Native Stats: can't auto-read complex\n\
                     data w/non-standard bfloat/BRIK filename:\
                     \n\n    $statpatt\n\n\
                     Need one of these:\n\
                     \n    real brik:   <stem>{_r,_x}+orig.BRIK\
                     \n    real bfloat: <stem>{_r,_x}_%03d.bfloat"
      return
    }
    set origstatpatt $statpatt
    if [string match *_%03d.bfloat $statpatt] {
      set stem [string range $statpatt 0 [expr [string length $statpatt] - 15]]
      setfile statpatt ${stem}${imaginfix}_%03d.bfloat
    }
    if [string match *+orig.BRIK $statpatt] {
      set stem [string range $statpatt 0 [expr [string length $statpatt] - 13]]
      setfile statpatt ${stem}${imaginfix}+orig.BRIK
    }
    forcebrikMSBfirst $statpatt
    read_native_stat 1
    logcmd "# next: 0=real, 1=imag, 2=mask"
    logcmd "read_native_stat 1"
    setfile statpatt $origstatpatt
  }
  do_regupsamp_stat  ;# does 1-3 just-read-in briks, dependent on flag state
  logcmd "do_regupsamp_stat"
}

proc readnativemask { } {   ;# read any mask
  global overlaymaskflag statpatt statpatt_m statpatt_mabbrev

  setfile statpatt_m [.mri.main.right.fi.mskn.cbx subwidget entry get] ;#update
  if { ![string match *_%03d.bfloat $statpatt_m] &&
       ![string match *+orig.BRIK $statpatt_m] } {
    confirmalert "Read Native Mask: curr only reads *+orig.BRIK, *.bfloat"
    return
  }
  if [string match *_%03d.bfloat $statpatt_m] {
    set firstbfloat [format $statpatt_m 0]
    if ![file exists $firstbfloat] {
      confirmalert "Read Native Mask: file not found:\n\n$firstbfloat"
      return
    }
  }
  if { [string match *+orig.BRIK $statpatt_m] && ![file exists $statpatt_m] } {
    confirmalert "Read Native Stats: file not found:\n\n$statpatt_m"
    return
  }
  forcebrikMSBfirst $statpatt_m
  set statpattSAV $statpatt
  setfile statpatt $statpatt_m
  read_native_stat 2
  logcmd "# next: 0=real, 1=imag, 2=mask"
  logcmd "read_native_stat 2"
  setfile statpatt $statpattSAV

  # N.B.: have to redo amp regupsamp here because do_reg does up to 3
  set overlaymaskflag 1   ;# do first so mask subsamped too!
  logcmd "set overlaymaskflag 1"
  do_regupsamp_stat       ;# does 1-3 just-read-in briks, dep on flag state
  logcmd "do_regupsamp_stat"
  secondsquashents
}

proc readupsampstats { } {   ;# read any real, auto-read imag req's std format
  global complexvalflag upstatpatt upstatpattabbrev

  setfile upstatpatt [.mri.main.right.fi.valup.cbx subwidget entry get]
#xxxxxxx -- allow read conforming float mgz/mgh
  if ![string match *+orig.BRIK $upstatpatt] {
    confirmalert "Read UpSamp Stats: currently only reads \$stem+orig.BRIK"
    return
  }
  if ![file exists $upstatpatt] {
    confirmalert "Read UpSamp Stats: file not found:\n\n$upstatpatt"
    return
  }
  set briksize [checkconform $upstatpatt]
  if { $briksize != "brik-256x256x256" && $briksize != "brik-512x512x512" } {
    confirmalert " Read UpSamp Stats: input file:\n\n\    $upstatpatt\n\n\
                   not 256^3 or 512^3:  $briksize\n\n\
                   First click \"valup:\" => \"valn:\" to load this file"
    return
  }
  forcebrikMSBfirst $upstatpatt
  read_regupsamp_stat 0
  logcmd "# next: 0=real, 1=imag, 2=mask"
  logcmd "read_regupsamp_stat 0"
  set infix ""
  if {$complexvalflag} {
    set infix [getstatbrikinfix $upstatpatt]
    if {$infix == "_r"} {
      set imaginfix "_i"
    } elseif {$infix == "_x"} {
      set imaginfix "_y"
    } elseif {$infix == "_i"} {
      confirmalert " Read UpSamp Stats: select real-valued member\n\
                     of this complex pair (infix: _r)"
      return
    } elseif {$infix == "_y"} {
      confirmalert " Read UpSamp Stats: select real-valued member\n\
                     of this complex pair (infix: _x)"
      return
    } else {
      confirmalert " Read UpSamp Stats: can't auto-read complex\n\
                     data with non-standard BRIK filename:\
                     \n\n\    $upstatpatt\n\n
                     Need realbrik nameformat: <stem>{_r,_x}+orig.BRIK"
      return
    }
    set origupstatpatt $upstatpatt
    set stem \
      [string range $upstatpatt 0 [expr [string length $upstatpatt] - 13]]
    setfile upstatpatt ${stem}${imaginfix}+orig.BRIK
    forcebrikMSBfirst $upstatpatt
    read_regupsamp_stat 1
    logcmd "# next: 0=real, 1=imag, 2=mask"
    logcmd "read_regupsamp_stat 1"
    setfile upstatpatt $origupstatpatt
  }
}

proc writeupsampstats { } {  ;# write any real, auto-write imag req's std fmt
  global complexvalflag upstatpatt upstatpattabbrev

  setfile upstatpatt [.mri.main.right.fi.valup.cbx subwidget entry get]
  if ![string match *.BRIK $upstatpatt] {
    confirmalert "Write UpSamp Stats: currently only writes \$stem+orig.BRIK"
    return
  }
  write_regupsamp_stat 0
  logcmd "# next: 0=real, 1=imag, 2=mask"
  logcmd "write_regupsamp_stat 0"
  if {$complexvalflag} {
    set infix [getstatbrikinfix $upstatpatt]
    if {$infix == "_r"} {
      set imaginfix "_i"
    } elseif {$infix == "_x"} {
      set imaginfix "_y"
    } else {
      confirmalert " Write UpSamp Stats: can't auto-write complex\n\
                     data with non-standard BRIK filename\n\n\
                     Need realbrik nameformat:\n\n    <stem>{_r,_x}+orig.BRIK"
      return
    }
    set origupstatpatt $upstatpatt
    set stem \
      [string range $upstatpatt 0 [expr [string length $upstatpatt] - 13]]
    setfile upstatpatt ${stem}${imaginfix}+orig.BRIK
    write_regupsamp_stat 1
    logcmd "# next: 0=real, 1=imag, 2=mask"
    logcmd "write_regupsamp_stat 1"
    setfile upstatpatt $origupstatpatt
  }
}

proc readupsampmask { } {  ;# read already reg/upsamp mask
  global upstatpatt upstatpatt_m upstatpatt_mabbrev

  setfile upstatpatt_m [.mri.main.right.fi.mskup.cbx subwidget entry get]
  if ![string match *+orig.BRIK $upstatpatt_m] {
    confirmalert "Read UpSamp Mask: currently only reads \$stem+orig.BRIK"
    return
  }
  if ![file exists $upstatpatt_m] {
    confirmalert "Read UpSamp Mask: file not found:\n\n$upstatpatt_m"
    return
  }
  set briksize [checkconform $upstatpatt_m]
  if { $briksize != "brik-256x256x256" && $briksize != "brik-512x512x512" } {
    confirmalert " Read UpSamp Mask: input file:\n\n\    $upstatpatt_m\n\n\
                   not 256^3 or 512^3:  $briksize\n\n\
                   First click \"mskup:\" => \"mskn:\" to load this file"
    return
  }
  forcebrikMSBfirst $upstatpatt_m
  read_regupsamp_stat 2
  logcmd "# next: 0=real, 1=imag, 2=mask"
  logcmd "read_regupsamp_stat 2"
  set overlaymaskflag 1
  logcmd "set overlaymaskflag 1"
  secondsquashents
}

proc writeupsampmask { } {
  global upstatpatt upstatpatt_m upstatpatt_mabbrev

  setfile upstatpatt_m [.mri.main.right.fi.mskup.cbx subwidget entry get]
  if ![string match *.BRIK $upstatpatt_m] {
    confirmalert "Write UpSamp Stats: currently only writes \$stem+orig.BRIK"
    return
  }
  set upstatpattSAV $upstatpatt
  setfile upstatpatt $upstatpatt_m
  write_regupsamp_stat 2
  logcmd "# next: 0=real, 1=imag, 2=mask"
  logcmd "write_regupsamp_stat 2"
  setfile upstatpatt $upstatpattSAV
}

proc gettseries { } {
  global isession scandir uplabel regdat rawdata

  # check vs. most other simpler buttons that just leave Cfunc error in log
  setfile uplabel [.mri.main.right.fi.roiup.cbx subwidget entry get]
  if ![string match *+orig.BRIK $uplabel] {
    confirmalert " Write ROI Timecourses: bad ROI filename\n\n\
                   Must be: <any_stem>+orig.BRIK"
    return
  }
  if ![file exists $uplabel] {
    confirmalert "Write ROI Timecourses:  ROI:\n\n   $uplabel\n\nnot found"
    return
  }
  if ![file exists $regdat] {
    confirmalert "Write ROI Timecourses:  regdat:\n\n   $regdat\n\nnot found"
    return
  }
  if ![file exists $rawdata] {
   confirmalert "Write ROI Timecourses:  rawdata:\n\n   $rawdata\n\nnot found"
    return
  }
  # copy infix/outfile str processing from tkmedit.c write_roi_timecourses()
  set infix [file tail $uplabel]
  set infix [string range $infix 0 [expr [string length $infix] - 11]]
  set file1 $isession/$scandir/$infix.raw
  if [testreplace $file1 write_roi_timecourses] {
    confirmalert \
      "raw timecourses for:\n\n   $uplabel\n\nwritten to:\n\n   $file1"
  }
}

proc getsegidtseries { } {
  global isession scandir regdat rawdata im2iloaded

  if {!$im2iloaded} {
    confirmalert "Write SegID Timecourses:  No 3D segmentation loaded\
              \n\n  (1) pick aseg/aparc from \"im2:\" dropdown\
                \n  (2) load using \"R\""
    return
  }
  set segid [file tail [.mri.main.right.fi.roiup.cbx subwidget entry get]]
  if ![string is int $segid] {
    confirmalert "Write SegID Timecourses:  requested segid:\
              \n\n    $segid\
              \n\nnot an integer"
    return
  }
  if ![file exists $regdat] {
    confirmalert "Write SegID Timecourses:  regdat:\n\n   $regdat\n\nnot found"
    return
  }
  if ![file exists $rawdata] {
   confirmalert "Write SegID Timecourses:  rawdata:\n\n   $rawdata\n\nnot found"
    return
  }
  # cp str processing from tkmedit.c write_segid_timecourses
  set outfile $isession/$scandir/segid=$segid.raw
  write_segid_timecourses $segid
  confirmalert "raw timecourses for:\n\n    segid = $segid\
            \n\nwritten to:\n\n   $outfile"
}

proc forcebrikMSBfirst { inbrik } {
  logcmd "# next: tkmedit.tcl proc"
  logcmd "forcebrikMSBfirst $inbrik"
  if { [file extension $inbrik] != ".BRIK" } { return }
  set inhead [file rootname $inbrik].HEAD
  if { ![file exists $inhead] || ![file exists $inbrik] } { return }
  set idinhead [open $inhead r]
  set lines [split [read $idinhead] \n]
  close $idinhead
  set tmphead /tmp/TmpAfniHead.[pid]
  if { [catch {set idtmphead [open $tmphead w 0666]}] } { return }
  set checkhead ok
  foreach line $lines {
    if [string match *'LSB_FIRST~* $line] {
      puts $idtmphead "'MSB_FIRST~"
      set checkhead swap
    } else {
      puts $idtmphead $line
    }
  }
  close $idtmphead   ;# TODO: extra CR appended
  set briktypes [readheadbriktypes $inhead]
  if {$briktypes != ""} {
    set firsttype [lindex $briktypes 0]
    foreach type $briktypes {
      if { $type != $firsttype } {
        confirmalert "BRICK_TYPES not all same:\n\n$briktypes\n\n...can't swap"
        return
      }
    }
  } else { set firsttype short }  ;# like AFNI

  if {$checkhead == "swap"} {
    if { $firsttype == "short" } {
      set swapper 2swap
    } elseif { $firsttype == "float" } {
      set swapper 4swap
    } else {
      confirmalert "can't swap this BRIK type: $firsttype"
      return
    }
    if { ![canwriteormakefile $inhead] || ![canwriteormakefile $inbrik] } {
      confirmalert "$inhead is LSBfirst but permissions prevent swap"
      exec rm -f $tmphead
      return
    }
    if ![foundbywhich $swapper] {
      confirmalert "$inhead is LSBfirst but AFNI $swapper not on path"
      return
    }
    exec $swapper -q $inbrik
    set ret [catch { exec mv -f $tmphead $inhead } err]
    if {$ret} { confirmalert "fail: mv -f $tmphead $inhead" }
    confirmalert "$inbrik swapped to MSBfirst"
  }
  if {$checkhead == "ok" && [file exists $tmphead] } { exec rm -f $tmphead }
}

proc readheadbriktypes { header } {
  set id [open $header r]
  set lines [split [read $id] \n]
  close $id
  set i 0
  set typecodelist ""
  foreach line $lines {
    if [string match *BRICK_TYPES* $line] { set i 2; continue }
    if { $i == 2 } { set i 1; set count [lindex $line 2]; continue }
    if { $i == 1 } {
      set typecodelist "$typecodelist $line"
      if { [llength $typecodelist] < $count } { continue }
      set i 0
    }
  }
  set typelist ""
  foreach typecode $typecodelist {
    set type $typecode
    if {$typecode == 0} { set type byte }
    if {$typecode == 1} { set type short }
    if {$typecode == 2} { set type int }
    if {$typecode == 3} { set type float }
    if {$typecode == 4} { set type double }
    if {$typecode == 5} { set type complex }
    if {$typecode == 6} { set type rgb }
    set typelist "$typelist $type"
  }
  return $typelist
}

proc secondsquashents { } {
  global overlaymaskflag
  if {$overlaymaskflag} {
    pack .mri.main.right.wm.thr.thr.st
    pack .mri.main.right.wm.thr.md.st
    pack .mri.main.right.wm.thr.sl.st
    .mri.main.right.wm.thr.thr.la config -text "thr" -width 2
    .mri.main.right.wm.thr.md.la config -text "md" -width 2
    .mri.main.right.wm.thr.sl.la config -text "sl" -width 1
  } else {
    pack forget .mri.main.right.wm.thr.thr.st
    pack forget .mri.main.right.wm.thr.md.st
    pack forget .mri.main.right.wm.thr.sl.st
    .mri.main.right.wm.thr.thr.la config -text "fthresh:" -width 6
    .mri.main.right.wm.thr.md.la config -text "fmid:" -width 4
    .mri.main.right.wm.thr.sl.la config -text "fslope:" -width 5
  }
}

proc listcmd_lut { combo } {
  global isession scandir

  set fullfilelist [glob -nocomplain $isession/$scandir/*.lut]
  # manually re-abbreviate vs. clog log with many setfiles
  set abbrevlist ""
  foreach fullfile $fullfilelist {
    set abbrevlist "$abbrevlist */$scandir/[file tail $fullfile]"
  }
  $combo subwidget listbox delete 0 end
  foreach abbrev $abbrevlist { $combo insert end $abbrev }
}

proc defmissinglutfile { } {
  global val2rgblut
  if ![file exists $val2rgblut] {
    if ![canwriteormakefile $val2rgblut] {
      confirmalert "Permissions don't allow create default color look-up table"
      return
    }
    set id [open $val2rgblut w 0644]
    puts $id \
      "### def val->RGB lookup table (val:float,ascending,negOK, r,g,b:0-255)"
    puts $id "# val\tred\tgreen\tblue"
    puts $id "0.0\t88\t88\t88"
    puts $id "1.0\t255\t0\t0"
    puts $id "2.0\t0\t0\t255"
    puts $id "3.0\t0\t255\t0"
    close $id
    logcmd "# made def colorLUT: $val2rgblut"
  } else { return }
}

# begin TRUNC no-arg button procs
############################################################################
proc trunc_tmpim1 { } {
  global truncflag

  if {$truncflag} {
    set truncflag 0
    logcmd "set truncflag 0"
    # problem after convert bind -> proc: button never appears sunken
    # 'after 1' fixes this on Mac/Linux (not-yet-debugged race cond?)
    after 1 ".mri.main.right.wm.trufil.aTRUNC.bu config -relief raised"
  } else {
    set truncflag 1
    logcmd "set truncflag 1"
    # same
    after 1 ".mri.main.right.wm.trufil.aTRUNC.bu config -relief sunken"
  }
  redraw
  logcmd "redraw"
}

proc trunc_toim1 { } {
  run_wmfilter justtrunc to_buf1
}

proc trunc_countim1_inlims { } {
  global white_lolim white_hilim

  countvox $white_lolim $white_hilim
}

proc trunc_edim1_im2inlims_togray { } {
  global im2loaded white_lolim white_hilim gray_hilim

  if {!$im2loaded} {
    confirmalert "Can't crop im using im2:\n\n...first load an im2"
    return
  }
  if [okreplace "" \
         "OK to edit im, replacing voxels where im2 has colors\
        \nwithin/including:\
      \n\n    $white_lolim - $white_hilim    (2 entries right of TRUNC)\
      \n\nwith new color:\
      \n\n    $gray_hilim ?    (entry right PF, use 1 for \"EDITED_TO_OFF\")" \
         "Crop Editable"] {
    crop_im_using_im2cols
    logcmd "crop_im_using_im2cols"
    redraw
    logcmd "redraw"
  } else {
    confirmalert "editable contents unchanged"
  }
}

proc trunc_edim1_im2inlims_togray_savelims { } {
  global im2loaded white_lolim white_hilim gray_hilim edit_lolim2 edit_hilim2

  if {!$im2loaded} {
    confirmalert "Can't crop im using im2:\n\n...first load an im2"
    return
  }
  if [okreplace "" \
         "OK to edit im, replacing voxels where im2 has colors\
        \nwithin/including:\
      \n\n    $white_lolim - $white_hilim    (2 entries right of TRUNC)\
      \n\nwith new color:\
      \n\n    $gray_hilim ?    (entry right PF, use 1 for \"EDITED_TO_OFF\")\
      \n\nbut only if editable image (im) NOT within/including:\
      \n\n    $edit_lolim2 - $edit_hilim2    (see R-clk TRUNC entries popup)" \
         "Crop Editable"] {
    crop_im_using_im2cols_save
    logcmd "crop_im_using_im2cols_save"
    redraw
    logcmd "redraw"
  } else {
    confirmalert "editable contents unchanged"
  }
}

proc trunc_cpim1toim2_im1inlims_togray { } {
  global white_lolim white_hilim gray_hilim

  if [okreplace "" \
         "OK to copy im to im2, replacing all voxels w/cols\
        \nwithin/including:\
      \n\n    $white_lolim - $white_hilim    (see 3 entries right of TRUNC)\
      \n\nwith new color:\
      \n\n    $gray_hilim ?    (use 1 for \"EDITED_TO_OFF\")" \
         "Replace Color to im2"] {
    cp_im_to_im2_replacing_cols
    logcmd "cp_im_to_im2_replacing_cols"
    redraw
    logcmd "redraw"
  } else {
    confirmalert "im2 contents unchanged"
  }
}
############################################################################
# end TRUNC no-arg button procs

# begin COMPARE no-arg button procs
############################################################################
proc compare_im_im2 { } {
  global drawsecondflag im2loaded

  if {$drawsecondflag} {
    set drawsecondflag 0
    logcmd "set drawsecondflag 0"
    # problem after convert bind -> proc: button never appears sunken
    # 'after 1' fixes this on Mac/Linux (not-yet-debugged race cond?)
    after 1 ".mri.main.right.cmp.im2.aCOMPARE.bu config -relief raised"
  } else {
    if {!$im2loaded} {
      confirmalert "No second image loaded yet:\
                \n\nSelect from mid-bottom \"im2:\" dropdown, then \"R\" (read)\
                \n\n(to change second image, select/read new)"
      return
    }
    set drawsecondflag 1
    logcmd "set drawsecondflag 1"
    # same
    after 1 ".mri.main.right.cmp.im2.aCOMPARE.bu config -relief sunken"
  }
  redraw
  logcmd "redraw"
}

proc compare_swap_im_im2 { } {
  global editedimage 

  if [okreplace "" \
       "OK to swap the CONTENTS of the\neditable and COMPARE (im2) buffers?" \
       "Swap Contents"] {
    if {$editedimage} {
      if [okreplace "" \
           "Current images edited:\
            \n\nStill OK to swap editable and COMPARE (im2)?\
            \nN.B. can't save COMPARE (im2) buffer" \
           "Swap Contents"] {
        swap_imim2
        logcmd "swap_imim2"
        #TODO: change to event generate b/c def left-click empty cmd, only bind
        #.mri.main.right.cmp.im2.aCOMPARE.bu invoke
        #.mri.main.right.cmp.im2.aCOMPARE.bu invoke
        redraw
        logcmd "redraw"
      }
    } else {
      swap_imim2
      logcmd "swap_imim2"
      #TODO: change to event generate b/c def left-click empty cmd, only bind
      #.mri.main.right.cmp.im2.aCOMPARE.bu invoke
      #.mri.main.right.cmp.im2.aCOMPARE.bu invoke
      redraw
      logcmd "redraw"
    }
  } else {
    confirmalert "editable and COMPARE contents unchanged"
  }
}

proc compare_xferedits_im2_toim1 { } {
  global im2loaded

  if [okreplace "" \
       "OK to transfer edited pixels from im2 to\neditable buffer?" \
       "Transfer im2 edits to editable"] {
    if {!$im2loaded} {
      confirmalert "Transfer edits failed:\n\n...first load an im2"
    } else {
      im2wmedits_to_im
      logcmd "im2wmedits_to_im"
      redraw
      logcmd "redraw"
    }
  } else {
    confirmalert "editable contents unchanged"
  }
}

proc compare_contradj_to_editable { } {
  global linearflag

  if [okreplace "" \
       "OK to copy visible/contrast-adjusted image to editable buffer?\
   \n\nN.B.: set linearflag 1 (F4 panel) so contrast not re-applied\
     \nN.B.: may change edited-to-blk (1) and edited-to-wht (255)" \
       "Copy constrast-adj'd to editable"] {
    visible_to_im
    logcmd "visible_to_im"
    set linearflag 1
    logcmd "set linearflag 1"
    redraw
    logcmd "redraw"
  } else {
    confirmalert "editable contents unchanged"
  }
}

proc compare_togglelinearflag { } {
  global linearflag

  set linearflag [expr !$linearflag]
  logcmd "set linearflag $linearflag"
  redraw
  logcmd "redraw"
}
############################################################################
# end COMPARE no-arg button procs

proc fscolormap2lut { } {
  global env subject mridir im2lutoverlayflag fscolormap im2loaded im2iloaded
  global val2rgblut val2rgblutabbrev imim2elloverlayflag drawsecondflag
  global randlut256flag im2abbrev

  # errs
  if {!$im2lutoverlayflag} { ;# maybe clear prev overlay
    redraw
    logcmd "redraw"
    return
  }
  if {!$im2loaded && !$im2iloaded} {
    confirmalert " No label overlay to display\n\n\
                   First load label file into im2 with \"R\":\n\n\
                   Examples:\n\n\    aseg.mgz\n    aseg.auto.mgz\
                   \n    aseg.auto_noCCseg.mgz\n    aparc.a2009s+aseg.mgz"
    # N.B.: aparc+aseg has 0-255 brainstem, lh=2000+{0-255} rh=1000+{0-255}
    set im2lutoverlayflag 0
    logcmd "set im2lutoverlayflag 0"
    return
  }
  set im2 [.mri.main.right.cmp.im2.cbx subwidget entry get]
  set structlist "orig.mgz T1.mgz T2.mgz PD.mgz brain.mgz wm.mgz filled.mgz \
                  orig T1 T2 PD brain wm filled"
  foreach struct $structlist {
    if { "$struct" == "$im2" } {
      confirmalert "Can't use struct scan:\n\n    $struct\n\
                    \nas im2 label overlay.\
                    \n\nInstead try:\n\n\    aseg.mgz\n    aseg.auto.mgz\
                    \n    aseg.auto_noCCseg.mgz\n    aparc.a2009s+aseg.mgz"
      set im2lutoverlayflag 0
      logcmd "set im2lutoverlayflag 0"
      return
    }
  }
  #if {$im2lutoverlayflag && $drawsecondflag} {
  #  confirmalert "click COMPARE for transparent overlay on main image\
  #            \n\ngoto F4 panel for:\
  #            \n\n   control overlay transparency (\"tran\" -> 0-255)\
  #              \n   force 256 rand cols for byte img (\"randlut256\")"
  #}
  set imim2elloverlayflag 0
  logcmd "set imim2elloverlayflag 0"

  # read/conv/sort {FreeSurfer,Csurf,HCP}ColorLUT.txt or make/read new rand LUT
  if {!$randlut256flag} {  ;# assume *.mgz containing int idnum
    if { [string match Csurf* $im2abbrev] ||
         [string match MY_ANNOT* $im2abbrev] } { ;#sequential idnums from annot
      ### next is my orig with (inadvisedly) same col/idnum for both hemis
      #set val2rgblut $env(CSURF_DIR)/lib/lut/CsurfColorLUT.txt ;#not sequential
      ### next has both hemis, L_,R_, uniq colors (r+1 for RH), re-sequential'd
      set val2rgblut $env(CSURF_DIR)/lib/lut/CsurfColorLUT-both.txt
      setfile val2rgblutsub $val2rgblut  ;# remake abbrev to report
      # C/tcl read_val2rgblut also calls next if match Csurf name
      read_sort_mghval2rgblut
      ### skip next b/c CsurfColorLUT-both.txt from mkbothlut already sequential
      #seq_renum_lut
    } elseif { [string match HCP-MMP1* $im2abbrev] } {
      ### next is single-hemi output of read_mgh_annot
      #set val2rgblut $env(CSURF_DIR)/lib/lut/HCP-MMP1ColorLUT.txt
      ### next renum'd from 2 read_mgh_annot input files (names/cols unique)
      set val2rgblut $env(CSURF_DIR)/lib/lut/HCP-MMP1ColorLUT-both.txt
      setfile val2rgblutsub $val2rgblut  ;# remake abbrev to report
      # C/tcl read_val2rgblut also calls next if match HCP-MMP1 name
      read_sort_mghval2rgblut
      ### skip next b/c mkbothlut HCP-MMP1ColorLUT-both.txt already sequential
      #seq_renum_lut
    } else {   ;# default FreeSurfer *.mgz 3D (N.B.: non-sequential idnums)
      set val2rgblut $env(CSURF_DIR)/lib/lut/FreeSurferColorLUT.txt
      setfile val2rgblutsub $val2rgblut  ;# remake abbrev to report
      # C/tcl read_val2rgblut also calls read_sort_mghval2rgblut if match FS std
      read_sort_mghval2rgblut
      ### skip next even tho not-sequentialized to correspond to LUT?
      #seq_renum_lut
    }
  } else {  ;# make a new LUT each time
    set val2rgblut $env(SUBJECTS_DIR)/$subject/$mridir/val2rgb.lut
    setfile val2rgblutsub $val2rgblut   ;# remake abbrev (blow away curr abbrev)
    if ![canwriteormakefile $val2rgblut] {
      confirmalert "Permissions don't allow write look-up table:\n\n$val2rgblut"
      return
    }
    set id [open $val2rgblut w 0644]
    set fstal $env(SUBJECTS_DIR)/$subject/$mridir/$fscolormap
    if { ![file exists $fstal] } {
      puts $id "### val2rgblut: 1-255 mapped to rand cols"
      puts $id "# val\tred\tgreen\tblue"
      set lines ""
      for {set i 0} {$i < 256} {incr i} { set lines "$lines $i\n" }
    } else {   ;# read/make only existing region numbers
      set idfstal [open $fstal r]
      set lines [split [read $idfstal] \n]
      close $idfstal
      puts $id "### talairach.label_intensities.txt -> val2rgblut (rand cols)"
      puts $id "# val\tred\tgreen\tblue"
    }
    foreach line $lines {
      if {$line != ""} {
        set i [lindex $line 0]
        if {$i > 0} {
          set r [expr int(rand()*255)]
          set g [expr int(rand()*255)]
          set b [expr int(rand()*255)]
        } else { set r 0; set g 0; set b 0 }
        puts $id "$i\t$r\t$g\t$b"
      }
    }
    close $id
    logcmd "# made random colortable: $val2rgblut"
    read_val2rgblut
    logcmd "read_val2rgblut"
  }

  set drawsecondflag 0
  logcmd "set drawsecondflag 0"
  .mri.main.right.cmp.im2.aCOMPARE.bu config -relief raised  ;# required
  redraw
  logcmd "redraw"
}

proc detectshowlabel { } {
  global im2lutoverlayflag mghseglabstemlist

  set im2stem [.mri.main.right.cmp.im2.cbx subwidget entry get]
  foreach labstem $mghseglabstemlist {
    if { "$labstem" == "$im2stem" } {
      set im2lutoverlayflag 1
      logcmd "set im2lutoverlayflag 1"
      fscolormap2lut   ;# logs, loadlut/redraw here
    }
  }
}

proc checkim2redraw { } {
  global imim2elloverlayflag im2loaded drawsecondflag im2lutoverlayflag
  if {$imim2elloverlayflag} {
    if {!$im2loaded} {
      confirmalert " Display regions defined by:\n\
                     \n    im col = \{center, radius\}\
                     \n    im2 col = \{center, radius\}:\n\n\
                     Failed:  first load an im2"
      # don't return here, let redraw below unset flag
    } else { set im2lutoverlayflag 0; logcmd "set im2lutoverlayflag 0" }
  }
  if {$drawsecondflag} {
    set drawsecondflag 0
    logcmd "set drawsecondflag 0"
    .mri.main.right.cmp.im2.aCOMPARE.bu config -relief raised
  }
  redraw  ;# unsets imim2elloverlayflag if !im2loaded
  logcmd "redraw"
  update idletasks
  set imim2elloverlayflag $imim2elloverlayflag  ;# force show uncheck
  logcmd "set imim2elloverlayflag $imim2elloverlayflag"
}

proc do_imim2op { } {
  global imim2opnum drawsecondflag im2loaded

  if {!$im2loaded} {
    confirmalert " Perform im/im2 operation failed:\n\n...first load an im2"
    return
  }
  if ![okreplace "" \
       "OK to truncate editable buffer using 2D color space ellipse?\
    \n\n(N.B.: cmd/alt-z in image window to undo)" \
       "Trunc Editable Using 2D Color Space"] { return }
  imim2op $imim2opnum
  logcmd "imim2op $imim2opnum"
  if {$drawsecondflag} {
    set drawsecondflag 0
    logcmd "set drawsecondflag 0"
    .mri.main.right.cmp.im2.aCOMPARE.bu config -relief raised
  }
  redraw
  logcmd "redraw"
}

proc getmghvolindex { } {
  global newimc newjc newic ydim zf
  set volcoords "$newjc [expr $ydim/$zf - 1 - $newic] $newimc"
  return $volcoords
}

proc zerotal { } {
  global xtalairach ytalairach ztalairach
  set xtalairach 0.0
  set ytalairach 0.0
  set ztalairach 0.0
  talairach_to_coords
  redraw
  unzoomcoords
}

proc boundseditctrls { } {  ;# right-click TRUNC entries
  global boundseditctrlswin im2boundsflag

  if [winfo exists $boundseditctrlswin] { raise $boundseditctrlswin; return }
  set title "IMAGE BOUNDS-DEPENDENT EDITING\
           \n(shift-left-click in image win\
           \nor ctrl-mid/rightl-click TRUNC)\
         \n\nTop bounds: edit im to targval\
           \n(gray_hilim) if image pixel\
           \n(can be from im or im2)\
           \nwithin these bounds\
         \n\nim2boundsflag: bounds test\
           \napplied to im2 instead of im\
           \n(edits still go to primary im!)\
         \n\nBottom bounds: structure-saving\
           \n(only used when \$im2boundsflag\
           \nticked) - block edit to im if\
          \nim within these bounds"
  set variablelist "whitespace \
                    im2boundsflag \
                    white_lolim \
                    white_hilim \
                    whitespace \
                    whitespace \
                    gray_hilim \
                    whitespace \
                    whitespace \
                    edit_lolim2 \
                    edit_hilim2"
  set boundseditctrlswin [controls $title $variablelist none none 11]
  ### hack: enable/disable second bounds on toggle im2boundsflag
  $boundseditctrlswin.ck0 config -command {  ;# setup toggle
    if {$im2boundsflag} {
      $boundseditctrlswin.edit_lolim2.la config -state normal
      $boundseditctrlswin.edit_lolim2.e config -state normal
      $boundseditctrlswin.edit_hilim2.la config -state normal
      $boundseditctrlswin.edit_hilim2.e config -state normal
    } else {
      $boundseditctrlswin.edit_lolim2.la config -state disabled
      $boundseditctrlswin.edit_lolim2.e config -state disabled
      $boundseditctrlswin.edit_hilim2.la config -state disabled
      $boundseditctrlswin.edit_hilim2.e config -state disabled
    }
  }
  if {!$im2boundsflag} {  ;# init panel
    $boundseditctrlswin.edit_lolim2.la config -state disabled
    $boundseditctrlswin.edit_lolim2.e config -state disabled
    $boundseditctrlswin.edit_hilim2.la config -state disabled
    $boundseditctrlswin.edit_hilim2.e config -state disabled
  }  ;### end hack
  # move it up to un-overlap buttonbar (R-click TRUNC, R-click lims OK)
  set g [split [wm geometry $boundseditctrlswin] "+x"]
  wm geometry $boundseditctrlswin +[lindex $g 2]+[expr [lindex $g 3]-500]
}

proc contrrampctrls { } {  ;# left-click PiecWiseLinNorm title
  global contrrampctrlswin

  if [winfo exists $contrrampctrlswin] { raise $contrrampctrlswin; return }
  set title "BRIGHTNESS-DEPENDENT\
           \nPIECEWISE LIN CONTRAST RAMP\
         \n\nDefault: OFF (contrastslope=0.0)\
           \n(no effect when ffrac0,1,2,3 == 1.0)\
         \n\nset no-contrast-change brightness, and\
           \nstrength of brightness (+dist)-dependent\
           \ncontrast ramp (neg OK), then TEST,APPLY"
  set variablelist "contrastnochange \
                    contrastslope"
  set contrrampctrlswin [controls $title $variablelist none none 11]
}

proc imim2opctrls { } {  ;# right-click help for OP and TRUNC butt
  global imim2opctrlswin imcolcent imcolrad im2colcent im2colrad imim2opnum

  if [winfo exists $imim2opctrlswin] { raise $imim2opctrlswin; return }
  set title "2D COLOR-SPACE ELLIPSE TRUNCATION\
         \n\nN.B.: requires im2 is loaded   \
           \nN.B.: trunc. applied to editble \
           \nN.B.: Undo: img win alt/cmd-z\
         \n\nTruncation Operation (\$imim2opnum):\
         \n\n    0: INSIDE im,im2 col ellipse->OFF   \
           \n    1: OUTSIDE im,im2 col ellipse->OFF"
  set variablelist "imim2opnum whitespace \
                    imcolcent imcolrad whitespace \
                    im2colcent im2colrad whitespace"
  set imim2opctrlswin [controls $title $variablelist \
                       "TRUNC EDITABLE WITH 2D COLOR SPACE" "do_imim2op" 11]
  # move up these ctrls to un-overlap TRUNC buttonbar (but not if from OP butt)
  if [winfo exists .buttonbar-trunc_tmpim1] { ;#intern: buttbar win nm=1st proc
    set g [split [wm geometry $imim2opctrlswin] "+x"]
    wm geometry $imim2opctrlswin +[lindex $g 2]+[expr [lindex $g 3]-400]
  }
  bind $imim2opctrlswin <ButtonRelease-3> { helpwin imim2op } ;# R-clk popup
}

proc flipctrls { } {  ;# ctrl-click CORONAL
  global flipctrlswin

  if [winfo exists $flipctrlswin] { raise $flipctrlswin; return }
  set title "FLIP DATA SET IN CORONAL VIEW\
         \n\n(1) First change to CORONAL view\
           \n(2) Enter non-overlapping \[-\]{x,y,z}\
           \nfor each \"flip to\""
  set variablelist "whitespace \
                    flip_curr_x_to \
                    flip_curr_y_to \
                    flip_curr_z_to \
                    whitespace"
  set flipctrlswin [controls $title $variablelist "FLIP DATA" "do_flip" 11]
}

proc do_flip { } {
  global flip_curr_x_to flip_curr_y_to flip_curr_z_to
  global plane cor xdim ydim zf

  set x_to [string range $flip_curr_x_to end end]  ;# strip possible sign
  set y_to [string range $flip_curr_y_to end end]
  set z_to [string range $flip_curr_z_to end end]
  if {$x_to != "x" && $x_to != "y" && $x_to != "z"} {
    confirmalert "flipctrls: value entered for \"flip_curr_x_to\":\
              \n\n    $flip_curr_x_to\
              \n\nis not valid\
              \n\nOK: x, -x,  y, -y,  z, -z"
    return
  }
  if {$y_to != "x" && $y_to != "y" && $y_to != "z"} {
    confirmalert "flipctrls: value entered for \"flip_curr_y_to\":\
              \n\n    $flip_curr_y_to\
              \n\nis not valid\
              \n\nOK: x, -x,  y, -y,  z, -z"
    return
  }
  if {$z_to != "x" && $z_to != "y" && $z_to != "z"} {
    confirmalert "flipctrls: value entered for \"flip_curr_z_to\":\
              \n\n    $flip_curr_z_to\
              \n\nis not valid\
              \n\nOK: x, -x,  y, -y,  z, -z"
    return
  }
  if {$z_to == $y_to || $x_to == $z_to || $y_to == $z_to } {
    confirmalert "flipctrls: degenerate flip\n\nflip_to\'s can't overlap"
    return
  }
  if {$plane != $cor} {
    confirmalert "First changing to centered CORONAL view:\
              \n\nCoords on FLIP pop-up refer only to CORONAL view!"
    #.mri.main.left.view.pan.cor.top.aCORONAL.bu invoke
    event generate .mri.main.left.view.pan.cor.top.aCORONAL.bu <ButtonRelease-1>
    set zdim $xdim  ;# assume cube (no zoomed window depth in tkmedit)
    goto_point_coords [expr $ydim/$zf/2] [expr $xdim*$zf/2] [expr $zdim/$zf/2]
    redraw
    after 500
  }

  flip_corview_xyz $flip_curr_x_to $flip_curr_y_to $flip_curr_z_to
  logcmd "flip_corview_xyz $flip_curr_x_to $flip_curr_y_to $flip_curr_z_to"
  redraw
}

proc listcmd_annots { combo } {
  global env subject insurf

  set hemi [string range [file tail $insurf] 0 1]
  set fullfilelist \
    [glob -nocomplain $env(SUBJECTS_DIR)/$subject/label/$hemi.*.annot]
  # manually re-abbreviate vs. clog log with many setfiles
  set abbrevlist ""
  foreach fullfile $fullfilelist {
    set abbrevlist "$abbrevlist ~/label/[file tail $fullfile]"
  }
  $combo subwidget listbox delete 0 end
  foreach abbrev $abbrevlist { $combo insert end $abbrev }
}

proc macro { } {
  global tkmeditinterface selectedpixval
  if {$tkmeditinterface == "micro"} { undomicro }
  .mri.main.left.head.save.aSAVEIMG.bu config -text "SAVEIMG"
  .mri.main.left.head.pnt.aall.ck config -text "all"
  .mri.main.left.head.save.a3D.ck config -text "3D"
  pack forget .mri.main.left.head
  pack forget .mri.main.farright
  pack .mri.main.left.head -before .mri.main.left.view  ;# back to old nest
  set winlist { .mri.main.right.fi.im }
  foreach win $winlist { pack forget $win }
  pack .mri.head                -before .mri.main -fill x
  pack .mri.main.right          -after .mri.main.left
  pack .mri.main.right.snorm    -after .mri.main.right.fi
  pack .mri.main.right.fi.roiup -after .mri.main.right.fi.surf
  pack .meg                     -after .mri
  pack forget .mri.main.left.head.pnt.az
  set tkmeditinterface macro
  set selectedpixval $selectedpixval
}

proc mini3 { } {
  global tkmeditinterface selectedpixval
  if {$tkmeditinterface == "micro"} { undomicro }
  .mri.main.left.head.save.aSAVEIMG.bu config -text "SAVEIMG"
  .mri.main.left.head.pnt.aall.ck config -text "all"
  .mri.main.left.head.save.a3D.ck config -text "3D"
  pack forget .mri.main.left.head
  pack forget .mri.main.farright
  pack .mri.main.left.head -before .mri.main.left.view
  pack .mri.head             -before .mri.main -fill x
  pack .mri.main.right       -after .mri.main.left
  pack .mri.main.right.snorm -after .mri.main.right.fi
  pack .mri.main.right.fi.im -after .mri.main.right.fi.surf
  set winlist { .mri.main.right.fi.roiup .meg .mri.head }
  foreach win $winlist { pack forget $win }
  pack forget .mri.main.left.head.pnt.az
  set tkmeditinterface mini3
  set selectedpixval $selectedpixval
}

proc mini2 { } {
  global tkmeditinterface selectedpixval
  #if {$tkmeditinterface == "micro"} { undomicro }  ;# mini does as first step
  mini       ;# rearrange nesting, re-pack several
  pack .mri.main.farright
  pack .mri.main.right.fi.roiup -after .mri.main.right.fi.surf
  set winlist { .mri.main.right.fi.im .meg .mri.head }
  foreach win $winlist { pack forget $win }
  set tkmeditinterface mini2
  set selectedpixval $selectedpixval
}

proc mini { } {    ;# rearrange nesting (default)
  global tkmeditinterface selectedpixval all3flag
  if {$tkmeditinterface == "micro"} { undomicro }
  pack .mri.head       -before .mri.main
  pack .mri.main.right -after .mri.main.left
  pack forget .mri.main.left.head
  pack forget .mri.main.farright
  pack .mri.main.left.head
  pack .mri.main.right -in .mri.main.left.head    ;# redo nesting
  .mri.main.left.head.save.aSAVEIMG.bu config -text "SAVE IMGS"
  .mri.main.left.head.save.a3D.ck config -text "3Dbrush"
  if {$all3flag} {
    .mri.main.left.head.pnt.aall.ck config -text "all3"
    pack .mri.main.left.head.pnt.az -after .mri.main.left.head.pnt.aall
  } else {
    .mri.main.left.head.pnt.aall.ck config -text "all3views"
  }
  set winlist { .mri.main.right.fi.roiup .mri.head .meg .mri.main.right.snorm }
  foreach win $winlist { pack forget $win }
  pack .mri.main.right.fi.im -after .mri.main.right.fi.surf
  set tkmeditinterface mini
  set selectedpixval $selectedpixval
}

proc micro { } {
  global ffontb tkmeditinterface selectedpixval followglwinflag
  mini       ;# rearrange nesting, re-pack several
  foreach v { cor sag hor } { pack .mri.main.left.view.pan.$v -side left }
  pack forget .mri.main.left.view.butt   ;# overlay/FILL/etc
  pack forget .mri.main.right.fi         ;# entries
  pack forget .mri.main.right.wm         ;# TRUNC + fthresh/fmid
  pack forget .mri.main.right.cmp.im2.la ;# tcl: label/button
  pack forget .mri.main.right.cmp.im2.ck ;# MGH 3D aseg labels
  pack .mri.main.right.cmp.im2.ck2 -side left
  .mri.main.left.head.save.aSAVEIMG.bu config -pady 0 -padx 12 -font $ffontb
  ".mri.main.left.head.pnt.aSEND PNT.bu" config -pady 0
  ".mri.main.left.head.pnt.aGOTO PNT.bu" config -pady 0
  .mri.main.right.cmp.im2.aCOMPARE.bu config -pady 0 -padx 10 -font $ffontb
  .mri.main.left.head config -bd 0
  set tkmeditinterface micro
  set selectedpixval $selectedpixval
  set followglwinflag 0   ;# others don't turn back on, so can use turn off
}

proc undomicro { } {
  global ffontbb
  foreach v { cor sag hor } { pack .mri.main.left.view.pan.$v -side top }
  pack .mri.main.right.fi
  pack .mri.main.right.wm 
  pack .mri.main.left.view.butt
  pack .mri.main.right.cmp.im2.la -side left
  pack .mri.main.right.cmp -after .mri.main.right.wm
  pack .mri.main.right.cmp.im2.ck -side left \
    -before .mri.main.right.cmp.im2.aCOMPARE
  pack forget .mri.main.right.cmp.im2.ck2
  .mri.main.left.head.save.aSAVEIMG.bu config -pady 1 -padx 4 -font $ffontbb
  ".mri.main.left.head.pnt.aSEND PNT.bu" config -pady 2
  ".mri.main.left.head.pnt.aGOTO PNT.bu" config -pady 2
  .mri.main.right.cmp.im2.aCOMPARE.bu config -pady 2 -padx 0 -font $ffontbb
  .mri.main.left.head config -bd 2
}

############################################################################
# main window, frame hierachy by indentation
############################################################################
#wm geometry . +36+744    ;# +114+740, +534+36, +122+762
wm geometry . +${glxwinx}+[expr $glxwiny + $glxwinh + 32]   ;# TKGL_YGAP=10?
wm title . "tkmedit ($subject)"
wm protocol . WM_DELETE_WINDOW testclose
wm resizable . 0 0

frame .mri
pack .mri -side left
  frame .mri.head
  pack .mri.head -side top -fill x
    frame .mri.head.pop
    pack .mri.head.pop -side left
    frame .mri.head.home
    pack .mri.head.home -side left
    frame .mri.head.env
    pack .mri.head.env -side left
  frame .mri.main
  pack .mri.main -side top
    # left column
    frame .mri.main.left
    pack .mri.main.left -side left
      frame .mri.main.left.head -borderwidth 2 -relief groove
      pack .mri.main.left.head -side top -fill x
        frame .mri.main.left.head.save
        pack .mri.main.left.head.save -side top
        frame .mri.main.left.head.pnt
        pack .mri.main.left.head.pnt -side top
      frame .mri.main.left.view
      pack .mri.main.left.view -side left
        frame .mri.main.left.view.pan
        pack .mri.main.left.view.pan -side top -fill y
        # three identical slice panels
        foreach v { cor sag hor } {
          frame .mri.main.left.view.pan.$v -borderwidth 2 -relief groove
          pack .mri.main.left.view.pan.$v -side top -fill x
            frame .mri.main.left.view.pan.$v.top
            pack .mri.main.left.view.pan.$v.top -side top
            frame .mri.main.left.view.pan.$v.bot
            pack .mri.main.left.view.pan.$v.bot -side top
        }
        # misc checks
        frame .mri.main.left.view.butt
        pack .mri.main.left.view.butt -side top
          frame .mri.main.left.view.butt.left
          pack .mri.main.left.view.butt.left -side left
          frame .mri.main.left.view.butt.right
          pack .mri.main.left.view.butt.right -side left
          frame .mri.main.left.view.butt.farright
          pack .mri.main.left.view.butt.farright -side left
    # right column
    frame .mri.main.right ;# -borderwidth 2
    pack .mri.main.right -side left
      frame .mri.main.right.fi -borderwidth 2 -relief groove
      pack .mri.main.right.fi -side top
      frame .mri.main.right.snorm -borderwidth 2 -relief groove
      pack .mri.main.right.snorm -side top -fill x
        frame .mri.main.right.snorm.but
        pack .mri.main.right.snorm.but -side top
        frame .mri.main.right.snorm.bot
        pack .mri.main.right.snorm.bot -side top
          frame .mri.main.right.snorm.bot.lim
          pack .mri.main.right.snorm.bot.lim -side left
          frame .mri.main.right.snorm.bot.ffrac
          pack .mri.main.right.snorm.bot.ffrac -side left
          frame .mri.main.right.snorm.bot.dir
          pack .mri.main.right.snorm.bot.dir -side left
      frame .mri.main.right.wm ;# -borderwidth 2 -relief groove
      pack .mri.main.right.wm -side top -fill x
        frame .mri.main.right.wm.trufil
        pack .mri.main.right.wm.trufil -side top
        frame .mri.main.right.wm.thr
        pack .mri.main.right.wm.thr -side top
      frame .mri.main.right.im2 -borderwidth 2 -relief groove
      pack .mri.main.right.im2 -side top -fill both
      frame .mri.main.right.cmp
      pack .mri.main.right.cmp -side top -fill both
    # far right column
    frame .mri.main.farright -bd 2 -relief groove
    pack .mri.main.farright -side left

frame .meg
pack .meg -side left
  frame .meg.ti -borderwidth 1
  pack .meg.ti -side top
  frame .meg.dips -borderwidth 2 -relief groove
  pack .meg.dips -side top
    frame .meg.dips.spac
    pack .meg.dips.spac -side left
    frame .meg.dips.en
    pack .meg.dips.en -side left
  frame .meg.xform
  pack .meg.xform -side left
    frame .meg.xform.files
    pack .meg.xform.files -side top
    frame .meg.xform.pan
    pack .meg.xform.pan -side top
      # rotate plus fieldsign
      frame .meg.xform.pan.le
      pack .meg.xform.pan.le -side left -anchor n
        frame .meg.xform.pan.le.rg
        pack .meg.xform.pan.le.rg -side top -anchor n -fill x
          frame .meg.xform.pan.le.rg.rot -borderwidth 2 -relief groove
          pack .meg.xform.pan.le.rg.rot -side top -fill both
            frame .meg.xform.pan.le.rg.rot.top
            pack .meg.xform.pan.le.rg.rot.top -side top
            frame .meg.xform.pan.le.rg.rot.bot
            pack .meg.xform.pan.le.rg.rot.bot -side top -anchor center
        frame .meg.xform.pan.le.surf -borderwidth 2 -relief groove
        pack .meg.xform.pan.le.surf -side top -fill x
          frame .meg.xform.pan.le.surf.top
          pack .meg.xform.pan.le.surf.top -side top
            frame .meg.xform.pan.le.surf.top.le
            pack .meg.xform.pan.le.surf.top.le -side left
            frame .meg.xform.pan.le.surf.top.ri
            pack .meg.xform.pan.le.surf.top.ri -side left
          frame .meg.xform.pan.le.surf.bot
          pack .meg.xform.pan.le.surf.bot -side top
        frame .meg.xform.pan.le.ex
        pack .meg.xform.pan.le.ex -side top
          frame .meg.xform.pan.le.ex.le
          pack .meg.xform.pan.le.ex.le -side left
          frame .meg.xform.pan.le.ex.ri
          pack .meg.xform.pan.le.ex.ri -side left
      # translate panel
      frame .meg.xform.pan.tran -borderwidth 2 -relief groove
      pack .meg.xform.pan.tran -side left -anchor n -fill y
        frame .meg.xform.pan.tran.top
        pack .meg.xform.pan.tran.top -side top
        frame .meg.xform.pan.tran.bot
        pack .meg.xform.pan.tran.bot -side top
          frame .meg.xform.pan.tran.bot.la
          pack .meg.xform.pan.tran.bot.la -side right -anchor center
            frame .meg.xform.pan.tran.bot.la.ent
            pack .meg.xform.pan.tran.bot.la.ent -side top
            frame .meg.xform.pan.tran.bot.la.wm -borderwidth 2 -relief groove
            pack .meg.xform.pan.tran.bot.la.wm -side top
            frame .meg.xform.pan.tran.bot.la.en
            pack .meg.xform.pan.tran.bot.la.en -side top

### if opened here (tkmedit option), log includes constant startup cmds
set mktcllabbold 0
if { $tkmeditlogflag } {
  if ![canwriteormakefile tkmedit.log] {
    confirmalert "can't write tkmedit.log to:\n\n[pwd]"
    set tkmeditlogflag 0
  } else {
    if { [pwd] != "$isession/scripts" } { ;# not from csurf
      confirmalert "N.B.: writing tcl cmd log outside scripts dir in:\n\n[pwd]"
    }
    logopen tkmedit.log
    set mktcllabbold 1
  }
}

############################################################################
# make two-column interface widgets, top left to bottom right
############################################################################
### make orig two-column F3 panel, then rearrange into compact F1 two-col
puts "tkmedit.tcl: making widgets"

### title (F4 only)
set f .mri.head.pop
buttons $f "POP GL" { raise_window; logcmd "raise_window" } row 0 5
set f .mri.head.home
edlabval $f "home(~)" $home/$subject n 8 30
$f.home(~).e config -font $ffontb -state disabled
$f.home(~).e xview end
# readenv
set f .mri.head.env
buttons $f READENV {
  source $env(CSURF_DIR)/lib/tcl/readenv.tcl
  logcmd "source $env(CSURF_DIR)/lib/tcl/readenv.tcl"
  redraw
} col 0 5
bind $f.aREADENV <ButtonRelease-3> { helpwin readenv }

#### SAVEIMG / SAVE IMGS (bigger font)
############################################################################
set f .mri.main.left.head.save
buttons $f "SAVEIMG" {
  set inoutim_curr $inoutim
  set inoutim $inoutim_orig   ;# back to tkmedit startup images
  test_write_images blocknew
  set inoutim $inoutim_curr
} row 1 4
$f.aSAVEIMG.bu config -font $ffontbb
bind $f.aSAVEIMG.bu <ButtonRelease-3> { helpwin saveimg }
## brush rad
edlabval $f "rad" 0 n 4 2 row
$f.rad.e config -textvariable prad -font $sfont
bind $f.rad.e <Return> { logcmd "set prad $prad" }
bind $f.rad.e <ButtonRelease-3> { helpwin brush }
bind $f.rad.la <ButtonRelease-1> {
  set circleflag  [expr !$circleflag];
  logcmd "set circleflag $circleflag"
  redraw
  logcmd "redraw"
  if {$circleflag} {
    confirmalert "toggle \$circleflag to $circleflag (circle/sphere)"
  } else {
    confirmalert "toggle \$circleflag to $circleflag (square/cube)"
  }
}
## brush 3D
checks $f "" "3D" inplaneflag row
$f.a3D.ck config -onvalue 0 -offvalue 1   ;# flip sign of inplaneflag
bind $f.a3D.ck <ButtonRelease-1> { logcmd "set inplaneflag $inplaneflag" }
bind $f.a3D.ck <ButtonRelease-3> { helpwin inplane }

### SEND/GOTO/all3/zoom
############################################################################
## SEND point
set f .mri.main.left.head.pnt
buttons $f "SEND PNT" {
  write_point
  logcmd "write_point"
} row 2 2
bind "$f.aSEND PNT.bu" <ButtonRelease-3> { helpwin sendpnt }
## next removed from SEND PNT above since requires xhost +
## -async so didn't wait for answer from running offline tcl script
#  findsendto
#  catch { send -async $fulltksurfer select_orig_vertex_coordinates }
## GOTO point
buttons $f "GOTO PNT" {
  goto_point
  logcmd "goto_point"
  set bigcursorflag 1
  redraw
  logcmd "redraw"
  set bigcursorflag 1  ;# stay big twice (for changeplane, sameplane OK)
  unzoomcoords
  logcmd "unzoomcoords"
} row 2 2
bind "$f.aGOTO PNT.bu" <ButtonRelease-3> { helpwin gotopnt }
## all3
checks $f "" "all" all3flag row
$f.aall.ck config -command {
  logcmd "set all3flag $all3flag"
  if {$zoomflag} {set zoomflag 0; logcmd "set zoomflag 0"}
  zoomhackscalerescurs
  logcmd "zoomhackscalerescurs"
  redraw
  logcmd "redraw"
} -padx 0
bind $f.aall.ck <ButtonRelease-3> { helpwin all3 }
## zoom (only visible if all3)
checks $f "" "z" zoomflag row
$f.az.ck config -command {
  logcmd "set zoomflag $zoomflag"
  zoomhackscalerescurs
  logcmd "zoomhackscalerescurs"
  redraw
  logcmd "redraw"
} -padx 0
bind $f.az.ck <ButtonRelease-3> { helpwin all3zoom }
pack forget .mri.main.left.head.pnt.az   ;# only visible if all3flag
.mri.main.left.head.pnt.aall.ck config -text "all3views"

### CORONAL button (x=jc,y=imc,z=ic)
############################################################################
set f .mri.main.left.view.pan.cor.top
# tiny "h" (tkmedit help)
button $f.bu -text "h" -font $ffontb -pady 2 -padx 0 -command {
  helpwin $env(CSURF_DIR)/lib/help/csurf/tkmedit
}
pack $f.bu -side left -padx 0
bind $f.bu <ButtonRelease-3> { helpwin hbutt }
# CORONAL button
buttons $f "CORONAL" { } row 2 5  ;# rm action->explicit bind for event gen hack
bind $f.aCORONAL.bu <ButtonRelease-1> {
  raise_window
  logcmd "raise_window"
  set plane $cor
  logcmd "set plane $cor"
  pixvaltitle 0 0 0
  logcmd "pixvaltitle 0 0 0"
  redraw
  logcmd "redraw"
  unzoomcoords
  logcmd "unzoomcoords"
}
# overload w/flip from corview (if not CORONAL, force to CORONAL/center)
bind $f.aCORONAL.bu <ButtonRelease-2> {
  if {$plane != $cor} {
    #.mri.main.left.view.pan.cor.top.aCORONAL.bu invoke
    event generate .mri.main.left.view.pan.cor.top.aCORONAL.bu <ButtonRelease-1>
    set zdim $xdim  ;# assume cube (no zoomed window depth in tkmedit)
    goto_point_coords [expr $ydim/$zf/2] [expr $xdim*$zf/2] [expr $zdim/$zf/2]
    redraw
  }
  flipctrls
}
## use event gen hack here to keep main bind's localized/parallel to SAG/HOR
proc coronal_std { } {
  event generate .mri.main.left.view.pan.cor.top.aCORONAL.bu <ButtonRelease-1>
}
proc coronal_flip { } {
  event generate .mri.main.left.view.pan.cor.top.aCORONAL.bu <ButtonRelease-2>
}
#bind $f.aCORONAL.bu <ButtonRelease-3> { helpwin coronal }
bind $f.aCORONAL.bu <ButtonRelease-3> {
  helpwin coronal
  buttonbar \
    "\"Change To CORONAL plane (left-click-CORONAL)\" \
     \"Flip Data Set in CORONAL View (mid-clk-CORONAL)\"" \
    "coronal_std coronal_flip" \
    ver "CORONAL Button" coronal
}
### CORONAL talairach
edlabval $f "yTal" 0 n 8 5 row
$f.yTal.e config -textvariable ytalairach -font $sfont
bind $f.yTal.e <Return> {
  logcmd "set ytalairach $ytalairach"
  talairach_to_coords
  logcmd "talairach_to_coords"
  redraw
  logcmd "redraw"
  unzoomcoords
  logcmd "unzoomcoords"
}
$f.yTal.la config -text "yTal P/A:" -font $ffontb
bind $f.yTal.la <ButtonRelease-1> { confirmalert \
  "Volume index for MGH tkmedit:\n\n    [getmghvolindex]" } ;# R-click
bind $f.yTal.e <ButtonRelease-3> { helpwin talcoords }
### CORONAL slider
set f .mri.main.left.view.pan.cor.bot
scale $f.sc -from $cormin -to $cormax -length $sclenx -variable newimc \
   -orient horizontal -tickinterval 127 -showvalue false -font $sfont \
   -width 11 -resolution 1
pack $f.sc -side left
bind $f.sc <ButtonRelease-1> {
  set plane $cor
  logcmd "set plane $cor"
  logcmd "set newimc $newimc"
  redraw
  logcmd "redraw"
  update idletasks
  logcmd "update idletasks"
}
bind $f.sc <B1-Motion> { redraw }
### CORONAL slice entry
edlabval $f "none" 0 n 0 4 row
pack $f.none -side top   ;# repack to align with scale
$f.none.e config -textvariable newimc -font $sfont
bind $f.none.e <Return> {
  set plane $cor
  logcmd "set plane $cor"
  logcmd "set newimc $newimc"
  redraw
  logcmd "redraw"
  update idletasks
  logcmd "update idletasks"
}
bind $f.none.e <ButtonRelease-3> { helpwin pixcoords }
### undoeditflag tickbox
checkbutton $f.none.ck -variable undoeditflag -font $ffont -text "un" \
  -bd 0 -padx 0
pack $f.none.e -side top   ;# repack to get tix underneath
pack $f.none.ck -side top
bind $f.none.ck <ButtonRelease-3> { helpwin undoedit }
bind $f.none.ck <ButtonRelease-1> {
  if {$undoeditflag} {
    confirmalert "toggle \$undoeditflag to $undoeditflag (enable 4-step undo)"
  } else {
    confirmalert "toggle \$undoeditflag to $undoeditflag (disable 4-step undo)"
  }
}

### SAGITTAL button
############################################################################
set f .mri.main.left.view.pan.sag.top
button $f.bu -text "i" -font $ffontb -pady 2 -padx 1 -command {
  if {$intbuttbar == "" || ![winfo exists .buttonbar-mini] } {
    set intbuttbar [buttonbar "F1 F2 F3 F4 F5" "mini mini2 mini3 macro micro"]
  } else { 
    raise $intbuttbar
  }
}
bind $f.bu <ButtonRelease-3> { helpwin interface }
bind $f.bu <ButtonRelease-2> { 
  set bwslope [expr -$bwslope]
  logcmd "set bwslope $bwslope"
  redraw
  logcmd "redraw"
}
pack $f.bu -side left -padx 0
buttons $f SAGITTAL {
  raise_window
  logcmd "raise_window"
  set plane $sag
  logcmd "set plane $sag"
  pixvaltitle 0 0 0
  logcmd "pixvaltitle 0 0 0"
  redraw
  logcmd "redraw"
  unzoomcoords
  logcmd "unzoomcoords"
} row 2 5 ;# 8
bind $f.aSAGITTAL.bu <ButtonRelease-3> { helpwin sagittal }
### SAGITTAL talairach entry
edlabval $f "xTal" 0 n 8 5 row
$f.xTal.e config -textvariable xtalairach -font $sfont
bind $f.xTal.e <Return> {
  logcmd "set xtalairach $xtalairach"
  talairach_to_coords
  logcmd "talairach_to_coords"
  redraw
  logcmd "redraw"
  unzoomcoords
  logcmd "unzoomcoords"
}
$f.xTal.la config -text "xTal R/L:" -font $ffontb
bind $f.xTal.la <ButtonRelease-1> { zerotal; \
  confirmalert " Go to pixel nearest Talairach zero:\n\
  \n    Pix (cor,sag,hor):  $newimc  $newjc  $newic \
  \n    Talairach (x, y, z):   $xtalairach  $ytalairach  $ztalairach" } ;#R-clk
bind $f.xTal.e <ButtonRelease-3> { helpwin talcoords }
### SAGITTAL slider
set f .mri.main.left.view.pan.sag.bot
scale $f.sc -from $sagmin -to $sagmax -length $sclenx -variable newjc \
   -orient horizontal -tickinterval 127 -showvalue false -font $sfont \
   -width 11 -resolution 1
pack $f.sc -side left
bind $f.sc <ButtonRelease-1> {
  set plane $sag
  logcmd "set plane $sag"
  logcmd "set newjc $newjc"
  redraw
  logcmd "redraw"
  update idletasks
  logcmd "update idletasks"
}
bind $f.sc <B1-Motion> { redraw }
### SAGITTAL slice entry
edlabval $f "none" 0 n 0 4 row
pack $f.none -side top
$f.none.e config -textvariable newjc -font $sfont
bind $f.none.e <Return> {
  set plane $sag
  logcmd "set plane $sag"
  logcmd "set newjc $newjc"
  redraw
  logcmd "redraw"
  update idletasks
  logcmd "update idletasks"
}
bind $f.none.e <ButtonRelease-3> { helpwin pixcoords }
### xform 305to152 tickbox
checkbutton $f.none.ck -variable xform_mni_305to152_flag -font $sfont \
  -text "152" -bd 0 -padx 0
pack $f.none.e -side top   ;# repack to get tix underneath
pack $f.none.ck -side top
bind $f.none.ck <ButtonRelease-3> { helpwin xfm305to152 }
bind $f.none.ck <ButtonRelease-1> {
  logcmd "set xform_mni_305to152_flag $xform_mni_305to152_flag"
  if {$xform_mni_305to152_flag} {
    confirmalert "use MNI 152 coordinates (transform 305 -> 152)"
  } else {
    confirmalert "use MNI 305 coordinates (default)"
  }
}

### HORIZONTAL button
############################################################################
set f .mri.main.left.view.pan.hor.top
buttons $f HORIZONTAL {
  raise_window
  logcmd "raise_window"
  set plane $hor
  logcmd "set plane $hor"
  pixvaltitle 0 0 0
  logcmd "pixvaltitle 0 0 0"
  redraw
  logcmd "redraw"
  unzoomcoords
  logcmd "unzoomcoords"
} row 2 6
bind $f.aHORIZONTAL.bu <ButtonRelease-3> { helpwin horizontal }
### HORIZONTAL talairach entry
edlabval $f "zTal" 0 n 7 5 row
$f.zTal.e config -textvariable ztalairach -font $sfont
bind $f.zTal.e <Return> {
  logcmd "set ztalairach $ztalairach"
  talairach_to_coords
  logcmd "talairach_to_coords"
  redraw
  logcmd "redraw"
  unzoomcoords
  logcmd "unzoomcoords"
}
$f.zTal.la config -text "zTal I/S:" -font $ffontb
bind $f.zTal.la <ButtonRelease-1> { confirmalert \
 "Talairach (x, y, z):\n\n    $xtalairach  $ytalairach  $ztalairach"} ;# R-click
bind $f.zTal.e <ButtonRelease-3> { helpwin talcoords }
### HORIZONTAL slider
set f .mri.main.left.view.pan.hor.bot
scale $f.sc -from $hormin -to $hormax -length $sclenx -variable newic \
   -orient horizontal -tickinterval 127 -showvalue false -font $sfont \
   -width 11 -resolution 1
pack $f.sc -side left
bind $f.sc <ButtonRelease-1> {
  set plane $hor
  logcmd "set plane $hor"
  logcmd "set newic $newic"
  redraw
  logcmd "redraw"
  update idletasks
  logcmd "update idletasks"
}
bind $f.sc <B1-Motion> { redraw }
### HORIZONTAL slice entry
edlabval $f "none" 0 n 0 4 row
pack $f.none -side top
$f.none.e config -textvariable newic -font $sfont
bind $f.none.e <Return> {
  set plane $hor
  logcmd "set plane $hor"
  logcmd "set newic $newic"
  redraw
  logcmd "redraw"
  update idletasks
  logcmd "update idletasks"
}
bind $f.none.e <ButtonRelease-3> { helpwin pixcoords }

### overlay/surface/contr/midpt
############################################################################
### overlay toggle
set f .mri.main.left.view.butt.left
frame $f.aoverlay
pack $f.aoverlay -side top -pady 1
checkbutton $f.aoverlay.ck -variable overlayflag -font $ffont -text "overlay" \
  -bd 0 -padx 0 -command checkoverlay  ;# logcmd in checkoverlay
pack $f.aoverlay.ck -side left -pady 1
bind $f.aoverlay.ck <ButtonRelease-3> { helpwin overlay }
### surface toggle
frame $f.asurface
pack $f.asurface -side top -pady 1
checkbutton $f.asurface.ck -variable surfflag -font $ffont -text "surface" \
  -bd 0 -padx 0 -command checksurface  ;# logcmd in checksurface
pack $f.asurface.ck -side left -pady 1
bind $f.asurface.ck <ButtonRelease-3> { helpwin surf_ck }
### contrast entry
set f .mri.main.left.view.butt.right
edlabval $f "contr" 0 n 5 4
$f.contr.e config -textvariable bwslope
$f.contr.la config -padx 0 -bd 0
bind $f.contr.e <Return> {
  logcmd "set bwslope $bwslope"
  set_scale
  logcmd "set_scale"
  redraw
  logcmd "redraw"
  if {$linearflag} {
    confirmalert "N.B.: no effect of \"contr:\" since \$linearflag is 1\
             \n\nclick bold \"contr:\" label to toggle linearflag to 0"
  }
}
bind $f.contr.e <ButtonRelease-3> { helpwin bwslope }
# overload (bold) label
bind $f.contr.la <ButtonRelease-1> {
  set linearflag [expr !$linearflag];
  logcmd "set linearflag $linearflag"
  redraw
  logcmd "redraw"
  if {$linearflag} {
    confirmalert "toggle \$linearflag to $linearflag\
             \n\nN.B.: this disables \"contr:\" and \"midpt:\" entries"
  } else {
    confirmalert "toggle \$linearflag to $linearflag\
             \n\nN.B.: \"contr:\" and \"midpt:\" entries re-enabled"
  }
}
$f.contr.la config -font $ffontb
### midpoint entry
edlabval $f "midpt" 0 n 5 4
$f.midpt.e config -textvariable bwmid
$f.midpt.la config -padx 0 -bd 0
bind $f.midpt.e <Return> {
  logcmd "set bwmid $bwmid"
  set_scale
  logcmd "set_scale"
  redraw
  logcmd "redraw"
  if {$linearflag} {
    confirmalert "N.B.: no effect of \"midpt:\" since \$linearflag is 1\
             \n\nclick bold \"contr:\" label to toggle linearflag to 0"
  }
}
bind $f.midpt.e <ButtonRelease-3> { helpwin bwmid }

### 3D ROI/mask/FILL
############################################################################
set f .mri.main.left.view.butt.farright
frame $f.aroi -bg $bgcol
pack $f.aroi -side top
## roi
checkbutton $f.aroi.ck -variable labelflag -font $ffont -text "roi" -bd 0 \
  -padx 0 -command {
  logcmd "set labelflag $labelflag"
  redraw
  logcmd "redraw"
}
bind $f.aroi.ck <ButtonRelease-3> { helpwin roi_ck }
## labelmask (m)
checkbutton $f.aroi.ck2 -variable labelmaskflag -font $ffont -text "m" -bd 0 \
  -padx 0 -command {
  logcmd "set labelmaskflag $labelmaskflag"
  if {$labelflag} {
    set labelflag 0
    logcmd "set labelflag $labelflag"
  }
  redraw
  logcmd "redraw"
}
bind $f.aroi.ck2 <ButtonRelease-3> { helpwin roi_ckmask }
pack $f.aroi.ck $f.aroi.ck2 -side left
## FILL
buttons $f "FILL" {
  if {$roisinitedflag} {
    set resp [okreplace "" "One (or more) ROI's have already been FILL'ed:\
                        \n\n  Append FILL to existing ROI?\
                          \n                  or\
                          \n  Clear, then FILL new ROI?" \
      "Clear/FILL" "Append"]
    if {$resp == 0} { confirmalert "nothing FILL'ed" }
    if {$resp == 1} {
      clear_rois
      logcmd "clear_rois"
      logcmd "set fillrad $fillrad"
      fill_roi
      logcmd "fill_roi"
      confirmalert "clear, fill new ROI"
    }
    if {$resp == 2} {
      logcmd "set fillrad $fillrad"
      fill_roi
      logcmd "fill_roi"
      redraw  ;# why needed when funct redraws, too?
      confirmalert "existing ROI appended"
    }
  } else {
    logcmd "set fillrad $fillrad"
    fill_roi
    logcmd "fill_roi"
    confirmalert "clear, fill new ROI"
  }
} row 0 0
## second FILL overload
bind $f.aFILL.bu <ButtonRelease-2> {
  if {$fillroi_allocated} {
    clear_rois
    logcmd "clear_rois"
    confirmalert "all ROIs cleared"
  } else {
    confirmalert "no ROI loaded or FILL'd yet"
  }
}
## third FILL overload
bind $f.aFILL.bu <Shift-ButtonRelease-1> {
  if {$fillroi_allocated} {
    vol_rois
    logcmd "vol_rois"
  } else {
    confirmalert "no ROI loaded or FILL'd yet"
  }
}
# use event gen hack here b/c compact/readable
proc fillroi_std { } {
  event generate .mri.main.left.view.butt.farright.aFILL.bu <ButtonRelease-1>
}
proc fillroi_clear { } {
  event generate .mri.main.left.view.butt.farright.aFILL.bu <ButtonRelease-2>
}
proc fillroi_measvol { } {
  event generate .mri.main.left.view.butt.farright.aFILL.bu <Shift-ButtonRelease-1>
}
#bind $f.aFILL.bu <ButtonRelease-3> { helpwin roi_fill }
bind $f.aFILL.bu <ButtonRelease-3> {
  helpwin roi_fill
  buttonbar \
    "\"Fill 3D ROI around cursor (left-click-FILL)\" \
     \"Clear All Filled ROI\'s (middle-click-FILL)\" \
     \"Calc Volume Curr ROI\'s (shift-left-clk-FILL)\"" \
    "fillroi_std fillroi_clear fillroi_measvol" \
    ver "FILL Button" roi_fill
}
## fillrad
entry $f.aFILL.e -textvariable fillrad -font $ffont -width 3
pack $f.aFILL.e -side right -padx 0
bind $f.aFILL.e <Return> {
  logcmd "set fillrad $fillrad"
  fill_roi
  logcmd "fill_roi"
}
bind $f.aFILL.e <ButtonRelease-3> { helpwin roi_rad }

### surface
############################################################################
set f .mri.main.right.fi
frame $f.surf
pack $f.surf -side top
## combo
setfile insurf $insurf  ;# make abbrev from C default
tixComboBox $f.surf.cbx -label " surf:" -dropdown true -editable true \
  -variable insurfabbrev -listcmd "listcmd_surf $f.surf.cbx" -listwidth 166 \
  -options "label.width 3 entry.width 13 listbox.height 10 listbox.width 19"
$f.surf.cbx subwidget label config -font $ffont
$f.surf.cbx subwidget entry config -selectforeground black
$f.surf.cbx subwidget listbox config -font $ffont \
  -selectbackground $selbgcol -selectforeground black
$f.surf.cbx config -value $insurfabbrev
pack $f.surf.cbx -side left -padx 0
$f.surf.cbx subwidget entry xview moveto 1
bind [$f.surf.cbx subwidget entry] <Return> "$f.surf.br invoke"
bind [$f.surf.cbx subwidget entry] <ButtonRelease-3> { helpwin surf }
## button
set readsurf2flag 0  ;# intern, not C: read 1st (yellow) or 2nd (green) surface
button $f.surf.br -text "R" -font $ffontb -pady 0 -padx 1 -command {
  setfile insurf [.mri.main.right.fi.surf.cbx subwidget entry get]
  if {$readsurf2flag} {
    read_binary_surface2
    logcmd "read_binary_surface2"
  } else {
    read_binary_surface
    logcmd "read_binary_surface"
  }
  set surfflag $surfflag
  logcmd "set surfflag $surfflag"
  redraw
  logcmd "redraw"
}
pack $f.surf.br -side left
bind $f.surf.br <ButtonRelease-3> { helpwin surf_read }
## jam in complexvalflag button ("cpx " space pushes away from "surf:")
checkbutton $f.surf.ck -variable complexvalflag -font $ffont -text "cpx " \
  -bd 0 -padx 0
pack $f.surf.ck -before $f.surf.cbx -side left
bind $f.surf.ck <ButtonRelease-1> {
  logcmd "set complexvalflag $complexvalflag"
  redraw
  logcmd "redraw"
}
bind $f.surf.ck <ButtonRelease-3> { helpwin complexval }
## jam in read second surface button
checkbutton $f.surf.ck2 -variable readsurf2flag -font $ffont -text "2" \
  -bd 0 -padx 0
pack $f.surf.ck2 -side right
bind $f.surf.ck2 <ButtonRelease-1> {
  if {$readsurf2flag} {
    logcmd "# R button will now call read_binary_surface2"
  } else {
    logcmd "# R button will now call read_binary_surface"
  }
}
bind $f.surf.ck2 <ButtonRelease-3> { helpwin surf2col }

### input/output struct (underlay) dataset
############################################################################
set f .mri.main.right.fi
frame $f.im
pack $f.im -side top
## combo (listbox.width alone clamped to around 18, was given 50?, no label?)
setfile inoutim $inoutim  ;# make abbrev from C default
tixComboBox $f.im.cbx -label "im:" -dropdown true -editable true \
 -variable inoutimabbrev -listcmd "listcmd_ims $f.im.cbx full" -listwidth 243 \
 -options "label.width 2 entry.width 21 listbox.height 10" ;# listbox.width 30
$f.im.cbx subwidget label config -font $ffont
$f.im.cbx subwidget entry config -selectforeground black
$f.im.cbx subwidget listbox config -font $ffont \
  -selectbackground $selbgcol -selectforeground black
$f.im.cbx config -value $inoutimabbrev
pack $f.im.cbx -side left -padx 0
$f.im.cbx subwidget entry xview moveto 1
## buttons
button $f.im.br -text "R" -font $ffontb -pady 0 -padx 2 -command {
  setfile inoutim [.mri.main.right.fi.im.cbx subwidget entry get]
  test_read_images
  redraw
  logcmd "redraw"
}
button $f.im.bw -text "W" -font $ffontb -pady 0 -padx 1 -command {
  setfile inoutim [.mri.main.right.fi.im.cbx subwidget entry get]
  set writeallCORflag 1
  test_write_images allownew
}
pack $f.im.br $f.im.bw -side left
bind [$f.im.cbx subwidget entry] <ButtonRelease-3> { helpwin imentry }
bind $f.im.br <ButtonRelease-3> { helpwin imread }
bind $f.im.bw <ButtonRelease-3> { helpwin imwrite }

### roiup: upsampled ROI/label (vs. roin: native ROI/label)
############################################################################
set f .mri.main.right.fi
frame $f.roiup
pack $f.roiup -side top -fill x -padx 0
## combo
setfile uplabel $uplabel ;# create abbrev from possibly-set-by-label
tixComboBox $f.roiup.cbx -label "roiup:" -dropdown true -editable true \
  -variable uplabelabbrev \
  -listcmd "listcmd_getbriks $f.roiup.cbx" -listwidth 418 \
  -options "label.width 4 entry.width 17 listbox.height 10" ;# listbox.width 55
$f.roiup.cbx subwidget label config -font $ffont
$f.roiup.cbx subwidget entry config -selectforeground black
$f.roiup.cbx subwidget listbox config -font $ffont \
  -selectbackground $selbgcol -selectforeground black
$f.roiup.cbx config -value $uplabelabbrev
pack $f.roiup.cbx -side left -padx 2
$f.roiup.cbx subwidget entry xview end
bind [$f.roiup.cbx subwidget label] <ButtonRelease-3> { helpwin roin2up }
bind [$f.roiup.cbx subwidget entry] <ButtonRelease-3> { helpwin roiup }
## buttons
button $f.roiup.br -text "R" -font $ffontb -pady 0 -padx 0 -command {
  setfile uplabel [.mri.main.right.fi.roiup.cbx subwidget entry get]
  readupsamproi  ;# logs
}
button $f.roiup.bw -text "W" -font $ffontb -pady 0 -padx 0 -command {
  setfile uplabel [.mri.main.right.fi.roiup.cbx subwidget entry get]
  testreplace $uplabel write_roi
}
# 1st 'W' overload -- type in segid num (vs. ROI BRIK)
bind $f.roiup.bw <ButtonRelease-2> {
  setfile uplabel [.mri.main.right.fi.roiup.cbx subwidget entry get]
  confirmalert "write all current integer MGH segid's into BRIK:\n\n$uplabel"
  testreplace $uplabel write_allsegids
}
bind [$f.roiup.cbx subwidget entry] <Return> {
  .mri.main.right.fi.roiup.br invoke
}
button $f.roiup.bt -text "T" -font $ffontb -pady 0 -padx 0 -command {
  gettseries       ;# call write_roi_timecourses (testreplace logs)
}
# 1st 'T' overload -- type in segid num (vs. ROI BRIK)
bind $f.roiup.bt <ButtonRelease-2> {
  getsegidtseries  ;# make tmp roi, call write_roi_timecourses with it
}
pack $f.roiup.br $f.roiup.bw $f.roiup.bt -side right
bind $f.roiup.br <ButtonRelease-3> { helpwin roiup_read }
bind $f.roiup.bw <ButtonRelease-3> { helpwin roiup_write }
bind $f.roiup.bt <ButtonRelease-3> { helpwin roiup_time }

### roin: native ROI/label
############################################################################
set f .mri.main.right.fi
frame $f.roin
pack $f.roin -side top -fill x -padx 0
### combo
setfile rawlabel $rawlabel ;# create abbrev from possibly-set-by-label
set currabbrev $rawlabelabbrev
tixComboBox $f.roin.cbx -label "roin:" -dropdown true -editable true \
  -variable rawlabelabbrev -listwidth 418 \
  -options "label.width 3 entry.width 22 listbox.height 10" ;# listbox.width 55
$f.roin.cbx subwidget label config -font $ffont
$f.roin.cbx subwidget entry config -selectforeground black
$f.roin.cbx subwidget listbox config -font $ffont \
  -selectbackground $selbgcol -selectforeground black
set fullfilelist [glob -nocomplain $isession/$scandir/*+orig.BRIK]
if [llength fullfilelist] { set rawlabel [lindex $fullfilelist 0] }
set abbrevlist ""
foreach fullfile $fullfilelist {
  setfile rawlabel $fullfile; set abbrevlist "$abbrevlist $rawlabelabbrev"
}
foreach abbrev $abbrevlist { $f.roin.cbx insert end $abbrev }
setfile rawlabel $currabbrev
$f.roin.cbx config -value $currabbrev
$f.roin.cbx subwidget entry xview end
pack $f.roin.cbx -side left -padx 2
bind [$f.roin.cbx subwidget label] <ButtonRelease-3> { helpwin roin2up }
bind [$f.roin.cbx subwidget entry] <ButtonRelease-3> { helpwin roin }
### buttons
button $f.roin.br -text "R" -font $ffontb -pady 0 -padx 0 -command {
  setfile rawlabel [.mri.main.right.fi.roin.cbx subwidget entry get]
  readnativeroi  ;# logs
}
pack $f.roin.br -side right
bind $f.roin.br <ButtonRelease-3> { helpwin roin_read }

#### clicking bold "roin" or "roiup" labels swaps native/upsamp
############################################################################
$f.roiup.cbx subwidget label config -font $ffontb
$f.roin.cbx subwidget label config -font $ffontb
bind [$f.roiup.cbx subwidget label] <ButtonRelease-1> { \
  pack .mri.main.right.fi.roin -after .mri.main.right.fi.roiup; \
  pack forget .mri.main.right.fi.roiup }
bind [$f.roin.cbx subwidget label] <ButtonRelease-1> { \
  pack .mri.main.right.fi.roiup -after .mri.main.right.fi.roin; \
  pack forget .mri.main.right.fi.roin; }
pack forget .mri.main.right.fi.roin  ;# start w/upsamp (hide native vs val,msk)

### valup (upsampled)
############################################################################
set f .mri.main.right.fi
frame $f.valup
pack $f.valup -side top -fill x -padx 0
## combo
setfile upstatpatt $upstatpatt ;# create abbrev from possibly-set-by -upreal
tixComboBox $f.valup.cbx -label "valup:" -dropdown true -editable true \
  -variable upstatpattabbrev \
  -listcmd "listcmd_getbriks $f.valup.cbx alsobfloat" -listwidth 418 \
  -options "label.width 5 entry.width 17 listbox.height 10" ;# listbox.width 55
$f.valup.cbx subwidget label config -font $ffont
$f.valup.cbx subwidget entry config -selectforeground black
$f.valup.cbx subwidget listbox config -font $ffont \
  -selectbackground $selbgcol -selectforeground black
$f.valup.cbx config -value $upstatpattabbrev
pack $f.valup.cbx -side left -padx 2
$f.valup.cbx subwidget entry xview end
bind [$f.valup.cbx subwidget label] <ButtonRelease-3> { helpwin valn2up }
bind [$f.valup.cbx subwidget entry] <ButtonRelease-3> { helpwin valup }
## buttons
button $f.valup.br -text "R" -font $ffontb -pady 0 -padx 1 -command {
  setfile upstatpatt [.mri.main.right.fi.valup.cbx subwidget entry get]
  readupsampstats  ;# logs
  set overlayflag 1
  logcmd "set overlayflag 1"
  redraw
  logcmd "redraw"
}
button $f.valup.bw -text "W" -font $ffontb -pady 0 -padx 1 -command {
  setfile upstatpatt [.mri.main.right.fi.valup.cbx subwidget entry get]
  testreplace $upstatpatt writeupsampstats  ;# logs
}
pack $f.valup.br $f.valup.bw -side left
bind $f.valup.br <ButtonRelease-3> { helpwin valup_read }
bind $f.valup.bw <ButtonRelease-3> { helpwin valup_write }

### valn (native)
############################################################################
set f .mri.main.right.fi
frame $f.valn
pack $f.valn -side top -fill x -padx 2
## combo
setfile statpatt $statpatt  ;# create abbrev from possibly-set-by -real
set currabbrev $statpattabbrev
tixComboBox $f.valn.cbx -label "valn:" -dropdown true -editable true \
  -variable statpattabbrev -listwidth 418 \
  -options "label.width 4 entry.width 21 listbox.height 10" ;# listbox.width 55
$f.valn.cbx subwidget label config -font $ffont
$f.valn.cbx subwidget entry config -selectforeground black
$f.valn.cbx subwidget listbox config -font $ffont \
  -selectbackground $selbgcol -selectforeground black
set fullfilelist [glob -nocomplain $isession/$scandir/*+orig.BRIK]
set fullfilelist "$fullfilelist\
  [glob -nocomplain $isession/$scandir/*_???.bfloat]"
set fullfilelist "$fullfilelist\
  [glob -nocomplain $isession/$scandir/*.mgz]"
set fullfilelist "$fullfilelist\
  [glob -nocomplain $isession/$scandir/*.mgh]"
if [llength fullfilelist] { set statpatt [lindex $fullfilelist 0] }
set abbrevlist ""
foreach fullfile $fullfilelist {
  setfile statpatt $fullfile; set abbrevlist "$abbrevlist $statpattabbrev"
}
foreach abbrev $abbrevlist { $f.valn.cbx insert end $abbrev }
setfile statpatt $currabbrev
$f.valn.cbx config -value $currabbrev   ;# N.B.: doesn't select in dropdown
$f.valn.cbx subwidget entry xview end   ;# see suffix
#TODO: would have to search listbox to find numerical index for next cmd
#$f.valn.cbx subwidget listbox selection set 2  ;# selects 3rd listbox entry
pack $f.valn.cbx -side left -padx 2
bind [$f.valn.cbx subwidget label] <ButtonRelease-3> { helpwin valn2up }
bind [$f.valn.cbx subwidget entry] <ButtonRelease-3> { helpwin valn }
## buttons
button $f.valn.br -text "R" -font $ffontb -pady 0 -padx 1 -command {
  setfile statpatt [.mri.main.right.fi.valn.cbx subwidget entry get]
  fix_statpatt_if_bfloat
  readnativestats  ;# logs
  set overlayflag 1
  logcmd "set overlayflag 1"
  redraw
  logcmd "redraw"
}
pack $f.valn.br -side left
bind $f.valn.br <ButtonRelease-3> { helpwin valn_read }

### clicking bold "valn" or "valup" labels swaps native/upsamp
############################################################################
$f.valup.cbx subwidget label config -font $ffontb
$f.valn.cbx subwidget label config -font $ffontb
bind [$f.valup.cbx subwidget label] <ButtonRelease-1> { \
  pack .mri.main.right.fi.valn -after .mri.main.right.fi.valup; \
  pack forget .mri.main.right.fi.valup }
bind [$f.valn.cbx subwidget label] <ButtonRelease-1> { \
  pack .mri.main.right.fi.valup -after .mri.main.right.fi.valn; \
  pack forget .mri.main.right.fi.valn; }
pack forget .mri.main.right.fi.valup  ;# start w/native (hide upsamp)

### mskup (upsampled)
############################################################################
set f .mri.main.right.fi
frame $f.mskup
pack $f.mskup -side top -fill x -padx 0
## check
checkbutton $f.mskup.ck -variable overlaymaskflag -command secondsquashents \
  -font $ffont -text "" -bd 0 -padx 0
pack $f.mskup.ck -side left -padx 0
bind $f.mskup.ck <ButtonRelease-1> {
  if {$sfthresh == 0.0 && $sfslope == 0.0} {
    confirmalert "N.B.: Both sfthresh=0.0 and sfslope=0.0 disables statmask!\
              \n\nresetting sfthresh to 0.01"
    set sfthresh 0.01
    logcmd "set sfthresh 0.01"
  }
  logcmd "set overlaymaskflag $overlaymaskflag" ;# report updated check state
  redraw
  logcmd "redraw"
}
bind $f.mskup.ck <ButtonRelease-3> { helpwin mask_ck }
## combo
setfile upstatpatt_m $upstatpatt_m ;# create abbrev from possib-set-by -upmask
tixComboBox $f.mskup.cbx -label "mskup:" -dropdown true -editable true \
  -variable upstatpatt_mabbrev \
  -listcmd "listcmd_getbriks $f.mskup.cbx alsobfloat" -listwidth 418 \
  -options "label.width 6 entry.width 14 listbox.height 10" ;# listbox.width 55
$f.mskup.cbx subwidget label config -font $ffont
$f.mskup.cbx subwidget entry config -selectforeground black
$f.mskup.cbx subwidget listbox config -font $ffont \
  -selectbackground $selbgcol -selectforeground black
$f.mskup.cbx config -value $upstatpatt_mabbrev
pack $f.mskup.cbx -side left -padx 2
$f.mskup.cbx subwidget entry xview end
bind [$f.mskup.cbx subwidget label] <ButtonRelease-3> { helpwin maskn2up }
bind [$f.mskup.cbx subwidget entry] <ButtonRelease-3> { helpwin maskup }
## buttons
button $f.mskup.br -text "R" -font $ffontb -pady 0 -padx 0 -command {
  setfile upstatpatt_m [.mri.main.right.fi.mskup.cbx subwidget entry get]
  readupsampmask  ;# logs
  set overlayflag 1
  logcmd "set overlayflag 1"
  redraw
  logcmd "redraw"
}
button $f.mskup.bw -text "W" -font $ffontb -pady 0 -padx 0 -command {
  setfile upstatpatt_m [.mri.main.right.fi.mskup.cbx subwidget entry get]
  testreplace $upstatpatt_m writeupsampmask
}
pack $f.mskup.br $f.mskup.bw -side left -padx 0
bind $f.mskup.br <ButtonRelease-3> { helpwin maskup_read }
bind $f.mskup.bw <ButtonRelease-3> { helpwin maskup_write }

### mskn (native)
############################################################################
set f .mri.main.right.fi
frame $f.mskn
pack $f.mskn -side top -fill x -padx 0
## check (N.B.: dup, but avoid another subframe)
checkbutton $f.mskn.ck -variable overlaymaskflag -command secondsquashents \
  -font $ffont -text "" -bd 0 -padx 0
pack $f.mskn.ck -side left -padx 0
bind $f.mskn.ck <ButtonRelease-1> {
  if {$sfthresh == 0.0 && $sfslope == 0.0} {
    confirmalert "N.B.: Both sfthresh=0.0 and sfslope=0.0 disables statmask!\
              \n\nresetting sfthresh to 0.01"
    set sfthresh 0.01
    logcmd "set sfthresh 0.01"
  }
  logcmd "set overlaymaskflag $overlaymaskflag"
  redraw
  logcmd "redraw"
}
bind $f.mskn.ck <ButtonRelease-3> { helpwin mask_ck }
## combo
setfile statpatt_m $statpatt_m  ;# create abbrev from possibly-set-by -mask
set currabbrev $statpatt_mabbrev
tixComboBox $f.mskn.cbx -label "mskn:" -dropdown true -editable true \
  -variable statpatt_mabbrev -listwidth 418 \
  -options "label.width 5 entry.width 17 listbox.height 10" ;# listbox.width 55
$f.mskn.cbx subwidget label config -font $ffont
$f.mskn.cbx subwidget entry config -selectforeground black
$f.mskn.cbx subwidget listbox config -font $ffont \
  -selectbackground $selbgcol -selectforeground black
set fullfilelist [glob -nocomplain $isession/$scandir/*+orig.BRIK]
set fullfilelist "$fullfilelist\
  [glob -nocomplain $isession/$scandir/*_???.bfloat]"
if [llength fullfilelist] { set statpatt_m [lindex $fullfilelist 0] }
set abbrevlist ""
foreach fullfile $fullfilelist {
  setfile statpatt_m $fullfile
  set abbrevlist "$abbrevlist $statpatt_mabbrev"
}
foreach abbrev $abbrevlist { $f.mskn.cbx insert end $abbrev }
setfile statpatt_m $currabbrev
$f.mskn.cbx config -value $currabbrev
$f.mskn.cbx subwidget entry xview end
pack $f.mskn.cbx -side left -padx 2
bind [$f.mskn.cbx subwidget label] <ButtonRelease-3> { helpwin maskn2up }
bind [$f.mskn.cbx subwidget entry] <ButtonRelease-3> { helpwin maskn }
## buttons
button $f.mskn.br -text "R" -font $ffontb -pady 0 -padx 1 -command {
  setfile statpatt_m [.mri.main.right.fi.mskn.cbx subwidget entry get]
  fix_statpatt_m_if_bfloat
  readnativemask  ;# logs
  set overlayflag 1
  logcmd "set overlayflag 1"
  redraw
  logcmd "redraw"
}
pack $f.mskn.br -side left -padx 0
bind $f.mskn.br <ButtonRelease-3> { helpwin maskn_read }

### clicking bold "mskn" or "mskup" labels swaps native/upsamp
############################################################################
$f.mskup.cbx subwidget label config -font $ffontb
$f.mskn.cbx subwidget label config -font $ffontb
bind [$f.mskup.cbx subwidget label] <ButtonRelease-1> { \
  pack .mri.main.right.fi.mskn -after .mri.main.right.fi.mskup;
  pack forget .mri.main.right.fi.mskup;
}
bind [$f.mskn.cbx subwidget label] <ButtonRelease-1> { \
  pack .mri.main.right.fi.mskup -after .mri.main.right.fi.mskn;
  pack forget .mri.main.right.fi.mskn;
}
pack forget .mri.main.right.fi.mskup  ;# start w/native (hide upsamp)

### save rgb
############################################################################
## entry
edlabval $f "rgb" default  w 3 20
setfile rgb $rgb   ;# make abbrev
$f.rgb.e config -textvariable rgbabbrev
set rel_rgbname [file tail $rgb]  ;# dir resettable; global for uplevel setfile
bind $f.rgb.e <ButtonRelease-3> { helpwin rgb }
## button
$f.rgb.bw config -command {
  setfile rgb [.mri.main.right.fi.rgb.e get]
  raise_window
  logcmd "raise_window"
  redraw
  logcmd "redraw"
  testreplace $rgb save_rgb
} -padx 1 -text W
bind $f.rgb.bw <ButtonRelease-3> { helpwin rgb_write }
## no redraw button
button $f.rgb.bw2 -text "" -font $ffontb -pady 0 -padx 3 -command {
  setfile rgb [.mri.main.right.fi.rgb.e get]
  testreplace $rgb save_rgb
} ;# save overlay timecourse graph (no redraw)
pack $f.rgb.bw2 -side left
bind $f.rgb.bw2 <ButtonRelease-3> { helpwin rgb_write2 }
## tiffoutflag
checkbutton $f.rgb.ck -variable tiffoutflag -padx 0 -command {
  if {$tiffoutflag} {
    setfile rgb [file rootname [.mri.main.right.fi.rgb.e get]].tiff
  } else {
    setfile rgb [file rootname [.mri.main.right.fi.rgb.e get]].rgb
  }
}
pack $f.rgb.ck -before $f.rgb.bw -side left -padx 0
bind $f.rgb.ck <ButtonRelease-1> { logcmd "set tiffoutflag $tiffoutflag" }
bind $f.rgb.ck <ButtonRelease-3> { helpwin tiffout }

### norm (piecewise-linear/spherical) (F3 interface only)
############################################################################
set f .mri.main.right.snorm.but
## TEST button
buttons $f TEST { } row 0 4 
bind $f.aTEST.bu <ButtonRelease-1> {
  norm_allslices_toim2 $normdir
  logcmd "set contrastslope $contrastslope"
  logcmd "set contrastnochange $contrastnochange"
  logcmd "set sphnormflag $sphnormflag"
  logcmd "set gaussnormflag $gaussnormflag"
  if {$sphnormflag} {
    logcmd "set newimc $newimc    ;# P/A"
    logcmd "set newjc $newjc    ;# R/L"
    logcmd "set newic $newic    ;# I/S"
    logcmd "set lim0 $lim0"; logcmd "set ffrac0 $ffrac0"
  } else {
    logcmd "set lim0 $lim0"; logcmd "set ffrac0 $ffrac0"
    logcmd "set lim1 $lim1"; logcmd "set ffrac1 $ffrac1"
    logcmd "set lim2 $lim2"; logcmd "set ffrac2 $ffrac2"
    logcmd "set lim3 $lim3"; logcmd "set ffrac3 $ffrac3"
  }
  logcmd "norm_allslices_toim2 $normdir"
  .mri.main.right.cmp.im2.aCOMPARE.bu config -relief sunken

}
# 1 overload -- apply locnorm hacks
bind $f.aTEST.bu <ButtonRelease-2> {
  if [okreplace ""\
     "OK to run experimental local normalization\
        \non editable buffer?\
        \n  -- output goes to im2\
        \n  -- rad=10 takes a few min\
        \n  -- multi-threaded (may speed up CPU fans)\
      \n\nCurrent Parameters:\
      \n\n    radius = $prad\
        \n        from \"rad:\" entry (in pixels)\
      \n\n    operation = $imim2opnum\
        \n        from entry after \"OP\" button (F3 interface)\
        \n        0=median, 1=histmax\
      \n\n    brain limits = $white_lolim to $white_hilim\
        \n        from entries beside \"TRUNC\""\
      "Local Normalize"] {
    locnorm_allslices $prad $imim2opnum 2
    logcmd "locnorm_allslices $prad $imim2opnum 2"
  }
}
## use event gen hack here to keep main bind's parallel/close to APPLY below
proc testnorm_lin_or_sph { } {
  event generate .mri.main.right.snorm.but.aTEST.bu <ButtonRelease-1>
}
proc testnorm_loc { } {
  event generate .mri.main.right.snorm.but.aTEST.bu <ButtonRelease-2>
}
#bind $f.aTEST.bu <ButtonRelease-3> { helpwin test1 }
bind $f.aTEST.bu <ButtonRelease-3> {
  helpwin test1
  buttonbar \
    "\"PiecewiaseLin or Spherical Normalize (left-clk-TEST)\" \
     \"Run Experimental Local Normalize (middle-click-TEST)\"" \
    "testnorm_lin_or_sph testnorm_loc" \
    ver "TEST (normalize) Button" test1
}
# label
label $f.la1 -text " PieceWiseLinNorm " -font $ffontb
pack $f.la1 -side left
bind $f.la1 <ButtonRelease-1> { contrrampctrls }
# APPLY button
buttons $f APPLY {  ;# was ALL, verbose/redundant report easier transcribe
  norm_allslices $normdir
  logcmd "set contrastslope $contrastslope"
  logcmd "set contrastnochange $contrastnochange"
  logcmd "set sphnormflag $sphnormflag"
  logcmd "set gaussnormflag $gaussnormflag"
  if {$sphnormflag} {
    logcmd "set newimc $newimc    ;# P/A"
    logcmd "set newjc $newjc    ;# R/L"
    logcmd "set newic $newic    ;# I/S"
    logcmd "set lim0 $lim0"; logcmd "set ffrac0 $ffrac0"
  } else {
    logcmd "set lim0 $lim0"; logcmd "set ffrac0 $ffrac0"
    logcmd "set lim1 $lim1"; logcmd "set ffrac1 $ffrac1"
    logcmd "set lim2 $lim2"; logcmd "set ffrac2 $ffrac2"
    logcmd "set lim3 $lim3"; logcmd "set ffrac3 $ffrac3"
  }
  logcmd "norm_allslices $normdir"
  logcmd "#HOWTO apply this hand normalization to any file (overwrites infile):"
  logcmd "#  put commands above (start w/contrastslope) into tmpscript.tcl"
  logcmd "#  add following two lines to tmpscript.tcl:"
  logcmd "#    write_images"
  logcmd "#    exit"
  logcmd "#  tkmedit <inputfile>.mgz -tcl tmpscript.tcl"
  .mri.main.right.cmp.im2.aCOMPARE.bu config -relief raised
} row 0 4
bind $f.aAPPLY.bu <ButtonRelease-3> { helpwin all }  ;# was aALL
## lims
set f .mri.main.right.snorm.bot.lim
edlabval $f "lim3" 0 n 5 3
edlabval $f "lim2" 0 n 5 3
edlabval $f "lim1" 0 n 5 3
edlabval $f "lim0" 0 n 5 3
$f.lim3.e config -textvariable lim3
$f.lim2.e config -textvariable lim2
$f.lim1.e config -textvariable lim1
$f.lim0.e config -textvariable lim0
bind $f.lim3.e <Return> {
  #.mri.main.right.snorm.but.aTEST.bu invoke
  event generate .mri.main.right.snorm.but.aTEST.bu <ButtonRelease-1>
  logcmd "set lim3 $lim3"
}
bind $f.lim2.e <Return> {
  #.mri.main.right.snorm.but.aTEST.bu invoke
  event generate .mri.main.right.snorm.but.aTEST.bu <ButtonRelease-1>
  logcmd "set lim2 $lim2"
}
bind $f.lim1.e <Return> {
  #.mri.main.right.snorm.but.aTEST.bu invoke
  event generate .mri.main.right.snorm.but.aTEST.bu <ButtonRelease-1>
  logcmd "set lim1 $lim1"
}
bind $f.lim0.e <Return> {
  #.mri.main.right.snorm.but.aTEST.bu invoke
  event generate .mri.main.right.snorm.but.aTEST.bu <ButtonRelease-1>
  logcmd "set lim0 $lim0"
}
## fracs
set f .mri.main.right.snorm.bot.ffrac
edlabval $f "ffrac3" 0 n 7 4
edlabval $f "ffrac2" 0 n 7 4
edlabval $f "ffrac1" 0 n 7 4
edlabval $f "ffrac0" 0 n 7 4
$f.ffrac3.e config -textvariable ffrac3
$f.ffrac2.e config -textvariable ffrac2
$f.ffrac1.e config -textvariable ffrac1
$f.ffrac0.e config -textvariable ffrac0
bind $f.ffrac3.e <Return> {
  #.mri.main.right.snorm.but.aTEST.bu invoke
  event generate .mri.main.right.snorm.but.aTEST.bu <ButtonRelease-1>
  logcmd "set ffrac3 $ffrac3"
}
bind $f.ffrac2.e <Return> {
  #.mri.main.right.snorm.but.aTEST.bu invoke
  event generate .mri.main.right.snorm.but.aTEST.bu <ButtonRelease-1>
  logcmd "set ffrac2 $ffrac2"
}
bind $f.ffrac1.e <Return> {
  #.mri.main.right.snorm.but.aTEST.bu invoke
  event generate .mri.main.right.snorm.but.aTEST.bu <ButtonRelease-1>
  logcmd "set ffrac1 $ffrac1"
}
bind $f.ffrac0.e <Return> {
  #.mri.main.right.snorm.but.aTEST.bu invoke
  event generate .mri.main.right.snorm.but.aTEST.bu <ButtonRelease-1>
  logcmd "set ffrac0 $ffrac0"
}
## normdirs, imim2 operation, sphere field
set f .mri.main.right.snorm.bot.dir
radios $f "" "P/A" normdir 0 3 col
radios $f "" "I/S" normdir 1 3 col
radios $f "" "R/L" normdir 2 3 col
bind $f.aP/A.ra <ButtonRelease-1> { logcmd "set normdir $normdir" }
bind $f.aI/S.ra <ButtonRelease-1> { logcmd "set normdir $normdir" }
bind $f.aR/L.ra <ButtonRelease-1> { logcmd "set normdir $normdir" }
frame $f.op -bg $bgcol
pack $f.op -side top
button $f.op.bu -text "OP" -font $ffontb -pady 0 -padx 0 -command "imim2opctrls"
entry $f.op.e -textvariable imim2opnum -font $ffont -width 2
pack $f.op.bu $f.op.e -side left -padx 0 -pady 0
bind $f.op.e <Return> { logcmd "set imim2opnum $imim2opnum" }
checkbutton $f.ck -variable sphnormflag -font $ffont -text "sph" -bd 0 -padx 0
pack $f.ck -side top
bind $f.ck <ButtonRelease-1> { logcmd "set sphnormflag $sphnormflag" }
bind $f.ck <ButtonRelease-3> { helpwin sphnorm }
bind $f.op.bu <ButtonRelease-3> { helpwin imim2op; imim2opctrls }
bind $f.op.e <ButtonRelease-3> { helpwin imim2op }
# 1 overload
bind $f.ck <ButtonRelease-2> {
  set gaussnormflag [expr !$gaussnormflag]
  logcmd "set gaussnormflag $gaussnormflag"
  if {$gaussnormflag} {
    if {!$sphnormflag} {
      set sphnormflag 1
      logcmd "set sphnormflag $sphnormflag"
      confirmalert "set sphere norm profile to Gaussian\
                  \n(autoset: set sphnormflag 1)"
    } else {
      confirmalert "set sphere norm profile to Gaussian"
    }
  } else {
    confirmalert "set sphere norm profile to linear"
  }
}

### TRUNC, Plane Filters
############################################################################
set f .mri.main.right.wm.trufil

## TRUNC button
buttons $f "TRUNC" { } row 1 2
# bind no-arg TRUNC procs (also used by buttonbar)
bind $f.aTRUNC.bu <ButtonRelease-1>         { trunc_tmpim1 }
bind $f.aTRUNC.bu <ButtonRelease-2>         { trunc_toim1 }
bind $f.aTRUNC.bu <Shift-ButtonRelease-2>   { trunc_countim1_inlims }
bind $f.aTRUNC.bu <Control-ButtonRelease-2> { trunc_edim1_im2inlims_togray }
bind $f.aTRUNC.bu <Control-ButtonRelease-3> { trunc_edim1_im2inlims_togray_savelims }
bind $f.aTRUNC.bu <Shift-ButtonRelease-3>   { trunc_cpim1toim2_im1inlims_togray}
# TRUNC R-click bind: helpwin + no-arg procs buttonbar popup
bind $f.aTRUNC.bu <ButtonRelease-3> {
  helpwin wmtrunc
  boundseditctrls
  buttonbar \
    "\"Truncate Saving Range: Toggle (left-click-TRUNC)\" \
     \"Truncate Saving Range: Apply (middle-click-TRUNC)\" \
     \"Count Voxels Within Range (shift-middle-clk-TRUNC)\" \
     \"Im->Targval If Im2 Range (ctrl-middle-clk-TRUNC)\" \
     \"Im->Targval If Im2 Range, Save Im (ctrl-R-clk-TRUNC)\" \
     \"Cp Im->Im2, Im->Targval If Range (shift-R-clk-TRUNC)\" \
     \"Truncate Using 2D Color Space Ellipse (no hotkey)\"" \
    "trunc_tmpim1 trunc_toim1 trunc_countim1_inlims \
     trunc_edim1_im2inlims_togray trunc_edim1_im2inlims_togray_savelims \
     trunc_cpim1toim2_im1inlims_togray imim2opctrls" \
    ver "TRUNC Button" wmtrunc
}
# lo lim entry
frame $f.lo -bg $bgcol
frame $f.hi -bg $bgcol
entry $f.lo.e -textvariable white_lolim -font $ffont -width 3
bind $f.lo.e <Return> {
  set truncflag 0
  logcmd "set white_lolim $white_lolim"
  trunc_tmpim1
}
# hi lim entry
entry $f.hi.e -textvariable white_hilim -font $ffont -width 3
bind $f.hi.e <Return> {
  set truncflag 0
  logcmd "set white_lolim $white_hilim"
  trunc_tmpim1
}
pack $f.lo $f.hi $f.lo.e $f.hi.e -side left
label $f.sp -text " " -font $ffont
pack $f.sp -side left

## PF button
buttons $f "PF" { run_wmfilter stdtrunc to_buf1 } row 1 1
# 1 overload
bind .mri.main.right.wm.trufil.aPF.bu <ButtonRelease-2> {
  run_wmfilter stdtrunc to_buf2  ;# logs
}
# buttonbar: need no-arg procs
proc pf_origwmfilter2editable { } { run_wmfilter stdtrunc to_buf1 }
proc pf_origwmfilter2compare { }  { run_wmfilter stdtrunc to_buf2 }
# PF R-click bind: helpwin + no-arg procs buttonbar popup
bind $f.aPF.bu <ButtonRelease-3> {
  helpwin wmfilterstd
  buttonbar \
    "\"Run Orig WmFilter/Trunc on Editable (left-click-PF)\" \
     \"Run Orig WmFilter/Trunc, Output->Im2 (mid-clk-PF)\"" \
    "pf_origwmfilter2editable pf_origwmfilter2compare" \
    ver "PF Button (least-var. loc. plane filter, original version)" wmfilterstd
}
# gray hi lim entry
frame $f.ghi
entry $f.ghi.e -textvariable gray_hilim -font $ffont -width 3
label $f.sp2 -text " " -font $ffont
pack $f.ghi $f.ghi.e $f.sp2 -side left
bind $f.ghi.e <Return> { logcmd "set gray_hilim $gray_hilim" }

## PFGAU button
buttons $f "PFGAU"                        { run_wmfilter gauss to_buf1 } row 1 1
# 3 overloads
bind $f.aPFGAU.bu <ButtonRelease-2>       { run_wmfilter gauss to_buf2 }
bind $f.aPFGAU.bu <Shift-ButtonRelease-1> { run_wmfilter gausstrunc to_buf1 }
bind $f.aPFGAU.bu <Shift-ButtonRelease-2> { run_wmfilter gausstrunc to_buf2 }
# buttonbar: need no-arg procs
proc pfgau_gauss2editable { }      { run_wmfilter gauss to_buf1 }
proc pfgau_gauss2compare { }       { run_wmfilter gauss to_buf2 }
proc pfgau_gausstrunc2editable { } { run_wmfilter gausstrunc to_buf1 }
proc pfgau_gausstrunc2compare { }  { run_wmfilter gausstrunc to_buf2 }
# PFGAU R-click bind: helpwin + no-arg procs buttonbar popup
bind $f.aPFGAU.bu <ButtonRelease-3> {
  helpwin wmfiltergau
  buttonbar \
    "\"Run Gaussian WmFilter on Editable (left-click-PFGAU)\" \
     \"Run Gaussian WmFilter, Output->Im2 (mid-clk-PFGAU)\" \
     \"Run Gaussian WmFilter/Trunc on Editable (shift-left-clk-PFGAU)\" \
     \"Run Gaussian WmFilter/Trunc, Output->Im2 (shift-mid-clk-PFGAU)\"" \
    "pfgau_gauss2editable pfgau_gauss2compare \
     pfgau_gausstrunc2editable pfgau_gausstrunc2compare" \
    ver "PFGAU Button (least-var. local plane filter, Gaussian version)" \
      wmfiltergau
}
# same helpwin for all three entries, add popup w/hidden parms
bind $f.lo.e <ButtonRelease-3> { helpwin truncparms; boundseditctrls }
bind $f.hi.e <ButtonRelease-3> { helpwin truncparms; boundseditctrls }
bind $f.ghi.e <ButtonRelease-3> { helpwin truncparms; boundseditctrls }

### overlay main controls (hideable by secondsquashents)
############################################################################
set f .mri.main.right.wm.thr
## fthresh
edlabval $f "thr" 0 n 2 3 row
$f.thr.e config -textvariable fthresh
bind $f.thr.e <Return> {
  logcmd "set fthresh $fthresh"
  redraw
  logcmd "redraw"
}
bind $f.thr.e <ButtonRelease-3> { helpwin fthresh }
## hideable sfthresh
frame $f.thr.st -bg $bgcol
pack $f.thr.st -side left
entry $f.thr.st.e -textvariable sfthresh -font $ffont -width 3
pack $f.thr.st.e -side left
bind $f.thr.st.e <Return> {
  if {$sfthresh == 0.0 && $sfslope == 0.0} {
    confirmalert "N.B.: Both sfthresh=0.0 and sfslope=0.0 disables statmask!\
              \n\nresetting sfthresh to 0.01"
    set sfthresh 0.01
    logcmd "set sfthresh 0.01"
  }
  logcmd "set sfthresh $sfthresh"
  redraw
  logcmd "redraw"
}
bind $f.thr.st.e <ButtonRelease-3> { helpwin sfthresh }
## fmid
edlabval $f "md" 0 n 3 3 row
$f.md.e config -textvariable fmid
bind $f.md.e <Return> {
  logcmd "set fmid $fmid"
  redraw
  logcmd "redraw"
}
bind $f.md.e <ButtonRelease-3> { helpwin fmid }
## hideable sfmid
frame $f.md.st -bg $bgcol
pack $f.md.st -side left
entry $f.md.st.e -textvariable sfmid -font $ffont -width 3
pack $f.md.st.e -side left
bind $f.md.st.e <Return> {
  logcmd "set sfmid $sfmid"
  redraw
  logcmd "redraw"
}
bind $f.md.st.e <ButtonRelease-3> { helpwin sfmid }
## fslope
edlabval $f "sl" 0 n 2 3 row
$f.sl.e config -textvariable fslope
bind $f.sl.e <Return> {
  logcmd "set fslope $fslope"
  redraw
  logcmd "redraw"
}
bind $f.sl.e <ButtonRelease-3> { helpwin fslope }
## hideable sfslope
frame $f.sl.st -bg $bgcol
pack $f.sl.st -side left
entry $f.sl.st.e -textvariable sfslope -font $ffont -width 3
pack $f.sl.st.e -side left
bind $f.sl.st.e <Return> {
  if {$sfthresh == 0.0 && $sfslope == 0.0} {
    confirmalert "N.B.: Both sfthresh=0.0 and sfslope=0.0 disables statmask!\
              \n\nresetting sfthresh to 0.01"
    set sfthresh 0.01
    logcmd "set sfthresh 0.01"
  }
  logcmd "set sfslope $sfslope"
  redraw
  logcmd "redraw"
}
bind $f.sl.st.e <ButtonRelease-3> { helpwin sfslope }
## init fthresh/fslope/fmid and hideable sfthresh/sfslope/sfmid
secondsquashents

### read im2, COMPARE, tcl buttons
############################################################################
set f .mri.main.right.cmp
frame $f.im2
pack $f.im2 -side top -padx 0
## combo
set im2abbrev "T1"  ;# N.B.: no setfile expansion, read_second_images does it
tixComboBox $f.im2.cbx -label "im2:" -dropdown true -editable true \
  -variable im2abbrev -listcmd "listcmd_ims $f.im2.cbx min" -listwidth 166 \
  -options "label.width 4 entry.width 5 listbox.height 10 listbox.width 19"
$f.im2.cbx subwidget label config -font $ffont -padx 0 -bd 0
$f.im2.cbx subwidget entry config -selectforeground black
$f.im2.cbx subwidget listbox config -font $ffont \
  -selectbackground $selbgcol -selectforeground black
set currabbrev $im2abbrev
$f.im2.cbx config -value $im2abbrev
pack $f.im2.cbx -side left -padx 0
$f.im2.cbx subwidget entry xview moveto 1
## button
button $f.im2.br -text "R" -font $ffontb -pady 0 -padx 0 -command {
  read_second_images [.mri.main.right.cmp.im2.cbx subwidget entry get]
  logcmd "read_second_images [.mri.main.right.cmp.im2.cbx subwidget entry get]"
  .mri.main.right.cmp.im2.aCOMPARE.bu config -relief sunken
  detectshowlabel  ;# logs
}
pack $f.im2.br -side left -padx 0
bind [$f.im2.cbx subwidget entry] <Return> {.mri.main.right.cmp.im2.br invoke}
## label has an action (bold)
$f.im2.cbx subwidget label config -font $ffontb -padx 0
bind [$f.im2.cbx subwidget label] <ButtonRelease-1> { \
  set imim2testctrlswin [controls "2D COLOR-SPACE ELLIPSE\
          \nTRUNCATION TEST\
          \n(to transparent green)\
        \n\nN.B.: requires im2 is loaded      \
          \nN.B.: green if INSIDE col ellipse\
          \nN.B.: to apply (instead of test):\
          \n(1) R-clk TRUNC for buttonbar\
          \n(2) bottom button makes popup" { \
    whitespace imim2elloverlayflag whitespace imcolcent imcolrad \
    whitespace im2colcent im2colrad whitespace overlayalpha } \
    REDRAW checkim2redraw]
  bind $imim2testctrlswin <ButtonRelease-3> { helpwin im2label } ;# R-clk popup
  helpwin im2label  ;# along w/popup
}
bind [$f.im2.cbx subwidget label] <ButtonRelease-3> { helpwin im2label }
bind [$f.im2.cbx subwidget entry] <ButtonRelease-3> { helpwin im2entry }
bind $f.im2.br <ButtonRelease-3> { helpwin im2read }
## MGH label tick ("la")
checkbutton $f.im2.ck -text "la" -variable im2lutoverlayflag \
  -command fscolormap2lut -bd 0 -padx 0 -font $ffont  ;# command logs
pack $f.im2.ck -side left
# overload
bind $f.im2.ck <ButtonRelease-2> {
  set im2boundsflag [expr !$im2boundsflag];
  logcmd "set im2boundsflag $im2boundsflag"
  redraw
  logcmd "redraw"
  confirmalert "toggle \$im2boundsflag to $im2boundsflag\
            \n\n(see R-click help TRUNC entries for details)\
              \n(N.B.: load im2 for this to have an effect!)"
}
bind $f.im2.ck <ButtonRelease-3> { helpwin seglabel }
## F5/micro copy of surface tick
checkbutton $f.im2.ck2 -text "surf" -variable surfflag \
  -command checksurface -bd 0 -padx 0 -font $ffont
bind $f.im2.ck2 <ButtonRelease-3> { helpwin surf_ck }
#pack $f.im2.ck2 -side left  ;# first micro does init pack
## space before COMPARE
frame $f.im2.sp -bg $bgcol -width 0
pack $f.im2.sp -side left
### COMPARE button
buttons $f.im2 "COMPARE" { } row 2 0
$f.im2.aCOMPARE.bu config -font $ffontbb
bind $f.im2.aCOMPARE.bu <ButtonRelease-1>       { compare_im_im2 }
bind $f.im2.aCOMPARE.bu <ButtonRelease-2>       { compare_swap_im_im2 }
bind $f.im2.aCOMPARE.bu <Shift-ButtonRelease-2> { compare_xferedits_im2_toim1 }
bind $f.im2.aCOMPARE.bu <Shift-ButtonRelease-1> { compare_contradj_to_editable }
#bind $f.im2.aCOMPARE.bu <ButtonRelease-3> { helpwin compare }
bind $f.im2.aCOMPARE.bu <ButtonRelease-3> {
  helpwin compare
  buttonbar \
    "\"Compare Editable (im) to im2 (left-click-COMPARE)\" \
     \"Swap Editable (im) and im2 (middle-click-COMPARE)\" \
     \"Transfer Edits in im2 to Editable (shift-mid-clk-COMPARE)\" \
     \"Copy Contrast-Adj'd to Editable (shift-left-clk-COMPARE)\" \
     \"Toggle LinearFlag (click bold \\\"contr:\\\" label)\"" \
    "compare_im_im2 compare_swap_im_im2 compare_xferedits_im2_toim1 \
     compare_contradj_to_editable compare_togglelinearflag" \
    ver "COMPARE Button" compare 
}
### enable/disable tcl logs by click "tcl" label
label $f.im2.la -text "tcl:" -font $ffont -padx 0
pack $f.im2.la -side left -padx 0
bind $f.im2.la <ButtonRelease-1> { enabledisablelog }
bind $f.im2.la <ButtonRelease-3> { helpwin script_record }
if {$mktcllabbold} { .mri.main.right.cmp.im2.la config -font $ffontb }

### two-state SMOOTHSTRUCT/SMOOTH STATS button (toggled by overlayflag)
############################################################################
set f .mri.main.farright
## two-state button
buttons $f SMOOTHGAUSS { } col 2 0
bind $f.aSMOOTHGAUSS.bu <ButtonRelease-1> {
  if {[.mri.main.farright.aSMOOTHGAUSS.bu cget -text] == "SMOOTH STATS"} {
    smooth_stats_3d $kcnt $kfwhm  ;# cmd does redraw
    logcmd "smooth_stats_3d $kcnt $kfwhm"
  } elseif {[.mri.main.farright.aSMOOTHGAUSS.bu cget -text] == "SMOOTHSTRUCT"} {
    smooth_3d $kcnt $kfwhm  ;# cmd does redraw
    logcmd "smooth_3d $kcnt $kfwhm"
  } else {
    confirmalert "unknown button (not SMOOTH STATS or SMOOTHSTRUCT)"
  }
}
setsmoothtype  ;# init SMOOTHGAUSS button text
## smooth controls
frame $f.sm
pack $f.sm -side top
entry $f.sm.e -width 1 -textvariable kcnt -bg $entbgcol -font $ffont \
  -selectbackground $selbgcol -highlightbackground $bgcol \
  -selectforeground black ;# blk: linux
bind $f.sm.e <Return> { logcmd "set kcnt $kcnt" } ;# button reads, too
bind $f.sm.e <ButtonRelease-3> { helpwin kernelsize }
label $f.sm.la -text " fwhm:" -bg $bgcol -font $ffont
entry $f.sm.e2 -width 3 -textvariable kfwhm -bg $entbgcol -font $ffont \
  -selectbackground $selbgcol -highlightbackground $bgcol \
  -selectforeground black ;# blk: linux
bind $f.sm.e2 <Return> { logcmd "set kfwhm $kfwhm" }
bind $f.sm.e2 <ButtonRelease-3> { helpwin fwhm }
checkbutton $f.sm.ck -text "m" -selectcolor $selcol -bg $bgcol -font $ffont \
  -variable smoothoverlaymaskflag -highlightbackground $bgcol -bd 0
bind $f.sm.ck <ButtonRelease-1> {
  logcmd "set smoothoverlaymaskflag $smoothoverlaymaskflag"
}
bind $f.sm.ck <ButtonRelease-3> { helpwin smoothmask }
pack $f.sm.e $f.sm.la $f.sm.e2 $f.sm.ck -side left -padx 0
## buttonbar: procs here to localize obscure butt text control
proc smoothbutt_struct { } {
  global overlayflag
  set overlayflag_saved $overlayflag
  set overlayflag 0  ;# in case viewing loaded overlay
  logcmd "set overlayflag 0"
  setsmoothtype  ;# changes button text, which controls which funct called!
  event generate .mri.main.farright.aSMOOTHGAUSS.bu <ButtonRelease-1> ;# no cmd
  set overlayflag $overlayflag_saved
  logcmd "set overlayflag $overlayflag_saved"
  setsmoothtype  ;# changes button text, which controls which funct called!
  redraw  ;# update redraw by smooth maybe w/diff overlayflag
}
proc smoothbutt_funct { } {
  global overlayflag overlayloaded
  if {!$overlayloaded} {
    confirmalert "No overlay dataset.  Use csurf VOLUME-STATS \
                \nor restart tkmedit with these additional args: \
              \n\n-real <format> *or* -complex <fmt_r> <fmt_i> \
                \n-nslices <num> \
                \n-statres <x> <y> \
                \n-regdat <filename>"
    return
  }
  set overlayflag_saved $overlayflag
  set overlayflag 1  ;# in case tmp off loaded overlay
  logcmd "set overlayflag 1"
  setsmoothtype  ;# changes button text, which controls which funct called!
  event generate .mri.main.farright.aSMOOTHGAUSS.bu <ButtonRelease-1> ;# no cmd
  set overlayflag $overlayflag_saved
  logcmd "set overlayflag $overlayflag_saved"
  setsmoothtype  ;# changes button text, which controls which funct called!
  redraw  ;# update redraw by smooth maybe w/diff overlayflag
}
proc smoothbutt_struct_dx { } {
  global kcnt kfwhm
  if [okreplace "" \
         "OK to calc gradient on editable structural underlay?\
     \n\n(result saved to intern buffer for other img calc)" "Calc grad x"] {
    smooth_3d_dx $kcnt $kfwhm
    logcmd "smooth_3d_dx $kcnt $kfwhm"
  }
}
proc smoothbutt_struct_dy { } {
  global kcnt kfwhm
  if [okreplace "" \
         "OK to calc gradient on editable structural underlay?\
     \n\n(result saved to intern buffer for other img calc)" "Calc grad y"] {
    smooth_3d_dy $kcnt $kfwhm
    logcmd "smooth_3d_dy $kcnt $kfwhm"
  }
}
proc smoothbutt_struct_dz { } {
  global kcnt kfwhm
  if [okreplace "" \
         "OK to calc gradient on editable structural underlay?\
     \n\n(result saved to intern buffer for other img calc)" "Calc grad z"] {
    smooth_3d_dz $kcnt $kfwhm
    logcmd "smooth_3d_dz $kcnt $kfwhm"
  }
}
# R-click bind: helpwin + buttonbar popup
bind $f.aSMOOTHGAUSS.bu <ButtonRelease-3> {
  helpwin smoothstats
  buttonbar \
    "\"3D Gauss Smooth Struct Underlay (left-clk-SMOOTHSTRUCT)\" \
     \"3D Gauss smooth Funct Overlay (left-clk-SMOOTH STATS)\" \
     \"Calc Gradient Struct Underlay: x direction (no hotkey)\" \
     \"Calc Gradient Struct Underlay: y direction  (no hotkey)\" \
     \"Calc Gradient Struct Underlay: z direction  (no hotkey)\"" \
    "smoothbutt_struct smoothbutt_funct \
     smoothbutt_struct_dx smoothbutt_struct_dy smoothbutt_struct_dz" \
    ver "SMOOTHSTRUCT / SMOOTH STATS Button" smoothstats
}

### colscales
############################################################################
## row1
frame $f.co
pack $f.co -side top
radios $f.co "" "w1" colscale 0 0 row; $f.co.aw1.ra config -padx 0
radios $f.co "" "h" colscale 1 0 row; $f.co.ah.ra config -padx 0
radios $f.co "" "b" colscale 4 0 row; $f.co.ab.ra config -padx 0
bind $f.co.aw1.ra <ButtonRelease-1> {
  logcmd "set colscale $colscale"
  redraw
  logcmd "redraw"
}
bind $f.co.ah.ra <ButtonRelease-1> {
  logcmd "set colscale $colscale"
  redraw
  logcmd "redraw"
}
bind $f.co.ab.ra <ButtonRelease-1> {
  logcmd "set colscale $colscale"
  redraw
  logcmd "redraw"
}
bind $f.co.aw1.ra <ButtonRelease-3> { helpwin val_w1 }
bind $f.co.ah.ra <ButtonRelease-3> { helpwin val_ht }
bind $f.co.ab.ra <ButtonRelease-3> { helpwin val_bi }
## row2
frame $f.co2
pack $f.co2 -side top
radios $f.co2 "" "BR" colscale 6 0 row; $f.co2.aBR.ra config -padx 0
radios $f.co2 "" "BRy" colscale 11 0 row; $f.co2.aBRy.ra config -padx 0
radios $f.co2 "" "lt" colscale 12 0 row; $f.co2.alt.ra config -padx 0
bind $f.co2.aBR.ra <ButtonRelease-1> {
  logcmd "set colscale $colscale"
  redraw
  logcmd "redraw"
}
bind $f.co2.aBRy.ra <ButtonRelease-1> {
  logcmd "set colscale $colscale"
  redraw
  logcmd "redraw"
}
bind $f.co2.alt.ra <ButtonRelease-1> {
  logcmd "set colscale $colscale"
  redraw
  logcmd "redraw"
}
bind $f.co2.aBR.ra <ButtonRelease-3> { helpwin val_BRw }
bind  $f.co2.aBRy.ra <ButtonRelease-3> { helpwin val_BRy }
bind $f.co2.alt.ra <ButtonRelease-3> { helpwin val_lt }

### color LUT
############################################################################
frame $f.lt
pack $f.lt -side top -fill x -padx 0
## combo (HOWTO crush combolabel:label -bd,-padx0 entry -highlightthickness 0)
setfile val2rgblut $val2rgblut  ;# create abbrev
tixComboBox $f.lt.cbx -dropdown true -editable true \
  -variable val2rgblutabbrev -listcmd "listcmd_lut $f.lt.cbx" -listwidth 215 \
  -options "label.width 0 entry.width 5 listbox.height 10" ;# listbox.width 26
$f.lt.cbx subwidget label config -bd 0 -padx 0
$f.lt.cbx subwidget entry config -selectforeground black -highlightthickness 0
$f.lt.cbx subwidget listbox config -font $ffont \
  -selectbackground $selbgcol -selectforeground black
$f.lt.cbx config -value $val2rgblutabbrev
pack $f.lt.cbx -side left -padx 0
$f.lt.cbx subwidget entry xview end
bind [$f.lt.cbx subwidget entry] <ButtonRelease-3> { helpwin val2rgb }
## buttons
button $f.lt.be -text "E" -font $ffontb -pady 0 -padx 0 -command {
  setfile val2rgblut [.mri.main.farright.lt.cbx subwidget entry get]
  defmissinglutfile  ;# logs
  editfile $val2rgblut
  logcmd "editfile $val2rgblut"
}
pack $f.lt.be -side left -padx 0
button $f.lt.br -text "R" -font $ffontb -pady 0 -padx 0 -command {
  setfile val2rgblut [.mri.main.farright.lt.cbx subwidget entry get]
  read_val2rgblut
  logcmd "read_val2rgblut"
  .mri.main.farright.lt.cbx subwidget entry xview moveto 1
  if {$complexvalflag} {
    set colscale 14
    logcmd "set colscale 14"
  } else {
    set colscale 12
    logcmd "set colscale 12"
  }
  redraw
  logcmd "redraw"
} ;# N.B.: live R click selects PHA[SE], not AMP
pack $f.lt.br -side left -padx 0
button $f.lt.bw -text "W" -font $ffontb -pady 0 -padx 0 -command {
  setfile val2rgblut [.mri.main.farright.lt.cbx subwiget entry get]
  testreplace $val2rgblut write_val2rgblut
}
pack $f.lt.bw -side left -padx 0
bind $f.lt.be <ButtonRelease-3> { helpwin val2rgb_edit }
bind $f.lt.br <ButtonRelease-3> { helpwin val2rgb_read }
bind $f.lt.bw <ButtonRelease-3> { helpwin val2rgb_write }

### CLR upsamp button + interpolatelut
############################################################################
frame $f.fl
pack $f.fl -side top
## CLR upsamp button
button $f.fl.bc -text CLR -font $ffontb -pady 0 -padx 0 -command {
  clear_upsamp_stat
  logcmd "clear_upsamp_stat"
  redraw
  logcmd "redraw"
}
pack $f.fl.bc -side left -padx 0
bind $f.fl.bc <ButtonRelease-3> { helpwin clear }
## interpolatelute check
checkbutton $f.fl.ck -variable interpolatelutflag -font $ffont \
  -text "interpolLUT" -bd 0 -padx 0
pack $f.fl.ck -side left -padx 0
bind $f.fl.ck <ButtonRelease-1> {
  logcmd "set interpolatelutflag $interpolatelutflag"
  redraw
  logcmd "redraw"
}
bind $f.fl.ck <ButtonRelease-3> { helpwin intplut }

### truncphase and limits
############################################################################
frame $f.tr
pack $f.tr -side top -padx 0
checkbutton $f.tr.ck -variable truncphaseflag -font $ffont -text "trunc" \
  -bd 0 -padx 0
bind $f.tr.ck <ButtonRelease-1> {
  logcmd "set truncphaseflag $truncphaseflag"
  redraw
  logcmd "redraw"
}
bind $f.tr.ck <ButtonRelease-3> { helpwin truncphase }
pack $f.tr.ck -side left -padx 2
# lo,hi
frame $f.tr.lo
frame $f.tr.hi
entry $f.tr.lo.e -textvariable truncphasemin -font $ffont -width 3
entry $f.tr.hi.e -textvariable truncphasemax -font $ffont -width 3
pack $f.tr.lo $f.tr.hi $f.tr.lo.e $f.tr.hi.e -side left
bind $f.tr.lo.e <Return> {
  logcmd "set truncphasemin $truncphasemin"
  set truncphaseflag 1
  logcmd "set truncphaseflag 1"
  redraw
  logcmd "redraw"
}
bind $f.tr.hi.e <Return> {
  logcmd "set truncphasemax $truncphasemax"
  set truncphaseflag 1
  logcmd "set truncphaseflag 1"
  redraw
  logcmd "redraw"
}
bind $f.tr.lo.e <ButtonRelease-3> { helpwin truncphasemin }
bind $f.tr.hi.e <ButtonRelease-3> { helpwin truncphasemax }

### color wheel controls
############################################################################
# angle cycles
edlabval $f "anglecycles" 0 n 11 3 col
$f.anglecycles.e config -textvariable angle_cycles
bind $f.anglecycles.e <Return> {
  logcmd "set angle_cycles $angle_cycles"
  redraw
  logcmd "redraw"
}
bind $f.anglecycles.e <ButtonRelease-3> { helpwin angle_cycles }
# rev + angle offset
frame $f.revoff -bg $bgcol
pack $f.revoff -side top
checkbutton $f.revoff.ck -variable revphaseflag -font $ffont -text "rev" \
  -bd 0 -padx 0
bind $f.revoff.ck <ButtonRelease-1> {
  logcmd "set revphaseflag $revphaseflag"
  redraw
  logcmd "redraw"
}
bind $f.revoff.ck <ButtonRelease-3> { helpwin revphase }
pack $f.revoff.ck -side left -padx 1
edlabval $f.revoff "angoff" 0 n 5 3 col
$f.revoff.angoff.e config -textvariable angle_offset
bind $f.revoff.angoff.e <Return> {
  logcmd "set angle_offset $angle_offset"
  redraw
  logcmd "redraw"
}
bind $f.revoff.angoff.e <ButtonRelease-3> { helpwin angle_offset }

### rarely used fadef,ipsiyellow tighter
############################################################################
frame $f.ip -bg $bgcol
pack $f.ip -side top
edlabval $f.ip "fad" 0 n 3 3 row
$f.ip.fad.e config -textvariable fadef
bind $f.ip.fad.e <Return> {
  logcmd "set fadef $fadef"
  redraw
  logcmd "redraw"
}
bind $f.ip.fad.e <ButtonRelease-3> { helpwin fadef }
edlabval $f.ip "iy" 0 n 2 3 row
$f.ip.iy.e config -textvariable ipsiyellowfact
bind $f.ip.iy.e <Return> {
  logcmd "set ipsiyellowfact $ipsiyellowfact"
  redraw
  logcmd "redraw"
}
bind $f.ip.iy.e <ButtonRelease-3> { helpwin ipsiyellowfact }

### tcl script
############################################################################
frame $f.sc
pack $f.sc -side top -padx 0 -pady 0
edlabval $f.sc "tcl" $script n 0 7 row
pack $f.sc.tcl -padx 0   ;# my internal
#entry $f.sc.e -textvariable scriptabbrev -font $ffont -width 4
$f.sc.tcl.la config -text "" -padx 0 -bd 0
$f.sc.tcl.e config -textvariable scriptabbrev
setfile script $script       ;# reset scriptabbrev (to show cmdline or default)
buttons $f.sc GO {
  setfile script [.mri.main.farright.sc.tcl.e get]; \
  catch { source $script } err;
  logcmd "source $script"
  if { "$err" != "" } { confirmalert "$script: $err" }
  prompt
} row 0 1
buttons $f.sc ED {
  setfile script [.mri.main.farright.sc.tcl.e get]
  editfile $script
  logcmd "editfile $script"
} row 0 1
bind $f.sc.tcl.e <Return> "$f.sc.aGO.bu invoke"
bind $f.sc.tcl.e <ButtonRelease-3> { helpwin script }
bind $f.sc.aGO.bu <ButtonRelease-3> { helpwin script_run }
bind $f.sc.aED.bu <ButtonRelease-3> { helpwin script_edit }

#xxxxx -- help not done below here

### title
set f .meg.ti
label $f.la -text "DIPOLE SAMPLE, MEG/EEG REGISTRATION, SURFPAINT" \
  -font $ffontb -pady 0
pack $f.la -side top

### spacing and dipoles (F4 interface only)
############################################################################
set f .meg.dips.spac
label $f.la -text "3D DIPOLES" -font $ffontb -pady 2
pack $f.la -side top
edlabval $f "spacing" 0 n 8 2
$f.spacing.e config -textvariable dip_spacing
bind $f.spacing.e <Return> {
  logcmd "set dip_spacing $dip_spacing"
  fixdipdecname dip_spacing 0 w  ;# logs
}
# dipoles
set f .meg.dips.en
edlabval $f  "dip"  default   w 4 19
edlabval $f  "dec"  default   w 4 19
setfile dip $dip    ;# make abbrevs
setfile dec $dec
$f.dip.e config -textvariable dipabbrev
$f.dec.e config -textvariable decabbrev
# entries (don't abbrev $f inside { }: need curr $dipname but orig $f)
$f.dip.bw config -command {
  setfile dip [.meg.dips.en.dip.e get]
  testreplace $dip write_dipoles
}
$f.dec.bw config -command {
  setfile dec [.meg.dips.en.dec.e get]
  testreplace $dec write_decimation
}

### headpts read/write files (F4 interface only)
############################################################################
set f .meg.xform.files
edlabval $f "hpts"    default   r  7 22
edlabval $f "htrans"  default   rw 7 22
setfile hpts $hpts      ;# make abbrevs
setfile htrans $htrans
$f.hpts.e config -textvariable hptsabbrev
$f.htrans.e config -textvariable htransabbrev
# entries (can't abbrev $f inside { }: we need curr $dipname but orig $f)
$f.hpts.br config -command {
  setfile hpts [.meg.xform.files.hpts.e get]
  read_hpts
  logcmd "read_hpts"
  redraw
  logcmd "redraw"
}
$f.htrans.br config -command {
  setfile htrans [.meg.xform.files.htrans.e get]
  read_htrans
  logcmd "read_htrans"
  redraw
  logcmd "redraw"
}
$f.htrans.bw config -command {
  setfile htrans [.meg.xform.files.htrans.e get]
  testreplace $htrans write_htrans
}
### rotate headpts
# title and horiz scale
set f .meg.xform.pan.le.rg.rot.top
label $f.title -text "ROTATE HDPTS (deg)" -font $ffontb -pady 0
pack $f.title -side top
scale $f.z -from 10 -to -10 -length $sclenx -variable zrot \
  -orient horizontal -tickinterval 10 -showvalue false -font $sfont \
  -width 11 -resolution 0.2
pack $f.z -side top
bind $f.z <ButtonRelease-1> {
  rotheadpts $zrot
  logcmd "rotheadpts $zrot"
  resettransform
  logcmd "resettransform"
  redraw
  logcmd "redraw"
}
# entry
set f .meg.xform.pan.le.rg.rot.bot
edlabval $f "zrot" 0 n 5 4
$f.zrot.e config -textvariable zrot -font $sfont -highlightthickness 1
$f.zrot.la config -font $sfont
bind $f.zrot.e <Return> {
  rotheadpts $zrot
  logcmd "rotheadpts $zrot"
  resettransform
  logcmd "resettransform"
  redraw
  logcmd "redraw"
}

### SURFPAINT panel (F4 interface only)
############################################################################
## label
set f .meg.xform.pan.le.surf.top.le
label $f.title -text "SURFPAINT" -font $ffontb -pady 0
pack $f.title -side left
## pick one annotation
label $f.la2 -text "an:" -font $ffont -pady 0
pack $f.la2 -side left -padx 0
entry $f.e -textvariable oneidnum -font $ffont -width 3
pack $f.e -side left -padx 0
bind $f.e <Return> {
  logcmd "set oneidnum $oneidnum"
  goto_idnum $oneidnum
  logcmd "goto_idnum $oneidnum"
  redraw
  logcmd "redraw"
}
bind $f.e <ButtonRelease-3> { helpwin surfpaint }
## linewidth
set f .meg.xform.pan.le.surf.top.ri  ;# extra frame for edlabval
edlabval $f "line" 0 n 4 2
$f.line.e config -textvariable surflinewidth -highlightthickness 0
bind $f.line.e <Return> {
  logcmd "set surflinewidth $surflinewidth"
  redraw
  logcmd "redraw"
}
bind $f.line.e <ButtonRelease-3> { helpwin linewidth }
## curv
set f .meg.xform.pan.le.surf.bot
edlabval $f "curv" 0 r 4 17
$f.curv.br config -text "R" -padx 1  ;# squish
setfile curv $curv  ;# makes abbrevs
$f.curv.e config -textvariable curvabbrev
$f.curv.br config -command {
  if {!$surfloaded} {
    confirmalert "first load surface with \"surf:\" dropdown"
  } else {
    setfile curv [.meg.xform.pan.le.surf.bot.curv.e get]
    read_binary_curv
    logcmd "read_binary_curv"
    logcmd "set curvflag $curvflag"  ;# 3 done by read_binary_curv
    logcmd "set fieldsignflag 0"
    logcmd "set annotflag 0"
    redraw
    logcmd "redraw"
  }
}
bind $f.curv.e <ButtonRelease-3> { helpwin surfpaint }
bind $f.curv.br <ButtonRelease-3> { helpwin surfpaint }
## fs
edlabval $f "fs" 0 r 2 19
$f.fs.br config -text "R" -padx 1 
setfile fs $fs
$f.fs.e config -textvariable fsabbrev
$f.fs.br config -command {
  if {!$surfloaded} {
    confirmalert "first load surface with \"surf:\" dropdown"
  } else {
    setfile fs [.meg.xform.pan.le.surf.bot.fs.e get]
    read_fieldsign
    logcmd "read_fieldsign"
    logcmd "set fieldsignflag $fieldsignflag"  ;# 3 done by read_fieldsign
    logcmd "set curvflag 0"
    logcmd "set annotflag 0"
    setfile fm [string range [.meg.xform.pan.le.surf.bot.fs.e get] 0 \
      [expr [string length [.meg.xform.pan.le.surf.bot.fs.e get]] - 4]].fm
    read_fsmask
    logcmd "read_fsmask"
    redraw
    logcmd "redraw"
  }
}
bind $f.fs.e <ButtonRelease-3> { helpwin surfpaint }
bind $f.fs.br <ButtonRelease-3> { helpwin surfpaint }
### annot combo
frame $f.annot
pack $f.annot -side top
## combo
setfile anlabel $anlabel  ;# make abbrev from C def
tixComboBox $f.annot.cbx -label "annot:" -dropdown true -editable true \
 -variable anlabelabbrev -listcmd "listcmd_annots $f.annot.cbx" -listwidth 243 \
 -options "label.width 4 entry.width 14 listbox.height 7" ;# listbox.width 30
$f.annot.cbx subwidget label config -font $ffont
$f.annot.cbx subwidget entry config -selectforeground black
$f.annot.cbx subwidget listbox config -font $ffont \
  -selectbackground $selbgcol -selectforeground black
$f.annot.cbx config -value $anlabelabbrev
pack $f.annot.cbx -side left -padx 0
$f.annot.cbx subwidget entry xview moveto 1
## buttons
button $f.annot.br -text "R" -font $ffontb -pady 0 -padx 1 -command {
  if {!$surfloaded} {
    confirmalert "first load surface with \"surf:\" dropdown"
  } else {
    setfile anlabel [.meg.xform.pan.le.surf.bot.annot.cbx subwidget entry get]
    read_mgh_annot
    logcmd "read_mgh_annot"
    logcmd "set annotflag $annotflag"  ;# 3 done by read_mgh_annot
    logcmd "set curvflag 0"
    logcmd "set fieldsignflag 0"
    redraw
    logcmd "redraw"
  }
}
pack $f.annot.br -side left
bind [$f.annot.cbx subwidget entry] <ButtonRelease-3> { helpwin surfpaint }
bind $f.annot.br <ButtonRelease-3> { helpwin surfpaint }

### {im,im2} 2D ellipse color controls, rarely used color flags (F4 only)
############################################################################
set f .meg.xform.pan.le.ex.le
#buttons $f "SMOOTH 3D NN" { smooth_3d_nn 1; redraw } col 0 1
#bind "$f.aSMOOTH 3D NN.bu" <ButtonRelease-3> { helpwin smooth }
edlabval $f "im:cent,rad" 0 n 10 3 col
$f.im:cent,rad.e config -textvariable imcolcent
entry $f.im:cent,rad.e2 -textvariable imcolrad -font $ffont -width 2
pack $f.im:cent,rad.e2 -side left -padx 0
edlabval $f "im2:cent,rad" 0 n 10 3 col
$f.im2:cent,rad.e config -textvariable im2colcent
entry $f.im2:cent,rad.e2 -textvariable im2colrad -font $ffont -width 2
pack $f.im2:cent,rad.e2 -side left -padx 0
bind $f.im:cent,rad.e <Return> {
  logcmd "set imcolcent $imcolcent"
  redraw
  logcmd "redraw"
}
bind $f.im:cent,rad.e2 <Return> {
  logcmd "set imcolrad $imcolrad"
  redraw
  logcmd "redraw"
}
bind $f.im2:cent,rad.e <Return> {
  logcmd "set im2colcent $im2colcent"
  redraw
  logcmd "redraw"
}
bind $f.im2:cent,rad.e2 <Return> {
  logcmd "set im2colrad $im2colrad"
  redraw
  logcmd "redraw"
}
bind $f.im:cent,rad.e <ButtonRelease-3> { helpwin imim2op }
bind $f.im:cent,rad.e2 <ButtonRelease-3> { helpwin imim2op }
bind $f.im2:cent,rad.e <ButtonRelease-3> { helpwin imim2op }
bind $f.im2:cent,rad.e2 <ButtonRelease-3> { helpwin imim2op }
set f .meg.xform.pan.le.ex.ri
checks $f "" "2Dcol" imim2elloverlayflag col
checks $f "" "linear" linearflag col
$f.a2Dcol.ck config -bd 0 -padx 0 -pady 2
$f.alinear.ck config -bd 0 -padx 0 -pady 2
bind $f.a2Dcol.ck <ButtonRelease-1> {
  logcmd "set imim2elloverlayflag $imim2elloverlayflag"
  checkim2redraw  ;# logs
}
bind $f.alinear.ck <ButtonRelease-1> {
  logcmd "set linearflag $linearflag"
  redraw
  logcmd "redraw"
}
bind $f.alinear.ck <ButtonRelease-3> { helpwin linear }
foreach var {imcolcent im2colcent imcolrad im2colrad} {
  set $var [expr int([set $var])]
}

### translate headpts (F4 interface only)
############################################################################
# title and horiz scale
set f .meg.xform.pan.tran.top
label $f.la -text "TRANSLATE HDPTS (mm)" -font $ffontb -pady 0
pack $f.la -side top
scale $f.x -from -25 -to 25 -length $sclenx -variable xtrans \
   -orient horizontal -tickinterval 25 -showvalue false -font $sfont \
   -width 11 -resolution 0.5
pack $f.x -side top
bind $f.x <ButtonRelease-1> {
  transheadpts $xtrans x
  logcmd "transheadpts $xtrans x"
  resettransform
  logcmd "resettransform"
  redraw
  logcmd "redraw"
}
# vertical scale
set f .meg.xform.pan.tran.bot
scale $f.y -from 25 -to -25 -length $scleny -variable ytrans \
   -orient vertical -tickinterval 25 -showvalue false -font $sfont \
   -width 11 -resolution 0.5
pack $f.y -side left
bind $f.y <ButtonRelease-1> {
  transheadpts $ytrans y
  logcmd "transheadpts $ytrans y"
  resettransform
  logcmd "resettransform"
  redraw
  logcmd "redraw"
}
# entries
set f .meg.xform.pan.tran.bot.la.ent
edlabval $f "x" 0 n 2 6
edlabval $f "y" 0 n 2 6
$f.x.e config -textvariable xtrans -font $sfont
$f.y.e config -textvariable ytrans -font $sfont
$f.x.la config -font $sfont
$f.y.la config -font $sfont
bind $f.x.e <Return> {
  transheadpts $xtrans x
  logcmd "transheadpts $xtrans x"
  resettransform
  logcmd "resettransform"
  redraw
  logcmd "redraw"
}
bind $f.y.e <Return> {
  transheadpts $ytrans y
  logcmd "transheadpts $ytrans y"
  resettransform
  logcmd "resettransform"
  redraw
  logcmd "redraw"
}
label $f.la -text " " -font $sfont  ;# space
pack $f.la -side top
# tack in unrelated overlay alpha
frame $f.sp -bg $bgcol -height 5
pack $f.sp -side top
edlabval $f "tran" 0 n 4 4
$f.tran.e config -textvariable overlayalpha
bind $f.tran.e <Return> {
  if {$overlayalpha < 0}   { set overlayalpha 0 }
  if {$overlayalpha > 255} { set overlayalpha 255 }
  logcmd "set overlayalpha $overlayalpha"
  redraw
  logcmd "redraw"
}
# tack in unrelated force randLUT 256
checkbutton $f.ck -variable randlut256flag -font $ffont -text "randlut256" \
  -bd 0 -padx 0
bind $f.ck <ButtonRelease-1> {
  fscolormap2lut  ;# logs
  logcmd "set randlut256flag $randlut256flag"
  redraw
  logcmd "redraw"
}
pack $f.ck -side top
# tack in unrelated block doubl click
checkbutton $f.ck2 -variable blockdoubleclickflag -font $ffont \
  -text "no double-clk" -bd 0 -padx 0
pack $f.ck2 -side top

############################################################################
# all traces
############################################################################
# explicit plane focus
#trace variable plane w fixfocus  ;# saved example old syntax
trace add variable plane write fixfocus
# fix slice num on var update
trace add variable newimc write zoomcoords
trace add variable newic write zoomcoords
trace add variable newjc write zoomcoords
# fix tal on nice update
trace add variable newimc write talupdate
trace add variable newic write talupdate
trace add variable newjc write talupdate
# current pixval
trace add variable selectedpixval write pixvaltitle
# dipoles
trace add variable dip_spacing write fixdipdecname

### initial update slice num's, Talairach
unzoomcoords
set plane $cor
set zf $zf

############################################################################
# shortcut key bindings
############################################################################
# Mac noeffect/reserved:  a,c,h,m,n,q,v,w,x,z
# Mac useable:  b,d,e,f,g,i,j,k,l,o,p,r,s,t,u,y,-,+,*,/,=

## plain keys (N.B.: plain letter keys will get typed into entries)
# interface size
bind . <F1> { mini }  ;# requires fn-F? on Mac
bind . <F2> { mini2 }
bind . <F3> { mini3 }
bind . <F4> { macro }
bind . <F5> { micro }
bind . <F12> { runscript mri2mpg.tcl }
# fn-F? broken on MacOS 10.14? -- need backup
#TODO: make small F1/F2/F3/F4/F5 button popup, "i" left of SAGITTAL
#bind . <$xcmd-Shift-1> { mini }  ;# doesn't work
# slices: slice changed by default arrowkey bindings for scale (Alt or no-Alt)
bind . <Right> {
  logcmd "set plane $plane"
  if {$plane==$cor} { logcmd "set newimc $newimc" }
  if {$plane==$hor} { logcmd "set newic $newic"   }
  if {$plane==$sag} { logcmd "set newjc $newjc"   }
  redraw
  logcmd "redraw"
}
bind . <Left> {
  logcmd "set plane $plane"
  if {$plane==$cor} { logcmd "set newimc $newimc" }
  if {$plane==$hor} { logcmd "set newic $newic"   }
  if {$plane==$sag} { logcmd "set newjc $newjc"   }
  redraw
  logcmd "redraw"
}
bind . <Up> {
  set plane $plane
  if {$plane==$cor} { logcmd "set newimc $newimc" }
  if {$plane==$hor} { logcmd "set newic $newic"   }
  if {$plane==$sag} { logcmd "set newjc $newjc"   }
  redraw
  logcmd "redraw"
}
bind . <Down> {
  logcmd "set plane $plane"
  if {$plane==$cor} { logcmd "set newimc $newimc" }
  if {$plane==$hor} { logcmd "set newic $newic"   }
  if {$plane==$sag} { logcmd "set newjc $newjc"   }
  redraw
  logcmd "redraw"
}
# skip key1-4 change tcl interface size because of accidental type into entry

## key combos: alt/cmd + key
# toggle expand cursor (require Alt/Cmd in interface window)
bind . <$xcmd-k> { set bigcursorflag [expr !$bigcursorflag]; redraw }
bind . <$xcmd-K> { set nocursorflag [expr !$nocursorflag]; redraw }
bind . <$xcmd-O> { set opencursorflag [expr !$opencursorflag]; redraw }
# fmid
bind . <$xcmd-i> { set fmid [format "%%2.2f" [expr $fmid - 0.1]]; redraw }
bind . <$xcmd-I> { set fmid [format "%%2.2f" [expr $fmid + 0.1]]; redraw }
# brush size
bind . <$xcmd-b> { set prad 0 }
bind . <$xcmd-B> { set prad [expr ($prad+1)%%11 ] }
bind . <$xcmd-l> { set pradtmp $prad; set prad $pradlast;set pradlast $pradtmp}
# underlay contrast and midpoint
bind . <$xcmd-asterisk> {set bwslope [expr $bwslope * 1.1]; set_scale;redraw}
bind . <$xcmd-slash> { set bwslope [expr $bwslope / 1.1]; set_scale; redraw }
bind . <$xcmd-plus>  { set bwmid [expr $bwmid - 0.015]; set_scale; redraw }
bind . <$xcmd-equal>  { set bwmid [expr $bwmid - 0.015]; set_scale; redraw }
bind . <$xcmd-minus> { set bwmid [expr $bwmid + 0.015]; set_scale; redraw }
bind . <$xcmd-r> { set bwmid 0.35; set bwslope 12.0; redraw }
# COMPARE button (proc not invoke b/c invoke doesn't activate binding)
#bind . <$xcmd-0>           { .mri.main.right.cmp.im2.aCOMPARE.bu invoke }
#bind . <$xcmd-apostrophe>  { .mri.main.right.cmp.im2.aCOMPARE.bu invoke }
bind . <$xcmd-0>           { compare_im_im2 }
bind . <$xcmd-apostrophe>  { compare_im_im2 }
bind . <$xcmd-C>           { compare_im_im2 } ;# b/c xcmd-c reserved by X11 app
# SEND/GOTO
bind . <$xcmd-f> { ".mri.main.left.head.pnt.aSEND PNT.bu" invoke }
bind . <$xcmd-g> { ".mri.main.left.head.pnt.aGOTO PNT.bu" invoke }
# toggle surface visibilty
bind . <$xcmd-d> { .mri.main.left.view.butt.left.asurface.ck invoke }
# toggle max intens projection
bind . <$xcmd-p> { set maxflag [expr !$maxflag]; redraw }
# toggle overlay
bind . <$xcmd-o> { .mri.main.left.view.butt.left.aoverlay.ck invoke }
# save images
bind . <$xcmd-e> { .mri.main.left.head.save.aSAVEIMG.bu invoke }
# toggle TRUNC
# TRUNC
bind . <$xcmd-period> { trunc_tmpim1 }
# UNDO
bind . <$xcmd-z> { saveim_for_redo; undo_edit; redraw }
bind . <$xcmd-Z> { saveim_for_undo; redo_edit; redraw }

# headpts: read/write
### disable headpts for now (N.B.: cmd-p overlaps max intens proj)
#bind . <$xcmd-R> { setfile hpts [.meg.xform.files.hpts.e get]; read_hpts; \
#                 setfile htrans [.meg.xform.files.htrans.e get]; \
#                 read_htrans; redraw }
#bind . <$xcmd-E>  { setfile htrans [.meg.xform.files.htrans.e get]; \
#                  testreplace $htrans write_htrans }
## headpts: translate small
#bind . <$xcmd-semicolon> { transheadpts 0.5 x;  set overlay_mode 2; redraw }
#bind . <$xcmd-l>         { transheadpts -0.5 x; set overlay_mode 2; redraw }
#bind . <$xcmd-p>         { transheadpts 0.5 y;  set overlay_mode 2; redraw }
#bind . <$xcmd-period>    { transheadpts -0.5 y; set overlay_mode 2; redraw }
## headpts: translate big
#bind . <$xcmd-colon>     { transheadpts 2.5 x;  set overlay_mode 2; redraw }
#bind . <$xcmd-L>         { transheadpts -2.5 x; set overlay_mode 2; redraw }
#bind . <$xcmd-P>         { transheadpts 2.5 y;  set overlay_mode 2; redraw }
#bind . <$xcmd-greater>   { transheadpts -2.5 y; set overlay_mode 2; redraw }
## headpts: rotate
#bind . <$xcmd-braceleft>    { rotheadpts 5.0;  set overlay_mode 2; redraw }
#bind . <$xcmd-braceright>   { rotheadpts -5.0; set overlay_mode 2; redraw }
#bind . <$xcmd-bracketleft>  { rotheadpts 0.5;  set overlay_mode 2; redraw }
#bind . <$xcmd-bracketright> { rotheadpts -0.5; set overlay_mode 2; redraw }

############################################################################
# choose interface size
############################################################################
puts "tkmedit.tcl: startup done"

# N.B.: w/command line script, these execute before gl window up
fixcolors
shrinkcomboarrows more
.mri.main.right.cmp.im2.cbx subwidget arrow config -width 9  ;# even more
if [info exists env(tkmeditinterface)] {   ;# env opt
  if {$env(tkmeditinterface) == "macro"} { macro }
  if {$env(tkmeditinterface) == "mini3"} { mini3 }
  if {$env(tkmeditinterface) == "mini2"} { mini2 }
  if {$env(tkmeditinterface) == "mini"}  { mini }
  if {$env(tkmeditinterface) == "micro"} { micro }
} elseif [info exists tkmeditinterface] {  ;# cmdline opt (bump-up if overlay)
  eval $tkmeditinterface
  puts "tkmedit.tcl: interface size set to $tkmeditinterface"
} else {  ;# default
  mini
  puts \
 "tkmedit.tcl: default mini interface (to change: macro,mini3,mini2,mini,micro)"
  puts "tkmedit.tcl: or: setenv tkmeditinterface {macro,mini3,mini2,mini,micro}"
}
#update   ;# on 10.15, causes empty white window to appear
puts "tkmedit.tcl: version: $tkmedittcl_version"
logcmd "# tkmedit.tcl startup done (cmdline script, interface cmds next)"
wm deiconify .    ;# undo wm withdraw at top

############################################################################
# various hacks
############################################################################
### override IRIX save_rgb (tkmedit2000 broken on Octane) (new compile fixes!)
#if { [exec uname] == "IRIX64" } {
#  puts "tkmedit.tcl: ### tmp hack (use scrsave) to make Octane save_rgb work"
#  proc save_rgb { } {
#    global rgb
#    eval exec scrsave $rgb 122 634 294 806
#  }
#}

### horrible tmp hack gives 20x drawing speedup (Yosemite+ 5sec->250ms, AppNap?)
if {$mac_appnap_hack} {
  tkwait visibility .    ;# returns when just window, before widgets drawn
  set geom +[winfo rootx .]+[winfo rooty .]
  set hackxtermx 73
  if {$tkmeditinterface == "mini2"} { set hackxtermx 93 }
  set pid [exec xterm -geom ${hackxtermx}x17${geom} -bg $bgcol -e bash --norc &]
  after 2000 { exec kill $pid }
}

