#! /usr/bin/env tclsh
#
# This file builds a table of context for a file and puts it at the 
# front of the file.
#
# An entry for the table is indicated by a line in the file that follows
# a line of all '-' characters and ends with a ':'.

# In addition, /usr/bin/env  we REQUIRE a double line of all "-" 
# before the first 
# item to be indexed.  This line is the end of the front matter and we
# assume that an old ToC follows it and that the old ToC ends with the
# first item to be indexed.
#
#
# set v to 1 to debug
set v 0
set all "-"
set endch ":"
set me [info script]
proc echo {mess} {
  if {$::v} {
    puts "$::me: $mess"
  }
}

proc mess {mess} {
  puts "$::me: $mess"
}

proc all_this { line ch } {
  set l [string length $line]
  if {$l == 0} {return 0}
  for {set ix 0} {$ix < $l} {incr ix} {
    if {[string range $line $ix $ix ] != $ch} {
      #mess "$line rtn on [string range $line $ix $ix ]"
      return 0
    }
  }
  #mess "$line rtn true"
  return 1
}

set file [file norm [lindex $argv 0]]
if {[catch "open $file r" fid] != 0} {
  mess "Open error $fid on file $file"
  mess "quiting ..."
  exit 1
}
set data [read $fid]
close $fid
set indxList {}
set here 0	  
while {[set po [string first \n $data $here]] != -1} {
  #puts "$po"
  lappend indxList [expr $po -1]
  incr po
  set here $po
}

set lineno -1
set found -2
set TofC {}
set end_of_front 0
set endOfTofC 0
#
# If found + 1 is less than lineno  we look only for a line of "-"
# else, look for the ":" line, another "-" line
# 
set last 0
foreach idx $indxList { 
  set line [string range $data $last $idx]
  set last [expr $idx + 2]
  incr lineno
  echo "$found $lineno $line"
  if {($found + 1) < $lineno} {
    if {[all_this $line $all]} {
      echo "Set found $lineno"
      set found $lineno
    }
    echo "Not f+1, continue"
    continue
  }
  if {[string range $line end end] == $endch} {
    # Found a ToC item
    if {$end_of_front == 0} {
      mess "Found ToC line prior to End of Front matter. \n quitting."
      exit 1
    }
    if {$endOfTofC == 0} {
      echo "End of TofC found"
      set endOfTofC [expr $lineno - 2]
    }
    set TofC ${TofC}\n${line}\n
    echo "adding $line"
    continue
  } elseif {[all_this $line $all]} {
    if {$end_of_front == 0} {
      echo "End of Front found"
      set end_of_front $lineno
      # this continue should prevent the end of front doubling as a TofC topic
      continue
    }
    set found $lineno
  }
}

# Ok what have we found?
#
if {$lineno < 3} {
  mess "file too short, quitting"
  exit 1
}
#echo "Found [llength $TofC] entries"
if {$TofC == {} } {
  mess "No Table of Context entries found \n quitting"
  exit 1
}
# build the new file
set newf [string range $data 0 [lindex $indxList $end_of_front]]
#echo "Front: $newf"

set newf "${newf}\n\nTable of Contents\n\n"
set newf ${newf}${TofC}
set newf ${newf}[string range $data [lindex $indxList $endOfTofC]+1 end]

if {[catch "open $file w" fid] != 0} {
  mess "Open error $fid on file $file"
  mess "quitting ..."
  exit 1
}
puts  $fid $newf
#echo $fid
close $fid
mess "Success, done"
exit 0
