#  This code keeps track of a running process
#
# Copyright (c) 1999 Pacific Marketing and Consulting, Inc,
#       and ICEM Systems, GmbH.  All rights reserved.
# Author:  Wayne A. Christopher, wayne@icemcfd.com

# interrupt check numdone numtotal message color
# if numtotal is 0 then it won't update the percentage
# if only interrupt check is given then it will check but not update
# interrupt add_message "xxxx" : goes above the Done line

proc show_logfile {file { w .tetra_monitor } { name Tetra } { last_token "tetra finished" } } {
    global sl_finished sl_pid sl_name sl_last_token

    set sl_last_token $last_token
    set sl_name $name
    
    if { [ winfo exists $w ] == 0 } {
    	top_window $w 1 "$name monitor"
    	text $w.text -width 40 -height 24 -yscroll \
	    "$w.yscroll set" -relief sunken -background white \
	    -borderwidth 2
    	scrollbar $w.yscroll -relief sunken -command \
	    "$w.text yview" -orient v
    	frame $w.buts
    	button $w.buts.done -text Done -command \
	    "top_destroy $w; set sl_finished 0"
    	button $w.buts.stat -text Status -command \
	    "show_status $w"
    	button $w.buts.kill -text Terminate -command \
	    "kill_sl_proc $w"
    	pack $w.buts.stat $w.buts.done $w.buts.kill -side left
    	pack $w.buts -side bottom
    	pack $w.text -side left -fill both
    	pack $w.yscroll -side right -fill y
    	top_geometry $w -0-0
    }
    
    set fp [open $file r]
    catch {unset sl_pid}
    tail_dashf $fp "tail_sl_log $fp $w"
    
    tkwait variable sl_finished
    
    if $sl_finished {
	mess "$name is finished.\n"
	return 1
    } else {
	mess "$name monitor exited.\n"
	return 0
    }
}

proc tail_sl_log {fp mon line} {
    global sl_finished sl_pid sl_name sl_last_token

    if {![info exists sl_pid] && [string match "process *" $line]} {
        set sl_pid [lindex $line 2]
    }
    $mon.text insert end $line\n
    $mon.text yview -pickplace end
    if ![string compare $line "$sl_last_token"] {
        close $fp
        set sl_finished 1
    }
}
proc kill_sl_proc {mon} {
    global sl_pid sl_finished sl_name

    if ![info exists sl_pid] {
        mess "Can't check process status: PID not known.\n" red
        return
    }
    if [tk_dialog .really_kill "Kill job" " Really terminate $sl_name job?\n\
            Intermediate data will be lost." "" -1 Yes No] return
    exec kill -9 $sl_pid

    $mon.text insert end "$sl_name job killed.\n"
    $mon.text yview -pickplace end
    set sl_finished 0
}
proc show_status {mon} {
    global sl_pid

    if ![info exists sl_pid] {
        mess "Can't check process status: PID is not known.\n" red
        return
    }
    if [catch {exec ps -lp$sl_pid} psout] {
        mess "The process (pid $sl_pid) is already finished.\n" red
        return
    }
    set line ""
    foreach wd [split [lindex [split $psout \n] 1] " "] {
        if [string compare $wd ""] { lappend line $wd }
    }

    if {$line == ""} {
        mess "Can't get process status: process is not running, or is\
                running on a different machine.\n" red
        return
    }
    switch [llength $line] {
        14 {
            set tsize [lindex $line 9]
            set ttime [lindex $line 12]
        }
        13 {
            set tsize [lindex $line 9]
            set ttime [lindex $line 11]
        }
        15 {
            set tsize [lindex $line 10]
            set ttime [lindex $line 13]
        }
        default {
            error "Can't parse output of ps: \"$line\""
        }
    }

    set psize [cmd_pagesize]

    set sz [lindex [split $tsize :] 0]
    if [string match *K $sz] {
        set psize 1024
        scan $sz %d sz
    } elseif [string match *M $sz] {
        set psize 1048576
        scan $sz %d sz
    }

    set tm $ttime

    set meg [format %.1f [expr {$sz * $psize / 1048576.0}]]
    $mon.text insert end "Size = $meg Meg; time = $tm\n"
    if {($meg < 1) || ($meg > 4000)} {
        $mon.text insert end "Hmm, that can't be right...\n"
    }
    $mon.text yview -pickplace end
}
