#!/bin/sh  
# \
exec oagtclsh "$0" "$@"

if [info exists env(OAG_TOP_DIR)] {
    set auto_path [linsert $auto_path 0 $env(OAG_TOP_DIR)/oag/apps/lib/$env(HOST_ARCH)]
} else {
    set auto_path [linsert $auto_path 0 /usr/local/oag/apps/lib/$env(HOST_ARCH)]
}

APSStandardSetup

proc CreateLatexHeader {args} {
    return "\\documentclass\[11pt\]\{article\}
\\usepackage\{booktabs\}
\\newcommand\{\\progref\}\[1\]\{\\hyperref\{\#1\}\{\{\\tt \#1\} (\}\{)\}\{\#1\}\}
\\pagestyle\{plain\}
\\newenvironment\{req\}\{\\begin\{equation\} \\rm\}\{\\end\{equation\}\}
\\setlength\{\\topmargin\}\{0.15 in\}
\\setlength\{\\oddsidemargin\}\{0 in\}
\\setlength\{\\evensidemargin\}\{0 in\}
\\setlength\{\\textwidth\}\{6.5 in\}
\\setlength\{\\headheight\}\{-0.5 in\}
\\setlength\{\\textheight\}\{9 in\}
\\begin\{document\}"
}

proc ReplaceMacros {str} {
    global macro
    set macros [split $macro ,]
    set a $str
    foreach m $macros {
        set m [split $m =]
        set m1 <[lindex $m 0]>
        set m2 [lindex $m 1]
        set i [string first $m1 $str]
        if {$i != -1} {
            set str [string range $str 0 [expr {$i - 1}]]${m2}[string range $str [expr {$i + [string length $m1]}] end]
        }
    }
    return $str
}

proc CleanLatexString {str} {
    set str [join [split $str "%"] \\%]
    set str [join [split $str "&"] \\&]
    set str [join [split $str "\b"] \\b]
    set str [join [split $str "\t"] \\t]
    set str [join [split $str "\r"] \\r]
    set str [join [split $str "\n"] \\n]
    return $str
}

proc EscapePercentSign {str} {
    return [join [split $str "%"] \\%]
}

proc CommandReference {str} {
    global env
    foreach name [array names env] {
        set ($name) $env($name)
    }
    if {[catch {eval exec $str} result]} {
        puts stderr "Error: $result"
        return "Error!"
    }
    if {[llength $result] != 1} {
        set result [join [split $result]]
    }
    return $result
}

proc SDDSDataReference {str} {
    global env
    set elements [split $str ";"]
    set file [lindex $elements 0]
    if {[string index $file 0] == "\$"} {
        set var [string trim [string range $file 1 end] "()"]
        if {[info exists env($var)]} {
            set file $env($var)
        }
    }
    if {![file exists $file]} {
        puts stderr "$file does not exist"
        return "Error!"
    }
    set name -[lindex $elements 1]
    set page ""
    set options ""
    foreach ele [lrange $elements 2 end] {
        if {[lindex [split $ele "="] 0] == "page"} {
            set page -$ele
        } else {
            append options "-$ele "
        }
    }
    if {[string length $options] > 0} {
        if {[catch {eval exec sddsprocess $file -pipe=out $options | sdds2stream -pipe $name $page} value]} {
            puts stderr "Error: $value"
            return "Error!"
        }
    } else {
        if {[catch {eval exec sdds2stream $file $name $page} value]} {
            puts stderr "Error: $value"
            return "Error!"
        }
    }
    if {[llength $value] != 1} {
        set value [join [split $value]]
    }
    if {[llength $value] == 0} {
        puts stderr "Error: no values found in $file"
        return "Error!"
    }
    return $value
}

proc CreateLatexTable {args} {
    set sddsFile ""
    set caption "No caption"
    set label "tab:NoLabel"
    set verticalBars 1
    APSStrictParseArguments {sddsFile caption label verticalBars}
    #Read in SDDS file
    if {[catch {sdds load $sddsFile data} results]} {
        puts stderr "Error: $results"
        exit
    }
    set i 1
    while {[info exists data(Parameter.ColumnLabel$i)]} {
        if {![info exists data(Parameter.ColumnAlignment$i)]} {
            puts stderr "Error: Missing parameter ColumnAlignment$i"
            exit
        }
        if {![info exists data(Column.DataReference$i)]} {
            puts stderr "Error: Missing column DataReference$i"
            exit
        }
        if {![info exists data(Column.DataFormat$i)]} {
            puts stderr "Error: Missing column DataFormat$i"
            exit
        }
        incr i
    }
    if {$i < 2} {
        puts stderr "Error: Missing parameter ColumnLabel1"
        exit
    }
    set rowUnits 0
    if {[info exists data(Column.RowLabel)] && [info exists data(Column.RowUnits)]} {
        set rowUnits 1
    }

    set vb ""
    if $verticalBars {
        set vb "|"
    }

    set page 0
    set pages [llength $data(Column.[lindex $data(ColumnNames) 0])]
    set output "\\begin\{table\}\[htb\]\n\\caption\{$caption\}\n\\label\{$label\}\n\\begin\{center\}\n"
    if {[info exists data(Parameter.Title)]} {
        append output "\{\\Large\\bf\{"
        append output "[ReplaceMacros [CleanLatexString [lindex $data(Parameter.Title) 0]]]"
        append output "\\\\\}\}"
    }
    append output "\\begin\{tabular\}\{${vb}l"

    set i 1
    while {[info exists data(Parameter.ColumnLabel$i)]} {
        append output "${vb}[lindex $data(Parameter.ColumnAlignment$i) 0]"
        incr i
    }
    if {$rowUnits} {
        append output "${vb}l${vb}\}\n\\toprule\n"
    } else {
        append output "${vb}\}\n\\toprule\n"
    }


    set i 1
    while {[info exists data(Parameter.ColumnLabel$i)]} {
        set value [ReplaceMacros [CleanLatexString [lindex $data(Parameter.ColumnLabel$i) 0]]]
        if {[info exists data(Parameter.ColumnUnits$i)]} {
            append value " ([ReplaceMacros [CleanLatexString [lindex $data(Parameter.ColumnUnits$i) 0]]])"
        }
        append output " & $value"
        incr i
    }

    if {$rowUnits} {
        append output " & \\\\\n\\midrule\n"
    } else {
        append output " \\\\\n\\midrule\n"
    }

    for {set page 0} {$page < $pages} {incr page} {

        if {[info exists data(Parameter.SectionLabel)]} {
            set SectionLabel [ReplaceMacros [CleanLatexString [lindex $data(Parameter.SectionLabel) $page]]]
            if {[info exists data(Parameter.SectionSpan)] && [expr [lindex $data(Parameter.SectionSpan) $page]>1]} {
                set alignment l
                if {[info exists data(Parameter.SectionAlignment)]}  {
                    set alignment [lindex $data(Parameter.SectionAlignment) $page]
                }
                append output "\\multicolumn{[lindex $data(Parameter.SectionSpan) $page]}{$alignment}{\\bf $SectionLabel}"
            } else {
                append output "{\\bf $SectionLabel}"
                set i 1
                while {[info exists data(Parameter.ColumnLabel$i)]} {
                    append output " &"
                    incr i
                }  
            }
            if {$rowUnits} {
                append output " & \\\\\n"
            } else {
                append output " \\\\\n"
            }
        }

        set rows [llength [lindex $data(Column.RowLabel) $page]]
        for {set row 0} {$row < $rows} {incr row} {
            set RowLabel [ReplaceMacros [CleanLatexString [lindex [lindex $data(Column.RowLabel) $page] $row]]]
            append output "$RowLabel"
            set i 1
            while {[info exists data(Column.DataReference$i)]} {
                set value [ReplaceMacros [lindex [lindex $data(Column.DataReference$i) $page] $row]]
                if {[string index $value 0] == "@"} {
                    set value [SDDSDataReference [string range $value 1 end]]
                } elseif {[string index $value 0] == "<"} {
                    set value [CommandReference [string range $value 1 end]]
                }
                set value [CleanLatexString $value]
                set format [ReplaceMacros [lindex [lindex $data(Column.DataFormat$i) $page] $row]]
                if {[llength $format]} {
                    if {[string first "%" $format] == -1} {
                        set format "%$format"
                    }
                    if {$value != "Error!"} {
                        if {[llength $value]} {
                            set value [eval format {$format} $value]
                        }
                        set dollarsign 0
                        set valTemp ""
                        foreach v $value {
                            if {$v == "\$"} {
                                set dollarsign [expr !$dollarsign]
                            }
                            if {(![string match %s $format]) && ([string match *e* $v] || [string match *g* $v])} {
                                set mantissa [os editstring S/e/100d $v]
                                if {$mantissa != "{}"} {
                                    scan [os editstring Ze $v] %d exponent
                                    if {$dollarsign} {
                                        set v [CleanLatexString "$mantissa \\times 10^\{$exponent\}"]
                                    } else {
                                        set v [CleanLatexString "\$$mantissa \\times 10^\{$exponent\}\$"]
                                    }
                                }
                                lappend valTemp $v
                            } else {
                                lappend valTemp $v
                            }
                        }
                        set value [join $valTemp]
                    }
                }
                if {[info exists data(Column.DataUnits$i)]} {
                    set units [ReplaceMacros [CleanLatexString [lindex [lindex $data(Column.DataUnits$i) $page] $row]]]
                    set value "$value $units"
                }
                append output " & $value"
                incr i
            }
            
            if {$rowUnits} {
                set RowUnits [ReplaceMacros [CleanLatexString [lindex [lindex $data(Column.RowUnits) $page] $row]]]
                append output " & $RowUnits \\\\\n"
            } else {
                append output " \\\\\n"
            }
        }
    }

    append output "\\bottomrule\n\\end\{tabular\}\n\\end\{center\}\n\\end\{table\}\n"
    return $output
}

proc CreateLatexEnding {args} {
    return "\\end\{document\}"
}

#Parse the command line arguments
set args $argv
set sddsFile ""
set texFile ""
set display 1
set header 1
set macro ""
set label "tab:NoLabel"
set caption "No caption"
set verticalBars 1
APSStrictParseArguments {sddsFile texFile display macro header label caption verticalBars}

if {([string length $sddsFile] == 0) || ([string length $texFile] == 0)} {
    puts stderr {Usage: sdds2latex -sddsFile <file> -texFile <file> [-display <0|1>] [-header <0|1>] [-label <string>] [-verticalBars <0|1>] [-caption <string>] [-macro <original>=<replacement>,...]}
    exit
}

#Create the four parts of the latex file"
if $header {
    set output "[CreateLatexHeader][CreateLatexTable -sddsFile $sddsFile -caption $caption -label $label -verticalBars $verticalBars][CreateLatexEnding]"
} else {
    set output "[CreateLatexTable -sddsFile $sddsFile -caption $caption -label $label -verticalBars $verticalBars]"
}
if {[catch {open $texFile "w"} fid]} {
    puts stderr "Error: $fid"
    exit
}
puts $fid [EscapePercentSign $output]
catch {close $fid}
if {$display && !$header} {
    puts stderr "Error: Not possible to display results if latex header is not requested."
    exit
}

if {$display} {
    exec cp $texFile /tmp/temp_sdds2latex.tex
    set pwd [pwd]
    cd /tmp
    set env(TEXINPUTS) ".:/home/oxygen/EMERY/mytex:/opt/local/share/texmf/tex/latex//"
    exec latex temp_sdds2latex.tex
    catch {exec dvips temp_sdds2latex -o temp_sdds2latex.ps}
    exec gv temp_sdds2latex.ps &
    cd $pwd
}
