#! /bin/sh
# (next line not seen by tcl) \
exec tclsh $0 ${1+"$@"}    # goto tcl

### use/help
if {$argc != 3} {
  puts ""
  puts "use: sortlabel <infile> <outfile> <vtx0>"
  puts ""
  puts "  --sort csurf/freesurfer label by path-dep Euclidean dist from vtx0"
  puts "  --find nearest vtx to vtx0, then nearest to that one, and so on"
  puts "  --designed for sorting single-vertex paths (e.g., Dijk output)"
  puts "  --output label vertices in path order (vs. std label vtx num order)"
  puts "  --outfile equals infile OK (warning)"
  puts "  --overlay data in file (if any, real or complex) copied as is"
  puts "  --label should be less than ~1000 vertices (larger very slow b/c tcl)"
  puts "  --for large labels, use equiv C-funct, write_sorted_by_pathdist_label"
  puts ""
  exit
}
set infile [lindex $argv 0]
set outfile [lindex $argv 1]
set vtx0 [lindex $argv 2]

### check
if ![file exists $infile] {
  puts "infile $infile not found"
  exit
}
if { [file extension $infile] != ".label" } {
  puts "sortlabel: ### infile suffix not .label  ...quitting"
  exit
}
if { [file extension $outfile] != ".label" } {
  puts "sortlabel: ### outfile suffix not .label  ...quitting"
  exit
}
if { [file exists $outfile] && "$infile" != "$outfile" } {
  puts "\nsortlabel: ### outfile $outfile exists, overwrite? (Y/n)"
  set resp [read stdin 1]
  if {"$resp" == "n" || "$resp" == "N"} {puts "$outfile not overwritten"; exit}
}
if { "$infile" == "$outfile" } {
  puts "sortlabel: ### OK to update infile $infile (Y/n)"
  set resp [read stdin 1]
  if {"$resp" == "n" || "$resp" == "N"} {puts "$infile not updated"; exit}
}
# read infile to see if vtx0 there
set id [open $infile r]
set lines [split [read $id] "\n"]
close $id
set found 0
foreach line $lines {
  if { [lindex $line 0] == $vtx0 } { set found 1 }
}
if { !$found } {
  puts "sortlabel: ### vertex vtx0 $vtx0 not found in $infile ...quitting"
  exit
}
# warn large labels
set vtxcnt [lindex $lines 1]
if {$vtxcnt > 1000} {
  puts "sortlabel: ### >1000 vertices, takes long time, go anyway? (Y/n)"
  set resp [read stdin 1]
  if {"$resp" == "n" || "$resp" == "N"} {puts "$outfile not overwritten"; exit}
}

### init
set ord 2  ;# label file line nums, this is first data vtx line
set vtxcnt [lindex $lines 1]
set todo $vtxcnt
set linecnt [expr $vtxcnt + 2]
for {set i 2} {$i < $linecnt} {incr i} {
  set line [lindex $lines $i]
  set v($i) [lindex $line 0]
  set x($i) [lindex $line 1]
  set y($i) [lindex $line 2]
  set z($i) [lindex $line 3]
  if { $v($i) == $vtx0 } {  ;# start at vtx0
    set x0 $x($i)
    set y0 $y($i)
    set z0 $z($i)
    set order($ord) $i   ;# both indices 0-based label file line nums
    set done($i) 1       ;# rm from search list
    incr todo -1
  } else { set done($i) 0 }
}

### find nearest Euclidean, save to order, rm from search list, til done
while {$todo > 0} {
  set dmin 1000.0
  for {set i 2} {$i < $linecnt} {incr i} {
    if {!$done($i)} {
      set dx [expr $x($i) - $x0]
      set dy [expr $y($i) - $y0]
      set dz [expr $z($i) - $z0]
      set d [expr sqrt( ($dx * $dx) + ($dy * $dy) + ($dz * $dz) )]
      if {$d < $dmin} { set dmin $d; set imin $i }
    }
  }
  incr ord
  set x0 $x($imin)  ;# new start
  set y0 $y($imin)
  set z0 $z($imin)
  set order($ord) $imin
  set done($imin) 1
  if ![expr $todo%100] {puts "[expr $vtxcnt - $todo] of $vtxcnt vertices done"}
  incr todo -1
}

### write path ordered label
set id [open $outfile w 0644]
set i [expr $linecnt - 1]
set lastline [lindex $lines $order($i)]
set vtx1 [lindex $lastline 0]
for {set i 0} {$i < $linecnt} {incr i} {
  if {$i == 0} {
    puts $id "[lindex $lines 0], vtxs in pathorder: $vtx0->$vtx1"
  } elseif {$i == 1} {
    puts $id [lindex $lines 1]
  } else {
    puts $id [lindex $lines $order($i)]
  }
}
close $id
puts "sortlabel.tcl: path-order-sorted label: outfile:\n  $outfile"

