#!/bin/sh
#
# File: make_manual.tcl
#
# Purpose: automatically generate MD++ manual in latex and html format
#
# \
exec tclsh "$0" ${1+"$@"}

#-----------------------------------------------------------------
# Setting
#
# location of MD++ source files
set src_dir "../src"
set src_name "*.cpp"
set tex_file "md++.tex"
set pkgs_sorted {organizer md mdparallel fs lj2 eam meam meam-baskes meam-lammps}
#excluded pkgs {swlj meam-marian vaspbox xgeo}

# places to host subdirectories for each command and variable
set tex_dir "tex"
set create_dir 0

# package, command, variables that will not appear on the manual
set remove_coms { closefile openfile printall }
set remove_vars { intval str x y z }

#-----------------------------------------------------------------
# Main program begins ...
#
set tstart [clock clicks -milliseconds]
puts "MD++ source directory is  $src_dir"

# need to create a "quit" command in md.cpp

#-----------------------------------------------------------------
# Find all commands and variables
#
set keyword "bind"
puts "Find all lines in souce code that contains keyword: $keyword\n"

# create a list of all matches
set src_files [lsort -dictionary [glob $src_dir/$src_name]]
foreach filename $src_files {
    set shortname [file tail $filename]
    set fp [open $filename r]
    while {[gets $fp line] >= 0} {
        if [regexp -- $keyword $line] {
            lappend match [list $shortname $line]
        }
    }
    close $fp
}

# create a list of commands and a list of variables
set keyword_com "bindcommand"
set keyword_var "bindvar"
foreach entry $match {
    set filename [file rootname [lindex $entry 0]]
    set line     [lindex $entry 1]
    if [regexp -- $keyword_com $line] {
        regexp {[^\"]*\"([^\"]*)\"[^\"]*} $line ->  name
        lappend md_coms [list $filename $name]
    }
    if [regexp -- $keyword_var $line] {
        regexp {[^\"]*\"([^\"]*)\"[^\"]*} $line ->  name
        lappend md_vars [list $filename $name]
    }
}

# sort commands and variables in ascending order
set md_coms [lsort -dictionary $md_coms]
set md_vars [lsort -dictionary $md_vars]

if { $create_dir } {
# create subdirectories for all commands and variables
foreach com $md_coms {
    set source [lindex $com 0]
    set name   [lindex $com 1]
    set dirname "$tex_dir/$source"
    set subdir  "$dirname/coms"
    set subdir2 "$subdir/$name"

    if {![file isdirectory $dirname]} {
        puts "create new directory: $dirname"
        file mkdir $dirname
    }     
    if {![file isdirectory $subdir]} {
        puts "create new directory: $subdir"
        file mkdir $subdir
    }
    if {![file isdirectory $subdir2]} {
        puts "create new directory: $subdir2"
        file mkdir $subdir2
    } else {
        #puts "directory $subdir2 already exists"
    }
}

foreach var $md_vars {
    set source [lindex $var 0]
    set name   [lindex $var 1]
    set dirname "$tex_dir/$source"
    set subdir  "$dirname/vars"
    set subdir2 "$subdir/$name"

    if {![file isdirectory $dirname]} {
        puts "create new directory: $dirname"
        file mkdir $dirname
    }     
    if {![file isdirectory $subdir]} {
        puts "create new directory: $subdir"
        file mkdir $subdir
    }
    if {![file isdirectory $subdir2]} {
        puts "create new directory: $subdir2"
        file mkdir $subdir2
    } else {
        #puts "directory $subdir2 already exists"
    }
}
}

# group commands and variables according to their source (package)
set md_pkgs { }
set md_pkg_names { }
foreach com [concat $md_coms $md_vars] {
    set pkg [lindex $com 0]
    set ind [lsearch $md_pkg_names $pkg]
    if { $ind == -1 } {
        lappend md_pkgs [ list $pkg { } { } ]
        lappend md_pkg_names [ list $pkg ]
    }
}

foreach com $md_coms {
    set pkg  [lindex $com 0]
    set name [lindex $com 1]
    if { [lsearch $remove_coms $name] == -1 } {
        set ind  [lsearch $md_pkg_names $pkg]
        set line [lindex $md_pkgs $ind]
        set existing_coms [lindex $line 1]
        if { [lsearch $existing_coms $name] == -1 } {
            lset md_pkgs $ind 1 [ concat $existing_coms $name ]
        }
    }
}

foreach var $md_vars {
    set pkg  [lindex $var 0]
    set name [lindex $var 1]
    if { [lsearch $remove_vars $name] == -1 } {
        set ind  [lsearch $md_pkg_names $pkg]
        set line [lindex $md_pkgs $ind]
        set existing_vars [lindex $line 2]
        if { [lsearch $existing_vars $name] == -1 } {
            lset md_pkgs $ind 2 [ concat $existing_vars $name ]
        }
    }
}

#-----------------------------------------------------------------
# Print out statistics
#
puts "\n Package\t\tCommands\tVariables"
puts "---------------------------------------------------"
foreach pkg $md_pkgs {
    set pkg_name [lindex $pkg 0]
    set pkg_coms [lindex $pkg 1]
    set pkg_vars [lindex $pkg 2]
    puts -nonewline " [format %-20s $pkg_name]\t"
    puts -nonewline "[format %-10d [llength $pkg_coms]]\t"
    puts "[format %-10d [llength $pkg_vars]]"
}
puts "---------------------------------------------------"
puts "Total\t[llength $md_coms]\t[llength $md_vars]"


#-----------------------------------------------------------------
# Create latex file
#
set fp [open $tex_file w 0600]
puts $fp "%%%%%%%%%%%%%%% -*-Tex-*- %%%%%%%%%%%%%%%%%%"
puts $fp "%% Creation Date : [clock format [clock seconds]]"
puts $fp "%% Last Modified :                            "
puts $fp "%% File : $tex_file                           "
puts $fp "%% Created by make_manual.tcl                 "
puts $fp "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%"
puts $fp "\\documentclass\[12pt, fullpage\]{article}"
puts $fp "\\usepackage{graphicx}"
puts $fp "\\usepackage{colortbl}"
puts $fp "\\usepackage{longtable}"
puts $fp "\\usepackage{color}"
puts $fp {\setlength{\topmargin}{-.5in}}
puts $fp {\setlength{\oddsidemargin}{0in}}
puts $fp {\setlength{\evensidemargin}{0in}}
puts $fp {\setlength{\textwidth}{6.5in}}
puts $fp {\setlength{\textheight}{9in}}
puts $fp {\newcommand{\FL}{\hspace{0in}\\}}
puts $fp {\definecolor{light}{gray}{0.0}}
puts $fp {\newcommand{\colorone}{\rowcolor[gray]{0.8}}}
puts $fp {\newcommand{\colortwo}{\rowcolor[gray]{1.0}}}
puts $fp "\\author{Wei Cai}"
puts $fp "\\title{MD++ Reference Manual}"
puts $fp "\\date{\\today}"
puts $fp "\\begin{document}"
puts $fp "\\maketitle"

foreach pkg_name $pkgs_sorted {
    set ind [lsearch $md_pkg_names $pkg_name]
    set pkg [lindex $md_pkgs $ind]
    set pkg_name [lindex $pkg 0]
    set pkg_coms [lindex $pkg 1]
    set pkg_vars [lindex $pkg 2]
    puts $fp "\\section{Class $pkg_name {\\normalsize \\rm ("
    puts $fp "[llength $pkg_coms] commands and"
    puts $fp "[llength $pkg_vars] variables )}}\n\n"

    # create table of commands
    puts $fp "\\FL {\\large \\bf Commands}\n\n"
    puts $fp {\begin{longtable}{|l|l|}}
    puts $fp {\hline}

    set count 0
    foreach com $pkg_coms {
        set fdescr "$tex_dir/$pkg_name/coms/$com/short_descr_$com.tex"
        regsub -all "_" $com "\\_" newcom        
        if [expr fmod($count,2)==0 ] {
            set color colorone
        } else {
            set color colortwo
        }
        if [ file exists $fdescr ] {
            set fid [open $fdescr r]
            puts $fp "\\$color {\\tt $newcom} & "
            # past description file
            puts $fp {\begin{minipage}[c]{.65\textwidth}\FL}
            while {[gets $fid line] >= 0} { puts $fp $line }
            puts $fp {\FL\end{minipage}}
            puts $fp "\\\\ \\hline"
            close $fid
        } else {
            puts $fp "\\$color {\\tt $newcom} & {no description file} \\\\ \\hline"
        }
        incr count

    }
    puts $fp "\\end{longtable}"

    # create table of variables
    puts $fp "\\FL {\\large \\bf Variables}\n\n"
    puts $fp {\begin{longtable}{|l|l|}}
    puts $fp {\hline}

    set count 0
    foreach var $pkg_vars {
        set fdescr "$tex_dir/$pkg_name/vars/$var/short_descr_$var.tex"
        regsub -all "_" $var "\\_" newvar        
        if [expr fmod($count,2)==0 ] {
            set color colorone
        } else {
            set color colortwo
        }
        if [ file exists $fdescr ] {
            set fid [open $fdescr r]
            puts $fp "\\$color {\\tt $newvar} & "
            # past description file
            puts $fp {\begin{minipage}[c]{.65\textwidth}\FL}
            while {[gets $fid line] >= 0} { puts $fp $line }
            puts $fp {\FL\end{minipage}}
            puts $fp "\\\\ \\hline"
            close $fid
        } else {
            puts $fp "\\$color {\\tt $newvar} & {no description file} \\\\ \\hline"
        }
        incr count

    }
    puts $fp "\\end{longtable}"
}

puts $fp "\\bibliography{a}"
puts $fp "\\bibliographystyle{unsrt}"
puts $fp "\\end{document}"

close $fp

# to compile latex file run
# ./compile

#-----------------------------------------------------------------
# The end
#
set tend [clock clicks -milliseconds]
puts "\nFinished:   [clock format [clock seconds]]."
puts "Time used:  [expr ($tend - $tstart)/1000.0] second."
