##############################################################################
# inflate movies (simple, dual infl/rot/defl front/back loop, rot+infl/defl)
##############################################################################
# read pre-made surf series, set pose, write tiffs (default outdir: /tmp), mpg1
# inflatetypes:
#  simple:   no rotate (except initial view)
#  frontbak: rot360/inflate/rot360/deflate/rot180/inflate/rot360/deflate/rot180
#  rotpump: slow rot, faster infl/defl (loop: infl+defl int fact of rotsteps)
# N.B.: assumes ExpertPrefs "write every x iter" is 1 (def=0: no steps saved)
# N.B.: req's first/last file, skips any missing intermediate
# interactive, or: tksurfer marty rh smoothwm -tcl inflatemovie.tcl
# change to redraws to redraw_cached except first
# remove yrot dependence between successive blocks in frontbak
### N.B.: caller must init $userok to 0

### hard defaults
if ![info exists userok] { set userok 0 }

### adjustable parms (interactive adj w/popup, or edit here for cmdline script)
if {!$userok} {  ;# don't blow away reset by controls
  ### frontback example (for cerebellum: start posterior, slightly topview)
  set inflatetype frontbak ;# simple, frontbak, rotpump
  set surfinfix  inflated  ;# inflated, sphere, sphere.reg
  set inityrot     85      ;# avoid tksurfer.tcl yrot (tk scale clamps -180,180)
  set initxrot    -18      ;# avoid tksurfer.tcl xrot (tk scale clamps -180,180)
  set initzrot      0      ;# avoid tksurfer.tcl xrot (tk scale clamps -180,180)
  set surfscale   1.0      ;# every frame
  set rotsteps    180      ;# steps for 360 rot
  set dyrot       2.0      ;# $rotsteps*$dyrot=360 for one complete rot loop
  set f             0      ;# index first output tiff (can reset to append)
  set minflate      0      ;# surface number (first suffix: 0000)
  set maxflate    300      ;# skips any missing intermediate
  #set skip         0      ;# how many surfaces to skip each step
  set every         1      ;# easier to understand
  set outdir     /tmp      ;# or: $env(SUBJECTS_DIR)/$subject/rgb
  set mkmpg1flag    0      ;# turn on to make mpg1 (doesn't delete tiffs)
  set bigcnt        1      ;# rotpump-only: frames to stay big (min=1)
  set smallcnt      1      ;# rotpump-only: frames to stay shrunken (min=1)
  set normarea      1      ;# for inflate
  ### simple example (300 surface saved, use 150)
  #set inflatetype simple
  #set surfinfix  inflated
  #set inityrot     0
  #set initxrot     0
  #set initzrot     0
  #set minflate     0
  #set maxflate   300
  #set every        2
  #set outdir    /tmp
  ### rotpump example (only 14 surfs saved: 0000 0010 0020 ... 0130)
  #set inflatetype rotpump
  #set surfinfix   sphere
  #set inityrot     0
  #set initxrot     0
  #set initzrot     0
  #set surfscale 0.65
  #set rotsteps   230  ;# 5cyc*(13+13+5+15) see below for effect of big/smallcnt
  #set dyrot   1.5652  ;# 360/230 -> one full rotcycle
  #set f            0
  #set minflate     0
  #set maxflate   130
  #set every       10
  #set outdir    /tmp
  #set smallcnt     5  ;# e.g. sm=3,bg=5:a b c d e [e e e e e] d c b a [a a a] b
  #set bigcnt      15
  #set normarea     0  ;# sphere all same size
}
#############################################################################
### for cmdline use
if {!$openglwindowflag} { open_window }

### popup controls (N.B.: buttonname "RUN SCRIPT" req'd for purplekillcontrols)
if ![info exists inflatemoviectrls] { set inflatemoviectrls "" }
if [winfo viewable .] {  ;# popup
  if {!$userok} {
    if [winfo exists $inflatemoviectrls] { raise $inflatemoviectrls; return }
    set inflatemoviectrls [controls "INFLATE MOVIE LOOP\
            \nExpert Prefs: \"write every x iter\" != 0\
            \ninflatetype: simple, frontbak, rotpump\
            \nsurfinfix: inflated, sphere, sphere.reg" {
      inflatetype surfinfix inityrot initxrot initzrot surfscale rotsteps \
      dyrot f minflate maxflate every outdir smallcnt bigcnt normarea
    } "RUN SCRIPT" "set userok 1; source [info script]" 12]
    bind $inflatemoviectrls <ButtonRelease-3> { helpwin script_inflatemovie }
    return
  }
} else {                 ;# batch scripts; re-read env to override defaults
  source $env(CSURF_DIR)/lib/tcl/readenv.tcl
}
set skip [expr $every - 1]

### report, even if aborted
puts ""
puts "inflatemovie.tcl: inflatetype = $inflatetype"
puts "inflatemovie.tcl: surfinfix = $surfinfix"
puts "inflatemovie.tcl: inityrot = $inityrot"
puts "inflatemovie.tcl: initxrot = $initxrot"
puts "inflatemovie.tcl: initzrot = $initzrot"
puts "inflatemovie.tcl: surfscale = $surfscale"
puts "inflatemovie.tcl: rotsteps = $rotsteps"
puts "inflatemovie.tcl: dyrot = $dyrot"
puts "inflatemovie.tcl: f = $f"
puts "inflatemovie.tcl: minflate = $minflate"
puts "inflatemovie.tcl: maxflate = $maxflate"
puts "inflatemovie.tcl: every = $every (skip = $skip)"
puts "inflatemovie.tcl: outdir = $outdir"
puts "inflatemovie.tcl: bigcnt = $bigcnt"
puts "inflatemovie.tcl: smallcnt = $smallcnt"
puts "inflatemovie.tcl: mkmpg1flag = $mkmpg1flag"
puts ""

### check first/last req'd input surf, surfinfix, inflatetype
set surfbeg \
  $env(SUBJECTS_DIR)/$subject/surf/$hemi.$surfinfix[format "%04d" $minflate]
if ![file exists $surfbeg] {
  confirmalert "first inflate step missing:\n\n    $surfbeg\n\n...quitting"
  return
}
set surfend \
  $env(SUBJECTS_DIR)/$subject/surf/$hemi.$surfinfix[format "%04d" $maxflate]
if ![file exists $surfend] {
  confirmalert "last inflate step missing:\n\n    $surfend\n\n...quitting"
  return
}
if {$surfinfix != "inflated" && $surfinfix != "sphere" && \
    $surfinfix != "sphere.reg"} {
  confirmalert "bad inflate surfinfix (OK: inflated, sphere, sphere.reg)"
  return
}
if {$inflatetype != "simple" && $inflatetype != "frontbak" && \
    $inflatetype != "rotpump"} {
  confirmalert "bad inflatetype (OK: simple, frontbak)\n\n...quitting"
  return
}
if {$inflatetype == "frontbak" && $skip != 0} {
  confirmalert "inflatetype \"frontbak\" req's every step\n\n...quitting"
  return
}
if {$inflatetype != "rotpump"} {
  if {$smallcnt != 1 || $bigcnt != 1} {
    confirmalert "bigcnt/smallcnt only relevant to inflatetype=rotpump"
  }
}

### go
puts "inflatemovie.tcl: #####################################"
puts "inflatemovie.tcl: begin saving tiffs (startframe=f[format "%04d" $f])"
puts "inflatemovie.tcl: #####################################"
set dstep [expr $skip + 1]
set tiffcnt 0
set drawnflag 0

### simple inflate (maybe skip some surfs)
if {$inflatetype == "simple"} {
  for {set inflstep $minflate} {$inflstep <= $maxflate} {incr inflstep $dstep} {
    setfile insurf $hemi.$surfinfix[format "%04d" $inflstep]
    if ![file exists $insurf] {puts "inflatemovie.tcl: skip $insurf"; continue}
    read_binary_surface
    if {$normarea} { normalize_area } 
    recalc_surface_center
    make_lateral_view
    rotate_brain_y $inityrot
    rotate_brain_x $initxrot
    rotate_brain_z $initzrot
    scale_brain $surfscale
    if {!$drawnflag} { redraw; set drawnflag 1 } else { redraw_cached }
    redraw
    raise_window
    set rgb $outdir/f[format "%04d" $f].tiff
    save_rgb
    incr f
    incr tiffcnt
    update
    if {$purplekillcontrols} {
      set purplekillcontrols 0
      confirmalert "Script interrupted:\n\n$script"
      return
    }
  }
}

### slow rot, faster inflate/deflate (loop: infl+deflat int factor of rotsteps)
if {$inflatetype == "rotpump"} {
  set inflstep $minflate
  set direction expand
  set yrot2 0.0  ;# avoid tksurfer.tcl $yrot
  for {set i 0} {$i < $rotsteps} {incr i} {
    setfile insurf $hemi.$surfinfix[format "%04d" $inflstep]
    if ![file exists $insurf] {puts "inflatemovie.tcl: skip $insurf"; continue}
    read_binary_surface
    if {$normarea} { normalize_area } 
    recalc_surface_center
    make_lateral_view
    rotate_brain_y $inityrot
    rotate_brain_x $initxrot
    rotate_brain_z $initzrot
    rotate_brain_y $yrot2  ;# after full pose reset
    scale_brain $surfscale
    if {!$drawnflag} { redraw; set drawnflag 1 } else { redraw_cached }
    raise_window
    set rgb $outdir/f[format "%04d" $f].tiff
    save_rgb
    set yrot2 [expr $yrot2 + $dyrot]
    incr f
    incr tiffcnt
    update
    if {$purplekillcontrols} {
      set purplekillcontrols 0
      confirmalert "Script interrupted:\n\n$script"
      return
    }
    if {$direction == "expand"} {
      incr inflstep $dstep
      if {$inflstep >= $maxflate} { set direction staybig; set j $bigcnt }
    } elseif {$direction == "staybig"} {
      incr j -1
      if {$j == 0} { set direction contract }
    } elseif {$direction == "contract"} {
      incr inflstep -$dstep
      if {$inflstep <= $minflate} { set direction staysmall; set k $smallcnt }
    } elseif {$direction == "staysmall"} {
      incr k -1
      if {$k == 0} { set direction expand }
    } else { ; }
  }
}

### loop: rot360/inflate/rot360/deflate/rot180/inflate/rot360/deflate/rot180
if {$inflatetype == "frontbak"} {
  set halfrot [expr $rotsteps/2]
  ### rotate 360 around vertical axis before inflate
  set inflstep $minflate
  setfile insurf $hemi.$surfinfix[format "%04d" $inflstep]
  read_binary_surface   ;# req same vtx cnt as orig surface (could check stale)
  if {$normarea} { normalize_area } ;# mris_inflate shrinks, only norms at end
  recalc_surface_center
  set yrot2 0.0  ;# avoid tksurfer.tcl $yrot
  for {set i 0} {$i < $rotsteps} {incr i} {
    make_lateral_view
    rotate_brain_y $inityrot
    rotate_brain_x $initxrot
    rotate_brain_z $initzrot
    rotate_brain_y $yrot2  ;# after full pose reset
    scale_brain $surfscale
    if {!$drawnflag} { redraw; set drawnflag 1 } else { redraw_cached }
    raise_window
    set rgb $outdir/f[format "%04d" $f].tiff
    save_rgb
    set yrot2 [expr $yrot2 + $dyrot]
    incr f
    incr tiffcnt
    update      ;# keep tksurfer.tcl interface alive
    if {$purplekillcontrols} {
      set purplekillcontrols 0
      confirmalert "Script interrupted:\n\n$script"
      return
    }
  }
  
  ### inflate dorsal view
  set yrot2 0.0  ;# avoid tksurfer.tcl $yrot
  for {set inflstep $minflate} {$inflstep <= $maxflate} {incr inflstep} {
    setfile insurf $hemi.$surfinfix[format "%04d" $inflstep]
    if ![file exists $insurf] {puts "inflatemovie.tcl: skip $insurf"; continue}
    read_binary_surface
    if {$normarea} { normalize_area }
    recalc_surface_center
    make_lateral_view
    rotate_brain_y $inityrot
    rotate_brain_x $initxrot
    rotate_brain_z $initzrot
    rotate_brain_y $yrot2  ;# after full pose reset
    scale_brain $surfscale
    redraw_cached
    raise_window
    set rgb $outdir/f[format "%04d" $f].tiff
    save_rgb
    incr f
    incr tiffcnt
    update
    if {$purplekillcontrols} {
      set purplekillcontrols 0
      confirmalert "Script interrupted:\n\n$script"
      return
    }
  }
  
  ### rotate 360 after inflate
  set inflstep $maxflate
  setfile insurf $hemi.$surfinfix[format "%04d" $inflstep]
  read_binary_surface
  if {$normarea} { normalize_area }
  recalc_surface_center
  set yrot2 0.0  ;# avoid tksurfer.tcl $yrot
  for {set i 0} {$i < $rotsteps} {incr i} {
    make_lateral_view
    rotate_brain_y $inityrot
    rotate_brain_x $initxrot
    rotate_brain_z $initzrot
    rotate_brain_y $yrot2  ;# after full pose reset
    scale_brain $surfscale
    redraw_cached
    raise_window
    set rgb $outdir/f[format "%04d" $f].tiff
    save_rgb
    set yrot2 [expr $yrot2 + $dyrot]
    incr f
    incr tiffcnt
    update
    if {$purplekillcontrols} {
      set purplekillcontrols 0
      confirmalert "Script interrupted:\n\n$script"
      return
    }
  }
  
  ### deflate in dorsal view
  set yrot2 0.0  ;# avoid tksurfer.tcl $yrot
  for {set inflstep $maxflate} {$inflstep >= $minflate} {incr inflstep -1} {
    setfile insurf $hemi.$surfinfix[format "%04d" $inflstep]
    if ![file exists $insurf] {puts "inflatemovie.tcl: skip $insurf"; continue}
    read_binary_surface
    if {$normarea} { normalize_area }
    recalc_surface_center
    make_lateral_view
    rotate_brain_y $inityrot
    rotate_brain_x $initxrot
    rotate_brain_z $initzrot
    rotate_brain_y $yrot2  ;# after full pose reset
    scale_brain $surfscale
    redraw_cached
    raise_window
    set rgb $outdir/f[format "%04d" $f].tiff
    save_rgb
    incr f
    incr tiffcnt
    update
    if {$purplekillcontrols} {
      set purplekillcontrols 0
      confirmalert "Script interrupted:\n\n$script"
      return
    }
  }
  
  ### rotate 180 after deflate
  set inflstep $minflate
  setfile insurf $hemi.$surfinfix[format "%04d" $inflstep]
  read_binary_surface
  if {$normarea} { normalize_area }
  recalc_surface_center
  set yrot2 0.0  ;# avoid tksurfer.tcl $yrot
  for {set i 0} {$i < $halfrot} {incr i} {
    make_lateral_view
    rotate_brain_y $inityrot
    rotate_brain_x $initxrot
    rotate_brain_z $initzrot
    rotate_brain_y $yrot2  ;# after full pose reset
    scale_brain $surfscale
    redraw_cached
    raise_window
    set rgb $outdir/f[format "%04d" $f].tiff
    save_rgb
    set yrot2 [expr $yrot2 + $dyrot]
    incr f
    incr tiffcnt
    update
    if {$purplekillcontrols} {
      set purplekillcontrols 0
      confirmalert "Script interrupted:\n\n$script"
      return
    }
  }
  
  ### inflate ventral view
  set yrot2 180.0  ;# avoid tksurfer.tcl $yrot
  for {set inflstep $minflate} {$inflstep <= $maxflate} {incr inflstep} {
    setfile insurf $hemi.$surfinfix[format "%04d" $inflstep]
    if ![file exists $insurf] {puts "inflatemovie.tcl: skip $insurf"; continue}
    read_binary_surface
    if {$normarea} { normalize_area }
    recalc_surface_center
    make_lateral_view
    rotate_brain_y $inityrot
    rotate_brain_x $initxrot
    rotate_brain_z $initzrot
    rotate_brain_y $yrot2  ;# after full pose reset
    scale_brain $surfscale
    redraw_cached
    raise_window
    set rgb $outdir/f[format "%04d" $f].tiff
    save_rgb
    incr f
    incr tiffcnt
    update
    if {$purplekillcontrols} {
      set purplekillcontrols 0
      confirmalert "Script interrupted:\n\n$script"
      return
    }
  }
  
  ### rotate 360 after inflate
  set inflstep $maxflate
  setfile insurf $hemi.$surfinfix[format "%04d" $inflstep]
  read_binary_surface
  if {$normarea} { normalize_area }
  recalc_surface_center
  set yrot2 180.0  ;# avoid tksurfer.tcl $yrot
  for {set i 0} {$i < $rotsteps} {incr i} {
    make_lateral_view
    rotate_brain_y $inityrot
    rotate_brain_x $initxrot
    rotate_brain_z $initzrot
    rotate_brain_y $yrot2  ;# after full pose reset
    scale_brain $surfscale
    redraw_cached
    raise_window
    set rgb $outdir/f[format "%04d" $f].tiff
    save_rgb
    set yrot2 [expr $yrot2 + $dyrot]
    incr f
    incr tiffcnt
    update
    if {$purplekillcontrols} {
      set purplekillcontrols 0
      confirmalert "Script interrupted:\n\n$script"
      return
    }
  }
  
  ### deflate in ventral view
  set yrot2 180.0  ;# avoid tksurfer.tcl $yrot
  for {set inflstep $maxflate} {$inflstep >= $minflate} {incr inflstep -1} {
    setfile insurf $hemi.$surfinfix[format "%04d" $inflstep]
    if ![file exists $insurf] {puts "inflatemovie.tcl: skip $insurf"; continue}
    read_binary_surface
    if {$normarea} { normalize_area }
    recalc_surface_center
    make_lateral_view
    rotate_brain_y $inityrot
    rotate_brain_x $initxrot
    rotate_brain_z $initzrot
    rotate_brain_y $yrot2  ;# after full pose reset
    scale_brain $surfscale
    redraw_cached
    raise_window
    set rgb $outdir/f[format "%04d" $f].tiff
    save_rgb
    incr f
    incr tiffcnt
    update
    if {$purplekillcontrols} {
      set purplekillcontrols 0
      confirmalert "Script interrupted:\n\n$script"
      return
    }
  }
  
  ### rotate 180 after deflate for loop
  set inflstep $minflate
  setfile insurf $hemi.$surfinfix[format "%04d" $inflstep]
  read_binary_surface
  if {$normarea} { normalize_area }
  recalc_surface_center
  set yrot2 180.0  ;# avoid tksurfer.tcl $yrot
  for {set i 0} {$i < $halfrot} {incr i} {
    make_lateral_view
    rotate_brain_y $inityrot
    rotate_brain_x $initxrot
    rotate_brain_z $initzrot
    rotate_brain_y $yrot2  ;# after full pose reset
    scale_brain $surfscale
    redraw_cached
    raise_window
    set rgb $outdir/f[format "%04d" $f].tiff
    save_rgb
    set yrot2 [expr $yrot2 + $dyrot]
    incr f
    incr tiffcnt
    update
    if {$purplekillcontrols} {
      set purplekillcontrols 0
      confirmalert "Interrupted script:\n\n$script"
      return
    }
  }
}

### done
puts "inflatemovie.tcl: ########################"
puts "inflatemovie.tcl: done saving $tiffcnt tiffs"
puts "inflatemovie.tcl: ########################"

### make mpg
if {$mkmpg1flag} {
  set mpgname $subject-$patchinfix-$hemi.mpg
  puts [eval exec tiff2mpg -q 1 $outdir/f????.tiff $mpgname]
  puts [eval exec mpeg_play -dither color -quiet -loop $mpgname >& /dev/null]
}

### cleanup (don't destroy window or reset userok to save so many re-settable)
#if [info exists inflatemoviectrls] { destroy $inflatemoviectrls }

