#! /usr/bin/tclsh
###############################################################################
# assemble-render-maps.tcl: mk border paint, disp vtxcol labels/borders, render
###############################################################################
### PURPOSE:
# Loads previously prepared vtxcol labels for mapping data from
#   experiments from three different modalities, each with differently-set
#   color scale, and then surrounds each group of areas with differently
#   colored two-vertex-wide border (creation and conversion border label to
#   vtxcol label done here)
# Popup to choose render final illustration bitmaps or movie frames
# If illus, popup to choose on- or off-screen (higher res) render
# If movie, popup to choose render indiv area or inflated rotation frames

### USE:
# (1) make annotation file of all regions
# (2) make vtxcol labels of mapping data with final color map settings by
#      load/mask mapping data for each modality, convert to vtxcol label
# (3) put this script in fsaverage (or other subject) scripts dir
# (4) start csurf, pick subject fsaverage, SURFACE
# (5) pick this script from "tcl:" dropdown, click GO
#  --works for either hemi
#  --popup to choose main images or movie frames
#  --popup to choose max onscreen (1098x1098) or offscreen render (2500x2500)
#
### INPUT: requires 7 files for each hemi
#  ~/label/$hemi-CsurfMaps1.annot          # full annotation file (1)
#  ~/label/$hemi-maps${modality}.cols      # vtxcol datalabels each modality (3)
#  ~/label/$hemi-mask${modality}1e.label   # mask label for each modality (3)
#
### OUTPUT: 10 bitmaps for each hemi
#   /tmp/allmaps-$hemi-inflated-{lat,med,ven,dor}.tiff
#   /tmp/allmaps-$hemi-flat.tiff
#   /tmp/alllabs-$hemi-inflated-{lat,med,ven,dor}.tiff
#   /tmp/alllabs-$hemi-flat.tiff
# optional movie frames (onscreen only):
#   /tmp/<region_num>-<region_name>-$hemi-flat.tiff
#   ...
### HOWTO make input vtxcol paint labels foreach vis,aud,som maps
#  (1) finalize area boundary edits
#  (2) mk indiv modality CsurfMaps1{}'s (6) by blk comment-out CsurfColorLut.txt
#  (3) mk all-modality CsurfMaps1's (2), both by (ctrl-mid-clk-W on label line)
#  (4) mk mask1e's (load 1-mod. annot, erodingfill, cuthole w/label, CLR val, W)
#    => $hemi-mask${modality}1e.label
#  (5) mk cols (load vis/aud/som data, sm=1, sfmid, cuthole w/mask, conv2cols)
#    mid-clk-"C" to cut hole with mask1e => $hemi-maps${modality}.label
#    mid-clk-"W" to conv to vtxcol label => $hemi-maps${modality}.cols
#

###############################################################################
# adjustable parameters
###############################################################################
set modalities "vis aud som"  ;# label file infixes
set offscreenrendersize 2500  ;# any size OK
set onscreenrendersize 1098   ;# this is max on 16 inch
set sombordcol "130 255 130"  ;# RGB color of somatosensory border
set audbordcol "255 130 130"  ;# RGB color of auditory border 
set visbordcol "100 130 255"  ;# RGB color of visual border
set maxregion 117             ;# number of non-background areas
set rotsteps 360              ;# num frames for 360deg rot (dorven:divisible/4)
set diagrotflag  0            ;# diagonal yx axis rotation (incompat w/next)
set dorvenrotflag 1           ;# add dorsal/ventral 90 back and forth

### HOWTO test 1 modality
#set modalities "vis"
#set modalities "aud"
#set modalities "som"

###############################################################################
# choose on/offscreen, mainimages/movie (can't do movie offscreen)
###############################################################################

# diagrot and dorvenrot incompatible
if {$diagrotflag && $dorvenrotflag} {
  confirmalert "\$diagrotflag and \$dorvenrotflag incompatible:\n\nTurn one OFF"
  return
}

# choose main images vs. movie frames
set resp [okreplace "" "Assemble maps from vis/aud/somato modalities,\
                      \nmake modality borders, and render final bitmaps:\
                    \n\n    main images (4 inflated views + flat)\
                      \n        *or*\
                      \n    movie frames (indiv areas, rotate movie)?\
                    \n\n(N.B.: movie frames: ON-screen only)" \
           "Main Images" "Movie Frames" "Cancel" "RENDER"]
if {$resp == 0} { return }  ;# cancel
if {$resp == 1} { set mainimagesflag 1; set framesflag 0 }  ;# action1
if {$resp == 2} { set mainimagesflag 0; set framesflag 1 }  ;# action2

# choose individ area flat movie vs. rot movie
set individualflag 0
set rotinflatedflag 0
if {$framesflag} {
  set resp [okreplace "" "Make movie frames:\
                      \n\n    individual areas on flat\
                        \n        *or*\
                        \n    y-axis rotate inflated_avg?\
                      \n\n(N.B.: movie frames: ON-screen only)" \
             "Individual Areas" "Rotate Inflated" "Cancel" "RENDER"]
  if {$resp == 0} { return }  ;# cancel
  if {$resp == 1} { set individualflag 1; set rotinflatedflag 0 }  ;# action1
  if {$resp == 2} { set individualflag 0; set rotinflatedflag 1 }  ;# action2
}

# choose on-screen vs. off-screen (if not rot)
set offscreen 0
if {$mainimagesflag} {
  set resp [okreplace "" "Render ON or OFF Screen?\
           \n\n ON screen:  $onscreenrendersize x $onscreenrendersize pix\
             \nOFF screen:  $offscreenrendersize x $offscreenrendersize pix\
           \n\n(adjust ON/OFF resolution in script)" \
              "ON screen" "OFF screen"]
  if {$resp == 0} { return }  ;# cancel
  if {$resp == 1} { set offscreen 0 }  ;# action1
  if {$resp == 2} { set offscreen 1 }  ;# action2
} else {
  confirmalert \
      "ON screen render:  $onscreenrendersize x $onscreenrendersize pix\
   \n\n(adjust resolution in script)"
}
clear_annot

###############################################################################
# make colored vtxcol border around a set of areas
###############################################################################
foreach modality $modalities {

  # init
  clear_ripflags        ;# ALL
  read_binary_surface
  read_binary_curv
  set flag2d 0
  restore
  #restore_ripflags 2   ;# INIT

  clear_values
  clear_vtxcol_labels
  set overlayflag 1
  set complexvalflag 0

  ### make border label
  # start w/mask1e
  setfile label ~/label/$hemi-mask${modality}1e.label   ;# setfile is my glob
  read_label_cut_clearvals 0

  # enlarge holes in mask w/three eroding FILL's, save as mask4e
  set erodingfillflag 1
  for {set i 0} {$i < 3} {incr i} {
    clear_vertex_marks_list
    if {$hemi == "lh"} { leftclick_vertex 58764 }  ;# ang gyrus
    if {$hemi == "rh"} { leftclick_vertex 78402 }
    floodfill_marked_patch 0
  }
  setfile label ~/label/$hemi-mask${modality}4e.label
  write_labeled_vertices

  # reload mask1e
  restore_ripflags 2   ;# INIT
  setfile label ~/label/$hemi-mask${modality}1e.label
  read_label_cut_clearvals 0    ;# 0=re-cut

  # cut hole mask1e w/mask4e, save border label
  setfile label ~/label/$hemi-mask${modality}4e.label
  read_label_cut_clearvals 1    ;# 1=cuthole
  setfile label ~/label/$hemi-mask${modality}bord.label
  write_labeled_vertices

  # load fixed .val into border label, save
  setfile label ~/label/$hemi-mask${modality}bord.label
  read_label_to_setvalval2 2.0 0.0
  setfile label ~/label/$hemi-mask${modality}bordval.label
  write_labeled_vertices

  # make tmp lut to render border color
  set id [open $env(SUBJECTS_DIR)/$subject/scripts/val2rgb.lut w 0666]
  puts $id "0.0  100 100 100"
  if {$modality == "som"} { puts $id "2.0 $sombordcol" }
  if {$modality == "aud"} { puts $id "2.0 $audbordcol" }
  if {$modality == "vis"} { puts $id "2.0 $visbordcol" }
  puts $id "4.0  100 100 100"
  close $id

  # load tmp lut
  set val2rgblut $env(SUBJECTS_DIR)/$subject/scripts/val2rgb.lut
  read_val2rgblut
  set colscale 12

  # unthresh border render (.val=2.0) before convert to vtxcol paint
  set statmaskampflag 0
  set fthresh 0.1
  set fmid 0.0

  # convert border label to vtxcol label
  setfile vclabel ~/label/$hemi-mask${modality}bordval.cols
  label_to_vtxcol_label

  # restore surface
  restore_ripflags 2   ;# INIT
}

###############################################################################
# load/render all paint files
###############################################################################
### setup offscreen
if {$offscreen} {
  close_window
  resize_window $offscreenrendersize
  set renderoffscreen 1
  open_window
  setfile insurf ~/surf/$hemi.inflated_avg
  read_binary_surface
  setfile curv ~/surf/$hemi.curv
  read_binary_curv
  make_lateral_view
  set overlayflag 1
}

### for redo
clear_values
clear_annot
clear_vtxcol_labels

### load annotation (for dot borders)
setfile anlabel ~/label/$hemi-CsurfMaps1.annot
read_mgh_annot

### load each modality vtxcol paint files (data, border)
foreach modality $modalities {
  setfile vclabel ~/label/$hemi-maps${modality}.cols
  read_vtxcol_label
  setfile vclabel ~/label/$hemi-mask${modality}bordval.cols
  read_vtxcol_label
}

### patch tiny 3aud afterward since somato border occludes map (area OK)
set modality aud
setfile vclabel ~/label/$hemi-maps${modality}-patch.cols
puts "assemble-render-maps.tcl: patch som borders occluding 3aud data"
read_vtxcol_label

### set border dots color
set meshr 0    ;# gray: 40, 220, 180, 150, 120, 90
set meshg 210  ;# cyan: 180
set meshb 210

### display
if {!$offscreen} {
  set pointsize 2.0
  resize_window $onscreenrendersize
} else {
  set pointsize 3.0
}
set_annot_alpha 255
set annotborddotflag 1
set labelflag 0   ;# annot dot borders still shown
set overlayflag 1
set vtxcolflag 1
redrawbutton

### save bitmaps
set pref1 allmaps
set pref2 alllabs
set black2transparentflag 1

# lateral
clear_ripflags
restore
redrawbutton
set rgb /tmp/$pref1-$hemi-inflated-lat.tiff
if {$mainimagesflag} { save_rgb }
set labelflag 1
redrawbutton
set rgb /tmp/$pref2-$hemi-inflated-lat.tiff
if {$mainimagesflag} { save_rgb }
set labelflag 0

# proc for rot only
proc save_mapsareas { frame } {
  global labelflag rgb

  set labelflag 0
  redraw
  raise_window
  set rgb /tmp/fmaps[format "%05d" $frame].tiff
  save_rgb
  set labelflag 1
  redraw
  raise_window
  set rgb /tmp/farea[format "%05d" $frame].tiff
  save_rgb
}

#########################################
# optional rot movies (do after lateral)
#########################################
if {$rotinflatedflag} {
  set dr [expr 360.0 / $rotsteps.0]
  if {$diagrotflag} { set dr [expr $dr / sqrt(2.0)] }
  set f 0
  if {!$dorvenrotflag} {  ;# simple 360 deg y-axis rot
    for {set i 0} {$i < $rotsteps} {incr i} {
      if {$hemi == "rh"} { rotate_brain_y -$dr }
      if {$hemi == "lh"} { rotate_brain_y  $dr }
      if {$diagrotflag} { rotate_brain_x -$dr }
      save_mapsareas $f
      incr f
    }
  } else {  ;# insert 90 deg/back x-axis rot at lateral and medial views

    for {set i 0} {$i < $rotsteps} {incr i} {   ;# rotate 360
      if {$hemi == "rh"} { rotate_brain_y -$dr }
      if {$hemi == "lh"} { rotate_brain_y  $dr }
      save_mapsareas $f
      incr f
    }
    # TODO: could make sinusoidal, deriv tanh() is 1/cosh^2(a)
    for {set i 0} {$i < [expr $rotsteps / 4]} {incr i} {  ;# to dor
      rotate_brain_x -$dr
      save_mapsareas $f
      incr f
    }
    for {set i 0} {$i < [expr $rotsteps / 2]} {incr i} {  ;# to ven
      rotate_brain_x $dr
      save_mapsareas $f
      incr f
    }
    for {set i 0} {$i < [expr $rotsteps / 4]} {incr i} {  ;# to lateral
      rotate_brain_x -$dr
      save_mapsareas $f
      incr f
    }


#    for {set i 0} {$i < [expr $rotsteps / 4]} {incr i} {  ;# to dor
#      rotate_brain_x -$dr
#      save_mapsareas $f
#      incr f
#    }
#    for {set i 0} {$i < [expr $rotsteps / 4]} {incr i} {  ;# back
#      rotate_brain_x $dr
#      save_mapsareas $f
#      incr f
#    }
#    for {set i 0} {$i < [expr $rotsteps / 2]} {incr i} {  ;# rot 180
#      if {$hemi == "rh"} { rotate_brain_y -$dr }
#      if {$hemi == "lh"} { rotate_brain_y  $dr }
#      save_mapsareas $f
#      incr f
#    }
#    for {set i 0} {$i < [expr $rotsteps / 4]} {incr i} {  ;# to ven
#      rotate_brain_x $dr
#      save_mapsareas $f
#      incr f
#    }
#    for {set i 0} {$i < [expr $rotsteps / 4]} {incr i} {  ;# back
#      rotate_brain_x -$dr
#      save_mapsareas $f
#      incr f
#    }
#    for {set i 0} {$i < [expr $rotsteps / 2]} {incr i} {  ;# rot 180
#      if {$hemi == "rh"} { rotate_brain_y -$dr }
#      if {$hemi == "lh"} { rotate_brain_y  $dr }
#      save_mapsareas $f
#      incr f
#    }


  }
  set labelflag 0
}

# medial
restore
rotate_brain_y 180
redrawbutton
set rgb /tmp/$pref1-$hemi-inflated-med.tiff
if {$mainimagesflag} { save_rgb }
set labelflag 1
redrawbutton
set rgb /tmp/$pref2-$hemi-inflated-med.tiff
if {$mainimagesflag} { save_rgb }
set labelflag 0

# dor
restore
rotate_brain_x -90
redrawbutton
set rgb /tmp/$pref1-$hemi-inflated-dor.tiff
if {$mainimagesflag} { save_rgb }
set labelflag 1
redrawbutton
set rgb /tmp/$pref2-$hemi-inflated-dor.tiff
if {$mainimagesflag} { save_rgb }
set labelflag 0

# ven
restore
rotate_brain_x 90
redrawbutton
set rgb /tmp/$pref1-$hemi-inflated-ven.tiff
if {$mainimagesflag} { save_rgb }
set labelflag 1
redrawbutton
set rgb /tmp/$pref2-$hemi-inflated-ven.tiff
if {$mainimagesflag} { save_rgb }
set labelflag 0

# flat
setfile patch ~/surf/$hemi.cortex2a.patch.flat
read_binary_patch
restore_zero_position
rotate_brain_x -90
if {$hemi == "rh"} {
  rotate_brain_z 96
  translate_brain_x 5.0
  translate_brain_y 2.0
}
if {$hemi == "lh"} {
  rotate_brain_z 79
  translate_brain_x 0.0   ;# position.tcl was 2.0?
  translate_brain_y 3.0
}
scale_brain 0.95
redrawbutton
set rgb /tmp/$pref1-$hemi-flat.tiff
if {$mainimagesflag} { save_rgb }
set labelflag 1
redrawbutton
set rgb /tmp/$pref2-$hemi-flat.tiff
if {$mainimagesflag} { save_rgb }
set labelflag 0

###############################################################################
# optional individual areas for movie
###############################################################################
if {$individualflag && !$offscreen} {
  # clear, reload to omit modality borders
  clear_vtxcol_labels
  foreach modality $modalities {
    setfile vclabel ~/label/$hemi-maps${modality}.cols
    read_vtxcol_label
  }
  # find area names for tiffs
  set id [open $env(SUBJECTS_DIR)/$subject/scripts/CsurfMaps1.ctab r]
  set lines [split [read -nonewline $id] "\n"]
  close $id
  foreach line $lines {
    if [string match "#*" $line] { continue }
    set regionnames([lindex $line 0]) [lindex $line 1]
  }
  # minimal borders for minimal occlusion
  set pointsize 1.0
  set labelflag 0
  set vtxcolflag 1
  set annotmaskflag 1
  set black2transparentflag 0
  set region 1
  prune_annotbord
  # write black map for sulcal labels
  set_idnums_visibility 0   ;# mask all
  redrawbutton
  set rgb /tmp/000-blank-$hemi-flat.tiff
  save_rgb
  # write indiv area bitmaps
  while {$region <= $maxregion} {
    set_idnums_visibility 0   ;# mask all
    set_idnum_visibility $region 1
    redrawbutton
    set fregion [format "%03d" $region]
    ## incl area name in tiff
    set rgb /tmp/$fregion-$regionnames($region)-$hemi-flat.tiff
    save_rgb
    incr region
  }
  ### N.B.:  have to update these if areas added!
  # put VIP1 back together
  set_idnums_visibility 0
  set_idnum_visibility 49 1
  set_idnum_visibility 50 1
  redrawbutton
  set rgb /tmp/049,050-VIP1-$hemi-flat.tiff
  save_rgb
  # put VIP2 back together
  set_idnums_visibility 0
  set_idnum_visibility 51 1
  set_idnum_visibility 52 1
  redrawbutton
  set rgb /tmp/051,052-VIP2-$hemi-flat.tiff
  save_rgb
  # put PZaud back together
  set_idnums_visibility 0
  set_idnum_visibility 86 1
  set_idnum_visibility 87 1
  redrawbutton
  set rgb /tmp/086,087-PZ-$hemi-flat.tiff
  save_rgb
  # put 3b back together
  set_idnums_visibility 0
  set_idnum_visibility 92 1
  set_idnum_visibility 93 1
  set_idnum_visibility 94 1
  redrawbutton
  set rgb /tmp/092,093,094-3b-$hemi-flat.tiff
  save_rgb
  # put 3a back together
  set_idnums_visibility 0
  set_idnum_visibility 95 1
  set_idnum_visibility 96 1
  set_idnum_visibility 97 1
  redrawbutton
  set rgb /tmp/095,096,097-3a-$hemi-flat.tiff
  save_rgb
  # put 1 back together
  set_idnums_visibility 0
  set_idnum_visibility 98 1
  set_idnum_visibility 99 1
  set_idnum_visibility 100 1
  redrawbutton
  set rgb /tmp/098,099,100-1-$hemi-flat.tiff
  save_rgb
  # put 4 back together
  set_idnums_visibility 0
  set_idnum_visibility 112 1
  set_idnum_visibility 113 1
  set_idnum_visibility 114 1
  redrawbutton
  set rgb /tmp/112,113,114-4-$hemi-flat.tiff
  save_rgb
  # put 7b_PIC back together
  set_idnums_visibility 0
  set_idnum_visibility 29 1
  set_idnum_visibility 30 1
  redrawbutton
  set rgb /tmp/029,030-7b_PIC-$hemi-flat.tiff
  save_rgb
  # cleanup
  set annotmaskflag 0
#  ffmpeg \
#    -v 0 \
#    -f image2 \
#    -r 2 \
#    -i ???-*-$hemi-flat.tiff \
#    -vcodec libx264 \
#    -pix_fmt yuv420p \
#    out.mp4
}

###############################################################################
# restore
###############################################################################
setfile insurf ~/surf/$hemi.inflated_avg
make_lateral_view
set flag2d 0
clear_ripflags
read_binary_surface
set black2transparentflag 0
redrawbutton

### kill big white window (close_window() crashes xcb)
if {$offscreen} { exit }

