#! /bin/sh
# the next line restarts using wish8.0 \
exec wish8.0 "$0" "$@"

# interface generated by SpecTcl version 1.1 from /usr2/people/ramsan/bin/specsamples/ProcWin.ui
#   root     is the parent window for this user interface

proc ProcWin_ui {root args} {

	# this treats "." as a special case

	if {$root == "."} {
	    set base ""
	} else {
	    set base $root
	}
	
    
	frame $base.frame#2 -relief groove -bd 3

	frame $base.frame#6

	frame $base.frame#1 -bd 2 -relief groove

	label $base.label#1 -text [_ "Project     Start time    UID"]
	listbox $base.listbox#1 \
		-height 8 \
		-width 40 \
		-xscrollcommand "$base.scrollbar#1 set" \
		-yscrollcommand "$base.scrollbar#2 set" -selectmode browse

	scrollbar $base.scrollbar#2 \
		-command [list $base.listbox#1 yview] \
		-orient v

	scrollbar $base.scrollbar#1 \
		-command [list $base.listbox#1 xview] \
		-orient h

	menu $base.runprocmenu
	bind $base.listbox#1 <1> "focus $base.listbox#1"
	bind $base.listbox#1 <3> "event generate $base.listbox#1 <1> -rootx %X -rooty %Y ; ShowRunprocMenu $base %X %Y"



	button $base.button#1 \
		-text [_ "Output view"] -width 10 -command [list PWViewOutput window]

	button $base.button#2 \
		-text [_ "Kill"] -width 10 -command [list PWKillProc window]

	button $base.button#4 -width 12 \
		-text [_ "Start"] -command ".central.s process escape escape escape \
		escape Utilities Calculate"

	focus $base.button#4 

	button $base.button#45 \
		-text [_ "Start remote"] -width 12 -command ".central.s process escape \
		escape escape \
		escape Utilities RemoteCalc"

	button $base.button#47 \
		-text [_ "Remote"]... -width 12 -command [list PWUpdate $base.update]


	button $base.button#5 \
		-text [_ "Close"] -width 12  -command [list destroy $base]


	# Geometry management

	grid $base.frame#2 -in $base.frame#1        -row 4 -column 1  \
		-sticky nw -padx 1 -pady 1
	grid $base.frame#6 -in $root        -row 3 -column 1 
	grid $base.frame#1 -in $root        -row 1 -column 1  \
		-sticky nesw -columnspan 2  -padx 3 -pady 3
	grid $base.label#1 -in $base.frame#1 -row 1 -column 1 \
		-sticky w -pady 3 -padx 3
	grid $base.listbox#1 -in $base.frame#1        -row 2 -column 1  \
		-sticky nesw
	grid $base.scrollbar#2 -in $base.frame#1        -row 2 -column 2  \
		-sticky ns
	grid $base.scrollbar#1 -in $base.frame#1        -row 3 -column 1  \
		-sticky ew
	grid $base.button#1 -in $base.frame#2        -row 1 -column 1   \
		-sticky w -padx 3
	grid $base.button#2 -in $base.frame#2        -row 1 -column 2  \
		-sticky w -padx 3
	grid $base.button#4 -in $base.frame#6        -row 1 -column 1  -padx 3
	grid $base.button#45 -in $base.frame#6        -row 1 -column 2  -padx 3
	grid $base.button#47 -in $base.frame#6        -row 1 -column 3  -padx 3
	grid $base.button#5 -in $base.frame#6        -row 1 -column 4  -padx 3

	# Resize behavior management

	grid rowconfigure $base.frame#6 1 -weight 0 
	grid columnconfigure $base.frame#6 1 -weight 1 
	grid columnconfigure $base.frame#6 2 -weight 1 

	grid rowconfigure $base.frame#2 1 -weight 0 
	grid columnconfigure $base.frame#2 1 -weight 1 
	grid columnconfigure $base.frame#2 2 -weight 1 

	grid rowconfigure $root 1 -weight 1 -pad 3
	grid rowconfigure $root 2 -weight 0 -pad 3
	grid rowconfigure $root 3 -weight 0 -pad 3
	grid columnconfigure $root 1 -weight 1 

	grid rowconfigure $base.frame#1 1 -weight 0 
	grid rowconfigure $base.frame#1 2 -weight 1 
	grid rowconfigure $base.frame#1 3 -weight 0 
	grid columnconfigure $base.frame#1 1 -weight 1 
	grid columnconfigure $base.frame#1 2 -weight 0 
}

proc ShowRunprocMenu { base X Y } {
    global GidProcWin RunProcInfo
    if { ![info exists RunProcInfo] } return
    if { ![info exists GidProcWin(w)] || \
	    ![winfo exists $GidProcWin(w).listbox#1] } {
	set wbase .gid
	set w ""
    } else {
	set wbase $GidProcWin(w)
	set w $GidProcWin(w).listbox#1
    }
    
    set i [$w curselection]
    if { $i < 0 } return

    $wbase.runprocmenu delete 0 end
    set state [lindex [lindex $RunProcInfo $i] 9]
    if { [lindex $state 0] == "RESULTSINSERVER" } {
	set name [lindex [lindex $RunProcInfo $i] 0]
	$wbase.runprocmenu add command -label [_ "Download results"] -command "update ; [list PWBeginCommand DOWNLOADRESULTS $name]"
	$wbase.runprocmenu add command -label [_ "Delete remote results"] -command "PWKillProc window"
    } else {
	$wbase.runprocmenu add command -label [_ "Output view"] -command "PWViewOutput window"
	$wbase.runprocmenu add command -label [_ "Kill"] -command "PWKillProc window"
    }

    tk_popup $wbase.runprocmenu $X $Y
}



proc PWUpdateDefaults { w } {
    global GidProcWin
    set retval [tk_dialogRAM $w.tempwinw [_ "defaults type"] \
		    [_ "Revert to user defaults or to program defaults?"] \
		    gidquestionhead 0 [_ "User"] [_ "Program"] [_ "Cancel"]]

    switch $retval {
	0 {
	    set GidProcWin(remoteauto) $GidProcWin(remoteautoold)
	    set GidProcWin(remotetime) $GidProcWin(remotetimeold)
	    set GidProcWin(remoteport) $GidProcWin(remoteportold)
	    set GidProcWin(remotetimeout) $GidProcWin(remotetimeoutold)
	    set GidProcWin(securemode) $GidProcWin(securemodeold)
	    set GidProcWin(remoteresultsdownload) $GidProcWin(remoteresultsdownloadold)
	    set GidProcWin(remoteresultsdelete) $GidProcWin(remoteresultsdeleteold)
	    
	}
	1 {
	    set GidProcWin(remoteauto) 1
	    set GidProcWin(remotetime) 10
	    set GidProcWin(remoteport) 2048
	    set GidProcWin(remotetimeout) 30
	    set GidProcWin(securemode) "BF"
	    set GidProcWin(remoteresultsdownload) "Automatic"
	    set GidProcWin(remoteresultsdelete) "Automatic"
	}
    }
}

proc PWUpdate { w } {
    global GidProcWin

    InitWindow $w [_ "Remote analysis properties"] ProcReportPropsWindowGeom

    if { ![info exists GidProcWin(remoteauto)] } {
	set GidProcWin(remoteauto) 1
    }
    if { ![info exists GidProcWin(remotetime)] } {
	set GidProcWin(remotetime) 10
    }
    if { ![info exists GidProcWin(remoteport)] } {
	set GidProcWin(remoteport) 2048
    }
    if { ![info exists GidProcWin(remotetimeout)] } {
	set GidProcWin(remotetimeout) 30
    }        


    set GidProcWin(remoteautoold) $GidProcWin(remoteauto)
    set GidProcWin(remotetimeold) $GidProcWin(remotetime)
    set GidProcWin(remoteportold) $GidProcWin(remoteport)
    set GidProcWin(remotetimeoutold) $GidProcWin(remotetimeout)
    set GidProcWin(securemodeold) $GidProcWin(securemode)
    set GidProcWin(remoteresultsdownloadold) $GidProcWin(remoteresultsdownload)
    set GidProcWin(remoteresultsdeleteold) $GidProcWin(remoteresultsdelete)

    framelabel $w.f1 [_ "Remote Options"]
    frame $w.f1.f1 -bd 2 -relief groove
    checkbutton $w.f1.f1.l -text [_ "Automatic remote update"] -var GidProcWin(remoteauto)
    label $w.f1.f1.l1 -text [_ "Every:"]
    entry $w.f1.f1.e -width 5 -textvar GidProcWin(remotetime)
    label $w.f1.f1.l2 -text [_ "sec"]

    GidHelp "$w.f1.f1.l $w.f1.f1.l1 $w.f1.f1.e $w.f1.f1.l2" [_ "If remote update is set, program will\
	    contact automatically with the sever one time every given seconds, to check if\
	    process has finished and also to get status information"]

    label $w.f1.f1.l3 -text [_ "Timeout:"]
    entry $w.f1.f1.e2 -width 5 -textvar GidProcWin(remotetimeout)
    label $w.f1.f1.l4 -text [_ "sec"]

    GidHelp "$w.f1.f1.l3 $w.f1.f1.e2 $w.f1.f1.l4" [_ "this is the time that program will wait for server to\
	    respond. After this time it will consider that connection has failed. Increase the\
	    time if your connection is slow."]

    grid $w.f1.f1.l -row 1 -column 1 -columnspan 3 -sticky w -pady 1
    grid $w.f1.f1.l1 -row 2 -column 1
    grid $w.f1.f1.e -row 2 -column 2 -sticky ew
    grid $w.f1.f1.l2 -row 2 -column 3
    grid $w.f1.f1.l3 -row 3 -column 1
    grid $w.f1.f1.e2 -row 3 -column 2 -sticky ew
    grid $w.f1.f1.l4 -row 3 -column 3
    grid columnconf $w.f1.f1 2 -weight 1

    frame $w.f1.f2 -bd 2 -relief groove

    label $w.f1.f2.l5 -text [_ "Port:"]
    entry $w.f1.f2.e3 -width 5 -textvar GidProcWin(remoteport)
    GidHelp "$w.f1.f2.l5 $w.f1.f2.e3" [_ "This is the connection port. Do not change it unless your are\
	    notified that your server use another port."]

    checkbutton $w.f1.f2.cbt -text [_ "Secure connection"] -var GidProcWin(securemode) \
	-onvalue "BF" -offvalue "NONE"
    GidHelp "$w.f1.f2.cbt" [_ "Check for a encryted secure connection with the server."]

    grid $w.f1.f2.l5 -row 1 -column 1
    grid $w.f1.f2.e3 -row 1 -column 2 -sticky ew
    grid $w.f1.f2.cbt -row 2 -column 1 -columnspan 3  -sticky w
    grid columnconf $w.f1.f2 2 -weight 1

    grid $w.f1.f1 $w.f1.f2 -sticky nsew
    grid columnconf $w.f1 "0 1" -weight 1
    
    framelabel $w.f2 [_ "Remote results"]
    frame $w.f2.f1 -bd 2 -relief groove
    frame $w.f2.f2 -bd 2 -relief groove
    label $w.f2.f1.lb1 -text [_ "Download"]
    radiobutton $w.f2.f1.rbt1 -text [_ "Automatic"] \
	  -variable GidProcWin(remoteresultsdownload) -value "Automatic" 
    radiobutton $w.f2.f1.rbt2 -text [_ "Manual"] \
	  -variable GidProcWin(remoteresultsdownload) -value "Manual" 
    GidHelp "$w.f2.f1.lb1 $w.f2.f1.rbt1 $w.f2.f1.rbt2" \
	    [_ "If automatic, when the analysis is finished, the results are automatically downloaded."]
    label $w.f2.f2.lb1 -text [_ "File Storage after download"]
    radiobutton $w.f2.f2.rbt1 -text [_ "Delete"] \
	  -variable GidProcWin(remoteresultsdelete) -value "Automatic" 
    radiobutton $w.f2.f2.rbt2 -text [_ "Mantain"] \
	  -variable GidProcWin(remoteresultsdelete) -value "Manual" 
    GidHelp  "$w.f2.f2.lb1 $w.f2.f2.rbt1 $w.f2.f2.rbt1" \
	    [_ "If automatic, after a download the results are automatically deleted from the server."]
    grid $w.f2.f1.lb1 -sticky w -pady 1 
    grid $w.f2.f1.rbt1 -sticky w -pady 1 
    grid $w.f2.f1.rbt2  -sticky w -pady 1 
    grid $w.f2.f2.lb1  -sticky w -pady 1 
    grid $w.f2.f2.rbt1 -sticky w -pady 1 
    grid $w.f2.f2.rbt2  -sticky w -pady 1 
    grid $w.f2.f1 $w.f2.f2 -sticky nsew
    grid columnconf $w.f2 "0 1" -weight 1

    framelabel $w.f3 [_ "Status"]
    label $w.f3.ltext -textvar GidProcWin(remotemessages) -height 3 -justify left -anchor nw
    grid $w.f3.ltext -column 1 -row 1 -sticky nsew -padx 2 -pady 2
    grid columnconf $w.f3 1 -weight 1
    grid rowconf $w.f3 1 -weight 1

    bind $w.f3.ltext <Configure> "after idle $w.f3.ltext conf -wraplength \[winfo width $w.f3.ltext]"
    
    set color_fondo [ CCGetRGB $w [ $w cget -background]]
    frame $w.buts -bd 0 -bg [CCColorActivo $color_fondo] 

    button $w.buts.un -text [_ "Update now"] -width 10 -command "ActualizeProcInfo force" -und 0
    button $w.buts.ok -text [_ "Defaults"]... -width 10 -command [list PWUpdateDefaults $w] -und 0
    button $w.buts.infoserver -text [_ "Info"]... -width 10 -command "PWMainRemoteCommand USERINFO" -und 0
    button $w.buts.close -text [_ "Close"] -width 10 -command [list destroy $w] -und 0
    focus $w.buts.ok

    bind $w <Alt-u> "tkButtonInvoke $w.buts.un"
    bind $w <Alt-d> "tkButtonInvoke $w.buts.ok"
    bind $w <Alt-c> "tkButtonInvoke $w.buts.close"
    bind $w <Escape> "tkButtonInvoke $w.buts.close"

    grid $w.buts.un $w.buts.ok $w.buts.infoserver $w.buts.close -padx 2 -pady 3

    set FramesSeparation [framelabelsep]
    grid $w.f1 -column 1 -row 1 -sticky ew -pady $FramesSeparation
    grid $w.f2 -column 1 -row 2 -sticky ew -pady $FramesSeparation
    grid $w.f3 -column 1 -row 3 -sticky ewns -pady [expr $FramesSeparation-4]
    grid $w.buts -column 1 -row 4 -sticky ewns
    grid columnconf $w 1 -weight 1
    grid rowconf $w 3 -weight 1
}

# type can be error or warning
proc PWViewOutputError { type w name time filename } {
    global tkPriv tcl_platform 

    if { $w == "" } { set w .gid.__viewoutputerror }

    if { $type == "error" } {
	InitWindow $w [_ "Process errors"] ProcViewOutputErrorWindowGeom "" "" 1
    } else {
	InitWindow $w [_ "Process warnings"] ProcViewOutputErrorWindowGeom "" "" 1
    }
    wm protocol $w WM_DELETE_WINDOW { }

    # The following command has been removed because if it is present
    # the dialog won't be posted if [winfo parent $w] is iconified.

    if { $tcl_platform(platform) == "windows" } {
	wm transient $w [winfo toplevel [winfo parent $w]]
    }

    frame $w.bot -relief raised -bd 1
    #pack $w.bot -side bottom -fill both
    frame $w.top -relief raised -bd 1
    #pack $w.top -side top -fill x -expand 1

    if { $type == "error" } {
	set text [_ "Process '%1\$s' started at %2\$s has finished with errors. Check data and run again" $name $time]
    } else {
	set text [_ "Process '%1\$s' started at %2\$s has finished correctly but has given warnings" $name $time]
    }

    label $w.msg -justify left -text $text \
	    -wraplength 75m -font BigFont

    pack $w.msg -in $w.top -side right -expand 1 -fill x -padx 3m -pady 3m
    label $w.bitmap -bitmap error
    pack $w.bitmap -in $w.top -side left -padx 3m -pady 3m

    frame $w.err
    text $w.err.t -xscrollcommand "$w.err.scrollbar#1 set" \
	    -yscrollcommand "$w.err.scrollbar#2 set" -width 20 -height 10

    $w.err.t del 1.0 end
    set f [open $filename r]
    while { ![eof $f] } {
	gets $f aa
	$w.err.t ins end $aa\n
    }
    close $f
    $w.err.t conf -state disabled
    bind $w.err.t <1> "focus $w.err.t"
    
    scrollbar $w.err.scrollbar#2 -command [list $w.err.t yview] -orient v
    scrollbar $w.err.scrollbar#1 -command [list $w.err.t xview] -orient h
    
    grid $w.err.t -row 1 -column 1 -sticky nesw
    grid $w.err.scrollbar#2 -row 1 -column 2 -sticky ns
    grid $w.err.scrollbar#1 -row 2 -column 1 -sticky ew
    grid columnconf $w.err 1 -weight 1
    grid rowconf $w.err 1 -weight 1


    grid $w.top -sticky ew
    grid $w.err -sticky nsew
    grid $w.bot -sticky ew
    grid columnconf $w 0 -weight 1
    grid rowconf $w 1 -weight 1

    grid remove $w.err


#      pack $w.err -side top -fill both -expand 1

    if { $type == "error" } {
	set text [_ "View errors"]
    } else {
	set text [_ "View warnings"]
    }

    proc PWViewOutputErrorFull { w } {
	wm geometry $w ""
	wm withdraw $w
	#pack $w.err -side top -fill both -expand 1
	grid $w.err
	$w.button0 conf -state disabled
	focus $w.button1
	update
	wm deiconify $w
	wm geometry $w +[winfo x $w]+[winfo y $w]
    }

    button $w.button0 -text $text  -width 11 -command [list PWViewOutputErrorFull $w]
    button $w.button1 -text [_ "Close"] -width 11 -command "set tkPriv(button) close"

    frame $w.default -relief sunken -bd 1
    raise $w.button0 $w.default
    pack $w.default -in $w.bot -side left -expand 1 -padx 3m -pady 2m

    pack $w.button0 -in $w.default -padx 2m -pady 2m
    pack $w.button1 -in $w.bot -side left -expand 1 \
	    -padx 3m -pady 2m

    bind $w.button0 <Return> "tkButtonInvoke $w.button0"
    bind $w.button1 <Return> "tkButtonInvoke $w.button1"
    bind $w <Escape> "tkButtonInvoke $w.button1"

    wm withdraw $w
    update idletasks
    
    # extrange errors with updates
    if { ![winfo exists $w] } { return 0}
    if { $w != ".gid.__viewoutputerror" } {
	set pare [winfo toplevel [winfo parent $w]]
	set x [expr [winfo x $pare]+[winfo width $pare ]/2- [winfo reqwidth $w]/2]
	set y [expr [winfo y $pare]+[winfo height $pare ]/2- [winfo reqheight $w]]
    } else {
	set x [expr [winfo screenwidth $w]/2 - [winfo reqwidth $w]/2 \
		- [winfo vrootx [winfo parent $w]]]
	set y [expr [winfo screenheight $w]/2 - [winfo reqheight $w]/2 \
		- [winfo vrooty [winfo parent $w]]]
    }
    if { $x < 0 } { set x 0 }
    if { $y < 0 } { set y 0 }
    WmGidGeom $w +$x+$y
    update

    if { [winfo exists $w] } { wm deiconify $w }

    catch { tkwait visibility $w }
    if { [winfo exists $w] } {
	focus $w.button0
	tkwait variable tkPriv(button)
    }

    if { [winfo exists $w] } {         
	destroy $w 
    }
}

# drives only for windows------------------------------------------|--------------|
#                                                                  v              v
# RunProcInfo: $basename $time $uid $outputfiles $errorfiles $warningfiles 
	#{$local_drives} {$net_drives}
# RunProcInfo (remote): $basename $time remote $outputfiles $errorfiles $warningfiles $server \
#                       $user $channel $state $dir $PT $args $timeaccess

# what can be: auto ; autoupdate ; firsttime ; force
proc ActualizeProcInfo { { what auto } } {

    global GidProcWin RunProcInfo tcl_platform
    after cancel ActualizeProcInfo

    if { $RunProcInfo == "" } return

    if { [info exists GidProcWin(w)] && [winfo exists $GidProcWin(w)] } {
	set w $GidProcWin(w)
    } else { 
	set w "" 
    }
    set namewin ".gid.tmpwin"
    if { $w != "" } {
	set namewin $w.tmpwin
    }

    set thereareremoteprocesses 0
    set ToDissapear ""
    set ipos 0
    foreach i $RunProcInfo {
	set uid [lindex $i 2]
	set name [file tail [lindex $i 0]]
	set state [lindex $i 9]
	if { $uid == "remote" } {                       
	    switch -glob $state {
		FINISHED* { set res 0 }
		RESULTSINSERVER* { set res 0 }
		ERROR* { set res 0 } 
		FILETOCLIENT* { set res 1 } 
		ENDFILETOCLIENT* { set res 1 } 
		FILETOSERVER* { set res 1 } 
		ENDFILETOSERVER* { set res 1 } 
		default {
		    if { $what == "force" } {
		        PWCheckIfAlive $namewin $name 2
		    } elseif { $what == "firsttime" } {
		        PWCheckIfAlive $namewin $name 1
		    } else {
		        PWCheckIfAlive $namewin $name 0
		    }
		    set res 1 
		    set thereareremoteprocesses 1
		}
	    }
	} elseif { $what != "firsttime" } {
	    set res [gidproc isalive $uid]
	} else {
	    set res [gidproc isalive $uid [lindex $i 1]]
	}

	if { $res == 0 } {
	    set time [lrange [clock format [lindex $i 1]] 0 3]
	    
	    set filenameserror [lindex $i 4]
	    set errorflag 0
	    if { $state != "ERROR" && [llength $filenameserror] != 0} {
		set filenameerror [lindex $filenameserror 0]
		if { [file exists "$filenameerror"] && \
		        [file size "$filenameerror"] > 0 } {
		    PWViewOutputError error $namewin $name $time "$filenameerror"
		    if { [ info procs EndGIDCalculation] != "" } { 
			if { $uid == "remote" } {  
			    EndGIDCalculation $name remote 1 $filenameerror
			} else {
			    EndGIDCalculation $name local 1 $filenameerror
			}
		    }
		    set errorflag 1
		    # note: windows drives are unset in RunProcInfoDeleteJob
		}
	    }

	    if { !$errorflag } {
		set filenameswarning [lindex [lindex $i 5] 0]
		if { [llength $filenameswarning] != 0 && [file exists $filenameswarning] && \
		        [file size $filenameswarning] > 0 } {
		    PWViewOutputError warning $namewin $name $time $filenameswarning
		    if { [ info procs EndGIDCalculation] != "" } { 
			if { $uid == "remote" } {  
			    EndGIDCalculation $name remote -1 $filenameswarning
			} else {
			    EndGIDCalculation $name local -1 $filenameswarning
			}
		    }
		} else {
		    set aa [.central.s info Project]
		    set ProjectName [lindex $aa 1]
		    if { [file extension $ProjectName] == ".gid" } {
		        set ProjectName [file root $ProjectName]
		    }
		    set basename [file tail $ProjectName]
      
		    if { $state == "ERROR" } {
		        set retval 0    
		    } elseif { $name == $basename } {  
		        #if { [winfo exists $w] }   
		        if { 0 } {
		            #not show message window, only show a warnline message
			    set msg [_ "Process '%1\$s' started at %2\$s has finished." $name $time]
		            ::GidUtils::SetWarnLine $msg
			    if { [ info procs EndGIDCalculation] != "" } { EndGIDCalculation $name local 0 "" }
		            ActualizeProcsListBox $w
		            if { $what == "autoupdate"} { set what "auto" }
		            set retval 0
		        } else {

			    catch {
				if { [.central.s info variable Sound] } {
				    playaudio [ file join $GIDDEFAULT audio Select2.wav]
				}
			    }

		            if { $uid == "remote" } {
		                if { [lindex $state 0] == "FINISHED" } {
				    set msg [_ "Remote process '%1\$s' started at %2\$s has finished." "$name" "$time"]
				    ::GidUtils::SetWarnLine $msg
		                    set retval [tk_dialogRAM $namewin [_ "Process info"] \
		                            $msg warning 0 [_ "OK"] [_ "Postprocess"]]
				    if { [ info procs EndGIDCalculation] != "" } { EndGIDCalculation $name remote 0 ""}
		                    
		                } elseif { [lindex $state 0] == "RESULTSINSERVER" } {
				    set msg [_ "Remote process '%1\$s' started at %2\$s has finished. Results stored in the server" "$name" "$time"]
				    ::GidUtils::SetWarnLine $msg
		                    set retval [tk_dialogRAM $namewin [_ "Process info"]  \
		                            $msg warning 0 [_ "OK"] [_ "Download"]]
				    if { [ info procs EndGIDCalculation] != "" } { EndGIDCalculation $name remote 0 ""}
		                } else {
				    set msg [_ "ActualizeProcInfo: Unexpected state=%s" $state)]
				    ::GidUtils::SetWarnLine $msg
		                    WarnWin $msg
				    if { [ info procs EndGIDCalculation] != "" } { EndGIDCalculation $name remote 1 ""}
		                    set retval 0
		                }                            
		            } else {
		                #local calculation
				set msg [_ "Process '%1\$s' started at %2\$s has finished." $name $time]
				::GidUtils::SetWarnLine $msg
		                set retval [tk_dialogRAM $namewin [_ "Process info"] \
		                        $msg warning 0 [_ "OK"] [_ "Postprocess"]]
				if { [ info procs EndGIDCalculation] != "" } { EndGIDCalculation $name local 0 ""}
		            }
		        }
		    } else {
		        if { [winfo exists $w] } {                       
		            #not show message window, only show a warnline message
			    set msg [_ "Process '%1\$s' started at %2\$s has finished." $name $time]
		            ::GidUtils::SetWarnLine $msg
			    if { [ info procs EndGIDCalculation] != "" } { EndGIDCalculation $name local 0 ""}
		            ActualizeProcsListBox $w
		            if { $what == "autoupdate"} { set what "auto" }
		            set retval 0
		        } else {
		            if { $uid == "remote" } {
		                if { [lindex $state 0] == "FINISHED" } {
				    set msg [_ "Remote process '%1\$s' started at %2\$s has finished." "$name" "$time"]
				    ::GidUtils::SetWarnLine $msg
		                    set retval [tk_dialogRAM $namewin [_ "Process info"] \
		                            $msg warning 0 [_ "OK"]]
				    if { [ info procs EndGIDCalculation] != "" } { EndGIDCalculation $name remote 0 ""}
		                    
		                } elseif { [lindex $state 0] == "RESULTSINSERVER" } {
				    set msg [_ "Remote process '%1\$s' started at %2\$s has finished. Results stored in the server" "$name" "$time"]
				    ::GidUtils::SetWarnLine $msg
		                    set retval [tk_dialogRAM $namewin [_ "Process info"]  \
		                            $msg warning 0 [_ "OK"]]
				    if { [ info procs EndGIDCalculation] != "" } { EndGIDCalculation $name remote 0 ""}
		                } else {
				    set msg [_ "ActualizeProcInfo: Unexpected state=%s" $state)]
				    ::GidUtils::SetWarnLine $msg
		                    WarnWin $msg
				    if { [ info procs EndGIDCalculation] != "" } { EndGIDCalculation $name remote 1 ""}
		                    set retval 0
		                }                            
		            } else {
		                #local calculation
				set msg [_ "Process '%1\$s' started at %2\$s has finished." $name $time]
				::GidUtils::SetWarnLine $msg
		                set retval [tk_dialogRAM $namewin [_ "Process info"] \
		                        $msg warning 0 [_ "OK"]]
				if { [ info procs EndGIDCalculation] != "" } { EndGIDCalculation $name local 0 ""}
		            }
		        }
		    }

		    if { $retval == 1 } {
		        if { [lindex $state 0] == "RESULTSINSERVER" } {
		            PWBeginCommand DOWNLOADRESULTS $name
		        } else {
		            .central.s process escape escape escape escape PostProcess
		        }
		    }
		}
		# note: windows drives are unset in RunProcInfoDeleteJob
	    }
	    if { [lindex $state 0] != "RESULTSINSERVER" } {
		lappend ToDissapear $name
	    }
	} else {
	    if { $what == "firsttime" && $uid != "remote" } {
		set time [lrange [clock format [lindex $i 1]] 0 3]
		set namewin ".gid.tmpwin"
		if {$w != ""} {
		    set namewin $w.tmpwin
		}
		set msg [_ "Process '%1\$s' started at %2\$s is still running." $name $time]
		::GidUtils::SetWarnLine $msg
		tk_dialogRAM $namewin [_ "Process info"] \
			$msg info 0 [_ "OK"]   
	    }
	}

       incr ipos
    }

    foreach name $ToDissapear {
	RunProcInfoDeleteJob $name
    }

    if { ($what == "autoupdate" || $ToDissapear != "") && $w != "" } {
	ActualizeProcsListBox $w
    }
    set CalculationNotFinished 0
    
    foreach i $RunProcInfo {
	set state [lindex $i 9]
	if { [lindex $state 0] != "RESULTSINSERVER" } {                
	    set CalculationNotFinished 1
	    break
	}
    }
    

    if { $CalculationNotFinished } {
	if { ![info exists GidProcWin(nexttime)] } {
	    set GidProcWin(nexttime) 0.5
	}
	set GidProcWin(nexttime) [expr $GidProcWin(nexttime)*1.1]
	if { $GidProcWin(nexttime) > 3 } { set GidProcWin(nexttime) 3 }
	after [expr int(1000*$GidProcWin(nexttime))] "ActualizeProcInfo auto"
    }

    if { !$thereareremoteprocesses && $what == "force" } {
	WarnWin [_ "There are no remote processes to update"]
    }
}

proc ActualizeProcInfoBegin {} {
    global RunProcInfo GidProcWin
   
    if { [info exists GidProcWin(Called_ActualizeProcInfoBegin)] } {
	ActualizeProcInfo auto
    } else {
	set GidProcWin(Called_ActualizeProcInfoBegin) 1 ;#to avoid reenter
	set ipos 0
	foreach i $RunProcInfo {
	    set uid [lindex $i 2]
	    if { $uid == "remote" } {
		set state [lindex $i 9]
		if {[lindex $state 0] != "FINISHED" && 
		    [lindex $state 0] != "ERROR" && 
		    [lindex $state 0] != "RESULTSINSERVER"} {
		    set state "EXECUTING"
		}
		set newi [lreplace $i 8 9 "" $state]
		set RunProcInfo [lreplace $RunProcInfo $ipos $ipos $newi]
	    }
	    incr ipos
	}
	ActualizeProcInfo firsttime
	#unset GidProcWin(Called_ActualizeProcInfoBegin) ;#to reenter
    }
}

proc ActualizeProcsListBox { w } {
    global RunProcInfo
    if { ![winfo exists $w] } { return }
    if { $w == ".gid" } { return }

    $w.listbox#1 del 0 end
    foreach i $RunProcInfo {
	set name [file tail [lindex $i 0]]
	set time [lrange [clock format [lindex $i 1]] 0 3]
	set uid [lindex $i 2]
	set state [lindex $i 9]
	if { [lindex $state 0] == "RESULTSINSERVER" } {
	    set status [_ "results stored in server"]
	} elseif { [lindex $state 0] == "DELETING" } {
	    set status [_ "deleting remote results"]...
	} elseif { [lindex $state 0] == "FILETOCLIENT" || 
	    [lindex $state 0] == "ENDFILETOCLIENT" || 
	    [lindex $state 0] == "DOWNLOADRESULTS" } {
	    set status [_ "downloading results"]...
	} elseif { [lindex $state 0] == "FILETOSERVER" || 
	    [lindex $state 0] == "ENDFILETOSERVER" || 
	    [lindex $state 0] == "DOWNLOADRESULTS" } {
	    set status [_ "uploading data"]...
	} else {
	    set status [_ "Calculating"]...
	}

	$w.listbox#1 ins end [format "%20s %20s %s %s" $name $time $uid $status]
    }
}

#return 0 if continue quit, 1 if cancel quit
proc PWQuittingGiD {} {
    global RunProcInfo done

    if { ![info exist RunProcInfo] || $RunProcInfo == "" } { return 0 }

    set runninglocal 0
    set comunicatingremote 0
    set runningremote 0
    set storedremote 0   

    set done 0
    while { !$done } {
	set runninglocal 0
	set comunicatingremote 0
	set runningremote 0
	set storedremote 0
	foreach i $RunProcInfo {
	    set uid [lindex $i 2]
	    if { $uid == "remote" } {
		set channel [lindex $i 8]
		set state [lindex $i 9]
		if { $channel != "" } {
		    if { [string match *EXECUTING* $state] } {
		        CloseChannel $channel
		        incr runningremote
		    } elseif { $state == "RESULTSINSERVER" } {
		        CloseChannel $channel
		        incr storedremote
		    } else {
		        incr comunicatingremote
		    }
		} else {
		    if { $state == "RESULTSINSERVER" } {
		        incr storedremote
		    } else {
		        incr runningremote
		    }
		}
	    } else {
		incr runninglocal
	    }

	}
	if { $comunicatingremote } {
	    set res [tk_dialogRAM .gid.tempwinpr [_ "Processes"] \
		         [_ "There are %d processes comunicating with server. If you quit, you may loose some processes. Do you want to wait some seconds?" \
		            $comunicatingremote]
		         gidquestionhead 0 [_ "Wait"] [_ "Quit"] [_ "Cancel"]]
	    if { $res == 0 } {
		after 3000 set done 0
		vwait done
		set done 0
	    } elseif { $res == 1 } { 
		return 0
	    } else {
		return 1
	    }
	} else { set done 1 }
    }

    if { $runninglocal || $runningremote } {
	set msg "There are "
	if { $runninglocal } {
	    append msg [_ "%d processes running. " $runninglocal]
	}
	if { $runningremote } {
	    append msg [_ "%d remote processes running. " $runningremote]
	}    
	append msg [_ "Kill them?"]
	
	set res [tk_dialogRAM .gid.tempwinpr [_ "Processes"] $msg \
		gidquestionhead 1 [_ "Yes"] [_ "No"] [_ "Cancel"]]
	
	if { $res == 0 } { 
	    PWKillAllProc
	} elseif { $res == 1 } { 
	    return 0
	} else {
	    return 1
	}
    }

    return 0
}

proc PWKillAllProc {} {
    global RunProcInfo tcl_platform

    if { ![info exists RunProcInfo] } {
	set RunProcInfo ""
    }
    foreach i $RunProcInfo {
	set uid [lindex $i 2]
	set name [file tail [lindex $i 0]]
	if { $uid == "remote" } {
	    PWBeginCommand KILLINGFORCE $name            
	} else {
	    gidproc kill $uid
	}
	if { $uid != "remote" && "$tcl_platform(platform)" == "windows"} {
	    set drives [ lindex $i 6]
	    set local_drives [ lindex $drives 0]
	    set net_drives [ lindex $drives 1]
	    foreach i $local_drives {
		set res [gidproc unsetdrive $i]
		if { "$res" != ""} {
		    WarnWin [_ "unsetdrive %1\$s: - %2\$s" $i $res]
		}
	    }
	    foreach i $net_drives {
		set res [gidproc unsetnetdrive $i]
		if { "$res" != ""} {
		    WarnWin [_ "unsetnetdrive %1\$s: - %2\$s" $i $res]
		}
	    }
	} else {
	    # nothing
	}
    }
    set RunProcInfo ""
}

# what can be: current or window
proc PWKillProc { { what current } } {
    global GidProcWin RunProcInfo tcl_platform

    if { ![info exists RunProcInfo] } {
	set RunProcInfo ""
    }
    
    if { [info exists GidProcWin(w)] && [winfo exists $GidProcWin(w).listbox#1] } {
	set wbase $GidProcWin(w)
	set w $GidProcWin(w).listbox#1
    } else {
	set wbase .gid
	set w ""
    }
    
    if { [llength $RunProcInfo] == 0 } {
	tk_dialogRAM $wbase.tempwin [_ "Error window"] \
	    [_ "There are no processes running."] gidquestionhead 0 [_ "OK"]
	return
    }
    
    set ToDissapear ""
    
    if { $what == "current" } {
	set aa [.central.s info Project]
	set ProjectName [lindex $aa 1]
	if { [file extension $ProjectName] == ".gid" } {
	    set ProjectName [file root $ProjectName]
	}
	set basename [file tail $ProjectName]
	foreach i $RunProcInfo {
	    set name [file tail [lindex $i 0]]
	    if { $name == $basename } {
		set ToDissapear $name
		break
	    }
	}
	if { $ToDissapear == "" } {
	    if { [llength $RunProcInfo] == 0 } {
		tk_dialogRAM $wbase.tempwin [_ "Error window"] \
		    [_ "Current project '%s' is not running." $basename] \
		    gidquestionhead 0 [_ "OK"]
	    } else {
		tk_dialogRAM $wbase.tempwin [_ "Error window"] \
		    [_ "Current project '%s' is not running. To kill other processes use the Calculate window" \
		        $basename] \
		    gidquestionhead 0 [_ "OK"]
	    }
	    return
	}
    } else {
	if { [$w size] == 1 } { $w sel set 0}
	for { set i 0 } { $i < [$w size] } { incr i } {
	    if { [$w sel includes $i] } {
		set aa [$w get $i]
		set name [string trim [string range $aa 0 19]]
		set ii 20
		while { [string index $aa $ii] != " " } { 
		    append name [string index $aa $ii]
		    incr ii
		}
		lappend ToDissapear $name
	    }
	}
	if { $ToDissapear == "" } {
	    tk_dialogRAM $wbase.tmpwin [_ "error"] [_ "Please, select a process first."] \
		error 0 [_ "OK"]
	    return
	}
    }
    
    set ReallyDead ""
    foreach i $ToDissapear {
	foreach j $RunProcInfo {
	    set name [file tail [lindex $j 0]]
	    if { $i == $name } {
		set uid [lindex $j 2]
		set time [lrange [clock format [lindex $j 1]] 0 3]
		set state [lindex $j 9]
		if { [lindex $state 0] == "RESULTSINSERVER" } {
		    set msg [_ "Are you sure you want to delete the remote results of process: '%1\$s' started at %2\$s ?" $name $time]
		} else {
		    set msg [_ "Are you sure you want to kill the process: '%1\$s' started at %2\$s ?" $name $time]
		}
		set ret [tk_dialogRAM $wbase.tempwin [_ "Dialog window"] $msg gidquestionhead 1 [_ "Yes"] [_ "No"]]
		if { $ret == 0 } {                        
		    if { $uid == "remote" } {
		        PWBeginCommand KILLING $name                        
		    } else {
		        gidproc kill $uid
		        lappend ReallyDead $name
		    }
		}
		break
	    }
	}
    }
    if { $ReallyDead != "" } {
	set state [lindex $j 9]
	set text ""
	foreach i $ReallyDead {
	    RunProcInfoDeleteJob $i
	    append text " '$i'"
	}     
	if { [lindex $state 0] == "RESULTSINSERVER" } {
	    set text [_ "Deleted results of  process:%s" $text]
	} else {
	    set text [_ "Killed process:%s" $text]
	}                   
	tk_dialogRAM $wbase.namewin [_ "Process info"] $text warning 0 [_ "OK"]
    }
    ActualizeProcInfo auto
    if { [info exists GidProcWin(w)] && [winfo exists $GidProcWin(w).listbox#1] } {
	ActualizeProcsListBox $GidProcWin(w)
    }
}

proc PWViewOutputFill { text fd filename { actualizar 1}} {
    global tcl_platform GidProcWin

    if { ![winfo exists $text] } { 
	catch { close $fd }
	return 
    }
    if { $fd == "" } {
	set JustOpen 1
	if { [catch { set fd [open $filename r] } ] } {
	    set fd ""
	} else {
	    bind $text <Destroy> "catch [list close $fd]"
	    $text del 1.0 end
	}
    } else { set JustOpen 0 }

    if { $fd != "" } {
	set textinserted 0
	set aa [gets $fd]
	while { ![fblocked $fd] && ![eof $fd]} {
	    set textinserted 1
	    $text ins end "$aa\n"
	    set aa [gets $fd]
	    if { $tcl_platform(platform) != "windows"} {
		if { ![info exists GidProcWin(tempstopupdates)] || $GidProcWin(tempstopupdates) == 0  } {
		    $text see end
		}
	    }
	}
	if { ($tcl_platform(platform) == "windows") && ($textinserted == 1)} {
	    if { ![info exists GidProcWin(tempstopupdates)] || $GidProcWin(tempstopupdates) == 0  } {
		$text see end
	    }
	}
	if { $JustOpen && !$textinserted } {
	    close $fd
	    set fd ""
	} else {
	    update idletasks
	}
    }
    if { $actualizar} {
	after 100 [list PWViewOutputFill $text $fd $filename ]
    }
}

proc PWViewOutputWin { filename name date { basename "" } { actualizar 1} } {
    global GidProcWin

    set title [_ "output info for '%1\$s' %2\$s" $name $date]

    set geom ""
    set inum 1
    while { [winfo exists ._outputview$inum] } { 
	if { [wm title ._outputview$inum] == $title } {
	    raise ._outputview$inum
	    return
	}
	set geom +[expr {[winfo rootx ._outputview$inum]+40}]
	append geom +[expr {[winfo rooty ._outputview$inum]+40}]
	incr inum
    }

    set w ._outputview$inum

    if { ![winfo exists $w] } {
	InitWindow $w $title ProcOutput${inum}WindowGeom

	if { $geom != "" } { wm geometry $w $geom }

	text $w.t -xscrollcommand "$w.scrollbar#1 set" \
		-yscrollcommand "$w.scrollbar#2 set" -font FixedFont

	scrollbar $w.scrollbar#2 -command [list $w.t yview] -orient v
	scrollbar $w.scrollbar#1 -command [list $w.t xview] -orient h

	bind $w.scrollbar#2 <ButtonPress-1> "set GidProcWin(tempstopupdates) 1"
	bind $w.scrollbar#1 <ButtonPress-1> "set GidProcWin(tempstopupdates) 1"
	bind $w.scrollbar#2 <ButtonRelease-1> "set GidProcWin(tempstopupdates) 0"
	bind $w.scrollbar#1 <ButtonRelease-1> "set GidProcWin(tempstopupdates) 0"

	frame $w.buts
	button $w.close -text [_ "Close"] -width 6 -command [list destroy $w]
	if { $basename != "" } {
	    button $w.update -text [_ "Update"] -width 6 -command \
		    [list PWCheckIfAlive $w.tmpwin $basename 2]
	    pack $w.update -in $w.buts -side right
	}
	pack $w.close -in $w.buts
	focus $w.close
	grid $w.t -row 1 -column 1 -sticky nesw
	grid $w.scrollbar#2 -row 1 -column 2 -sticky ns
	grid $w.scrollbar#1 -row 2 -column 1 -sticky ew
	grid $w.buts -row 3 -column 1 -rowspan 2 -pady 5
	grid rowconfigure $w 1 -weight 1 
	grid columnconfigure $w 1 -weight 1 
    }
    PWViewOutputFill $w.t "" $filename $actualizar

}

# what can be: current or window
proc PWViewOutput { { what current } } {
    global GidProcWin GIDDEFAULT RunProcInfo

    if { ![info exists RunProcInfo] } {
	set RunProcInfo ""
    }

    if { ![info exists GidProcWin(w)] || \
	    ![winfo exists $GidProcWin(w).listbox#1] } {
	set wbase .gid
	set w ""
    } else {
	set wbase $GidProcWin(w)
	set w $GidProcWin(w).listbox#1
    }

    if { $what == "current" } {
	set aa [.central.s info Project]
	set ProjectName [lindex $aa 1]
	if { [file extension $ProjectName] == ".gid" } {
	    set ProjectName [file root $ProjectName]
	}
	set basename [file tail $ProjectName]
	set uid ""

	foreach i $RunProcInfo {
	    set name [file tail [lindex $i 0]]
	    if { $name == $basename } {
		set filenames [lindex $i 3]
		set uid [lindex $i 2]
		set time [lindex $i 1]
		break
	    }
	}
	if { $uid == "" } {
	    set filenames [PWFIndOutputFilenameCurrent]
	}
	if { $filenames == "" } {
	    tk_dialogRAM $wbase.tmpwin [_ "error"] \
		[_ "There is no information to visualize for current project '%s'." $basename] \
		error 0 [_ "OK"]
	    return
	}
	set index 0
	foreach filename $filenames {
	    if { $uid == "" && ![file exists $filename] } {
		tk_dialogRAM $w.tmpwin [_ "error"] \
		    [_ "There is no information to visualize for current project."] \
		    error 0 [_ "OK"]
		return
	    }
	    set name current
	    if {$index > 0} {
		set name "$name-$index"
	    }
	    if { $uid == "" } {
		PWViewOutputWin $filename $name ""
	    } elseif { $uid == "remote" } {
		PWViewOutputWin $filename $name \
		        [lrange [clock format [list $time]] 0 3] $basename
	    } else {
		PWViewOutputWin $filename $name [lrange [clock format [list $time]] \
		        0 3] ""
	    }
	    incr index
	}
	return
    }

    if { [llength $RunProcInfo] == 0 } {
	tk_dialogRAM $wbase.tempwin [_ "Error window"] \
	    [_ "There are no processes running."] gidquestionhead 0 [_ "OK"]
	return
    }

    set inum 0
    if { [$w size] == 1 } { $w sel set 0}
    for { set i 0 } { $i < [$w size] } { incr i } {
	if { [$w sel includes $i] } {
	    incr inum
	    set aa [$w get $i]
	    set name [string trim [string range $aa 0 19]]
	    set ii 20
	    while { [string index $aa $ii] != " " } { 
		append name [string index $aa $ii]
		incr ii
	    }
	    set filenames ""
	    foreach j $RunProcInfo {
		set namein [file tail [lindex $j 0]]
		if { [string comp $namein $name] == 0 } {
		    set filenames [lindex $j 3]
		    set uid [lindex $j 2]
		    set time [lindex $j 1]
		    break
		}
	    }
	    if { $filenames == "" } {
		tk_dialogRAM $wbase.tmpwin [_ "error"] \
		    [_ "There is no information to visualize for project '%s'." $name] \
		    error 0 [_ "OK"]
		continue
	    }
	    set index 0
	    foreach filename $filenames {
		if {$index > 0} {
		    set name "$name-$index"
		}
		if { $uid == "remote" } {
		    PWViewOutputWin $filename $name [lrange [clock format \
		            [list $time]] 0 3] $name
		} else {
		    PWViewOutputWin $filename $name [lrange [clock format \
		            [list $time]] 0 3] ""
		}
		incr index
	    }
	}
    }
    if { $inum == 0 } {
	tk_dialogRAM $wbase.tmpwin [_ "error"] [_ "Please, select a process first."] \
	    error 0 [_ "OK"]
	return
    }
}

proc PWFIndOutputFilename { word batfile basename directory ProblemDirectory } {
    global GIDDEFAULT
    global tcl_platform

    set GiDpath [file join $GIDDEFAULT gid]
    set aa [.central.s info Project]
    set ProjectName [lindex $aa 1]
    if { [file extension $ProjectName] == ".gid" } {
    set ProjectName [file root $ProjectName]
    }

    set fd [open $batfile r]
    set filename ""
    set filenames [list ]

    set regexp [format {%s:[ ]+([^ ]*).*$} [string toupper $word]]

    regsub -all {\\} $directory {\\\\} directory
    while { ![eof $fd] } {
	gets $fd aa
	if { [regexp -nocase $regexp $aa trash filename] } {
	    
	    if { $filename == "" } { return "" }

	    if { $::tcl_platform(platform) == "windows" } {
		set filename [string map [list %1 $basename] $filename]
		set filename [string map [list %2 $directory] $filename]
		set filename [string map [list %3 $ProblemDirectory] $filename]
		set filename [string map [list %4 $GiDpath] $filename]
	    } else {
		set filename [string map [list \$1 $basename] $filename]
		set filename [string map [list \$2 $directory] $filename]
		set filename [string map [list \$3 $ProblemDirectory] $filename]
		set filename [string map [list \$4 $GiDpath] $filename]
	    }
	    
	    set filename "[string trim $filename \"]"
	    if { [file pathtype [list $filename]] == "relative" } {
		set filename [file join $ProjectName.gid $filename]
	    }
	    if { [file pathtype $filename] == "relative" } {
		set filename [file join [pwd] $filename]
	    }
	    # Transform filename to native path style
	    set filename [file native $filename]
	    set filenames [linsert $filenames end "$filename"]
	}
    }
    close $fd
    return $filenames
}

proc PWFIndOutputFilenameCurrent {} {
    global GIDDEFAULT tcl_platform

    set aa [.central.s info Project]
    set ProblemType [lindex $aa 0]
    set ProjectName [lindex $aa 1]
    if { [file extension $ProjectName] == ".gid" } {
    set ProjectName [file root $ProjectName]
    }
    
    set basename [file tail $ProjectName]

    if { $ProblemType == "UNKNOWN" } {
	return ""
#          tk_dialogRAM .gid.tmpwin error "Select first one Problem type" \
#                  error 0 OK
#          return
    }

    set ProblemDirectory $ProblemType.gid

    if { ![file isdirectory $ProblemDirectory] } {
	set ProblemDirectory [file join $GIDDEFAULT problemtypes $ProblemType.gid]
    }
    if { ![file isdirectory $ProblemDirectory] } {
	set ProblemDirectory [file join $GIDDEFAULT $ProblemType.gid]
    }
    
    if { [file pathtype $ProblemDirectory] == "relative" } {
	set ProblemDirectory [file join [pwd] $ProblemType.gid]
    } 

    if { ![file isdirectory $ProblemDirectory] } {
	return ""
#          tk_dialogRAM .gid.tmpwin error "Problem type '$ProblemType' can't be found" \
#                  error 0 OK
#          return
    }

    if { $ProjectName == "UNNAMED" } {
	return ""
#          tk_dialogRAM .gid.tmpwin error \
#                  "Before calculating, a project title is needed. Save project to get it" \
#                  error 0 OK
#          return
    }

    set directory $ProjectName.gid
    if { [file pathtype $directory] == "relative" } {
	set directory [file join [pwd] $directory]
    }

    set args ""

    set list ""
    catch {set list [SelectGIDBatFile $directory $basename]}
    if {$list != ""} {
	set file [file native  [file join $ProblemDirectory [lindex $list 0]]]
	# if " is added, an argument list will be treated as one argument 
	set args [lrange $list 1 end]

    }
    if {$list == ""} {
	set file ""        
	if { $tcl_platform(platform) == "windows" } {
	    set tmpfile [file native [file join $ProblemDirectory \
		        [file tail $ProblemType].win.bat]]
	    if { [file exists $tmpfile] } {
		set file $tmpfile
	    }
	} else {
	    set tmpfile [file native [file join $ProblemDirectory \
		        [file tail $ProblemType].unix.bat]]
	    if { [file exists $tmpfile] } {
		set file $tmpfile
	    }
	}
	if { $file == "" } {
	    set file [file native  [file join $ProblemDirectory [file tail $ProblemType].bat]]
	}       
	set args ""
    }
    set outfilenames [PWFIndOutputFilename OutputFile $file $basename \
	    $directory $ProblemDirectory]
    return $outfilenames
}

proc PWStartProc { { isremote 0} } {
    global GidProcWin RunProcInfo GIDDEFAULT tcl_platform env

    if { [info exists GidProcWin(w)] && [winfo exists $GidProcWin(w)]} {
	set w $GidProcWin(w)
    } else { set w .gid }
    set aa [.central.s info Project]
    set ProblemType [lindex $aa 0]
    set ProjectName [lindex $aa 1]
    if { [file extension $ProjectName] == ".gid" } {
    set ProjectName [file root $ProjectName]
    }
    
    set basename [file tail $ProjectName]

    if { $ProjectName == "UNNAMED" } {
	tk_dialogRAM $w.tmpwin [_ "error"] \
	    [_ "Before calculating, a project title is needed. Save project to get it"] \
	    error 0 [_ "OK"]
	return
    }


     if { $ProblemType == "UNKNOWN" } {
	 tk_dialogRAM $w.tmpwin [_ "error"] \
	     [_ "In order to perform a calculation, a problemtype must be loaded. Use Data->Problemtypes."] \
	     error 0 [_ "OK"]
	return
    }

    set ProblemDirectory $ProblemType.gid

    if { ![file isdirectory $ProblemDirectory] } {
	set ProblemDirectory [file join $GIDDEFAULT problemtypes $ProblemType.gid]
    }
    if { ![file isdirectory $ProblemDirectory] } {
	set ProblemDirectory [file join $GIDDEFAULT $ProblemType.gid]
    }
    
    if { [file pathtype $ProblemDirectory] == "relative" } {
	set ProblemDirectory [file join [pwd] $ProblemType.gid]
    } 

    if { ![file isdirectory $ProblemDirectory] } {
	tk_dialogRAM $w.tmpwin [_ "error"] \
	    [_ "Problem type '%s' can't be found" $ProblemType]\
	    error 0 [_ "OK"]
	return
    }

    set directory $ProjectName.gid
    if { [file pathtype $directory] == "relative" } {
	set directory [file join [pwd] $directory]
    }

    set gidexecutable [info nameofexecutable]

    if { ![.central.s info variables CalcWithoutMesh] } {
	if { [lindex [.central.s info Mesh] 0] == 0 } {
	    tk_dialogRAM $w.tmpwin [_ "error"] \
		    [_ "Don't forget to generate the mesh"] \
		    error 0 [_ "OK"]
	    return
	}
    }

    if { [info exists RunProcInfo] } {
	set ipos 0
	foreach i $RunProcInfo {
	    if { $basename == [lindex $i 0] } {
		if { [lindex $i 9] == "RESULTSINSERVER" } {                    
		    set RunProcInfo [lreplace $RunProcInfo $ipos $ipos]
		    ActualizeProcInfo autoupdate
		    #PWBeginCommand KILLINGFORCE $basename
		} else {
		    tk_dialogRAM $w.tmpwin [_ "error"] [_ "This problem is already running"] \
		            error 0 [_ "OK"]
		    return
		}
	    }
	    incr ipos
	}
    }

    set oldfocus [focus]
    mkDialog $w.calc [list -text [_ "Initializing process. Wait, please"]... -aspect 250 \
		-justify left]  [list [_ "Stop"] ""]
    update 

    set DefaultFileNAmeInCalcFile \
	    [.central.s info variables DefaultFileNAmeInCalcFile]
    if { $DefaultFileNAmeInCalcFile == 0 } {
	.central.s process escape escape escape escape utilities variables \
		DefaultFileNAmeInCalcFile 1 escape
    }

    .central.s process escape escape escape escape files WriteCalcFile

    if { $DefaultFileNAmeInCalcFile == 0 } {
	.central.s process escape escape escape escape utilities variables \
		DefaultFileNAmeInCalcFile 0 escape
    }

    if { [ winfo exist $w.calc]} {
	destroy $w.calc
    }

    focus -force $oldfocus

    set LastOutCalcFailFlag [.central.s info LastOutCalcFailFlag]
    if { $LastOutCalcFailFlag != 0 } {
	tk_dialogRAM $w.tmpwin [_ "Error"] \
	    [_ "Error running process."] \
	    error 0 [_ "OK"]
	return
    }

    set args ""

    set list ""
    catch {set list [SelectGIDBatFile $directory $basename]}
    if {$list != ""} {
	set file [file native [file join $ProblemDirectory [lindex $list 0]]]
	# if " is added, an argument list will be treated as one argument "
	set args [lrange $list 1 end]
    }

    if {$list == ""} {
	set file ""        
	if { $tcl_platform(platform) == "windows" } {
	    set tmpfile [file native [file join $ProblemDirectory \
		        [file tail $ProblemType].win.bat]]
	    if { [file exists $tmpfile] } {
		set file $tmpfile
	    }
	} else {
	    set tmpfile [file native [file join $ProblemDirectory \
		        [file tail $ProblemType].unix.bat]]
	    if { [file exists $tmpfile] } {
		set file $tmpfile
	    }
	}
	if { $file == "" } {
	    set file [file native  [file join $ProblemDirectory [file tail $ProblemType].bat]]
	}       
	set args ""
    }

    if { [catch {
	set outfilenames [PWFIndOutputFilename OutputFile $file $basename \
		$directory $ProblemDirectory]
	if { $outfilenames != "" } {
	    foreach f $outfilenames {
		file delete $f
	    }
	}
	set outfilenameserror [PWFIndOutputFilename ErrorFile $file \
		$basename $directory $ProblemDirectory]
	if { $outfilenameserror != "" } {
	    foreach f $outfilenameserror {
		file delete $f
	    }
	}
	set outfilenameswarning [PWFIndOutputFilename WarningFile $file \
		$basename $directory $ProblemDirectory]
	if { $outfilenameswarning != "" } {
	    foreach f $outfilenameswarning {
		file delete $f
	    }
	}
    } err] } {
	WarnWin [_ "Error deleting old file (%s). Correct the problem and execute again" $err]
	return
    }
    set olddir [pwd]
    cd $directory
    if { !$isremote && [file exists [file join $ProblemDirectory password.txt]] } {
	file copy -force [file join $ProblemDirectory password.txt] .
    }
    set AnexoRunProcInfo ""
    if { $isremote } {

	set res [PWCalcRemote $w.calremote "$basename" "$directory" \
		$ProblemType $args]
	set AnexoRunProcInfo [lrange $res 2 end]
	set res [lrange $res 0 1]

    } elseif { $tcl_platform(platform) != "windows" } {
	if { [info procs InitGIDCalculation] != "" } { 
	    InitGIDCalculation $file $basename $directory $problem_dir $gidexecutable $args
	}
	set res [gidproc exec "$file" "$basename" "$directory" \
		"[file native $ProblemDirectory]" "$gidexecutable" $args]
    } else {

	set directory [ file native $directory]
	set gidexecutable [file native $gidexecutable]
	set problem_dir [file native $ProblemDirectory]
	set local_drives ""
	set net_drives ""
	if { [file exists [file join $GIDDEFAULT command.exe]] } {
	    set usedrives 0
	} else { set usedrives 1 }

	if { $usedrives } {
	    # Como el tamano(commandline) < 128
	    # hemos de subst disco: $basename
	    # hemos de subst disco: problem_dir
	    set res [gidproc getvolumes]
	    regsub -all {:\\} $res {} drives
	    set net_drives ""
	    set local_drives ""

	    set net_proj_dir ""
	    # foreach i { z y x w v u t s r q p o n m l k j i h g f e d c b a 0} 
	    foreach i { e f g h i j k l m n o p q r s t u v w x y z 0} {
		if { [ string first $i $drives] == -1} {
		    break
		}
	    }
	    if { "$i" == "0"} {
		WarnWin [_ "Sorry but, couldn't find a free drive letter."]
		cd $olddir
		return
	    }
	    set proj_drv $i
	    lappend drives $i

	    #el directorio del proyecto es un directorio de red?
	    set directory [ file native $directory]
	    if { "[ string range $directory 0 1]" == "\\\\"} {
		set recurso "$directory"
		if { ![ regexp {^(\\\\[^\\]+\\[^\\]+)\\(.*)} $recurso dumm net_dir resto]} {
		    #WarnWin "$directory is not a valid net path."
		    WarnWin [_ "Sorry, but couldn't use '%s' as project directory to calculate." $recurso]
		    cd $olddir
		    return
		}

		set net_proj_dir $net_dir
		set res [ gidproc setnetdrive $proj_drv "$net_dir"]
		if { "$res" != ""} {
		    WarnWin [_ "setnetdrive %1\$s: '%2\$s' - %3\$s" $proj_drv $net_dir $res]
		    cd $olddir
		    return
		}

		lappend net_drives $proj_drv
		set directory [ file native "$proj_drv:/$resto"]

		#WarnWin "[ pwd] -> cd $directory"

		cd $directory
	    } else {
		set res [gidproc setdrive $proj_drv "[ file dirname $directory]"]
		if { "$res" != ""} {
		    WarnWin [_ "setdrive %1\$s: '%2\$s' - %3\$s" $proj_drv [file dirname $directory] $res]
		    cd $olddir
		    return
		}
		lappend local_drives $proj_drv
		set directory [ file native "$proj_drv:/[ file tail $directory]"]
	    }

	    set problem_dir [file native $ProblemDirectory]
	    # foreach i { z y x w v u t s r q p o n m l k j i h g f e d c b a 0} 
	    foreach i { e f g h i j k l m n o p q r s t u v w x y z 0} {
		if { [ string first $i $drives] == -1} {
		    break
		}
	    }
	    if { "$i" == "0"} {
		WarnWin [_ "Sorry but, culdn't find a free drive letter."]
		cd $olddir
		return
	    }
	    set prob_drv $i
	    lappend drives $i

	    #el directorio del tipo de problema es un directorio de red?
	    if { "[ string range $problem_dir 0 1]" == "\\\\"} {
		set recurso "$problem_dir"
		if { ![ regexp {^(\\\\[^\\]+\\[^\\]+)\\(.*)} $recurso dumm net_dir resto]} {
		    #WarnWin "$problem_dir is not a valid net path."
		    WarnWin [_ "Sorry, but couldn't use '%s' as problem directory to calculate." $recurso]
		    cd $olddir
		    if { [ string first $proj_drv $net_drives] == -1} {
		        gidproc unsetdrive $proj_drv
		    } else {
		        gidproc unsetnetdrive $proj_drv
		    }
		    return
		}

		if { "$net_dir" != "$net_proj_dir"} {
		    set res [ gidproc setnetdrive $prob_drv "$net_dir"]
		    if { "$res" != ""} {
		        WarnWin [_ "setnetdrive %1\$s: '%2\$s' - %3\$s" $prob_drv $net_dir $res]
		        cd $olddir
		        if { [ string first $proj_drv $net_drives] == -1} {
		            gidproc unsetdrive $proj_drv
		        } else {
		            gidproc unsetnetdrive $proj_drv
		        }
		        return
		    }

		    lappend net_drives $prob_drv
		} else {
		    # en güindous NT no podemos mapear dos veces el mismo recurso, asin que . . .
		    set prob_drv $proj_drv
		}

		set problem_dir [ file native "$prob_drv:/$resto"]
	    } else {
		# es local
		set res [gidproc setdrive $prob_drv "[ file dirname $problem_dir]"]
		if { "$res" != ""} {
		    WarnWin [_ "setdrive %1\$s: '%2\$s' - %3\$s" $prob_drv $[ file dirname $problem_dir] $res]
		    cd $olddir
		    if { [ string first $proj_drv $net_drives] == -1} {
		        gidproc unsetdrive $proj_drv
		    } else {
		        gidproc unsetnetdrive $proj_drv
		    }
		    return
		}
		lappend local_drives $prob_drv
		set problem_dir [ file native "$prob_drv:/[ file tail $problem_dir]"]
	    }
	}
	# adecuamos algunos parametros
	#RAMSAN
	#set file [ file native [ file join $problem_dir [ file tail $file]]]
	set ProblemDirectory [ file join $problem_dir]
	set outfilenames [PWFIndOutputFilename OutputFile $file $basename \
		$directory $ProblemDirectory]
	if { $outfilenames != "" } {
	    foreach f $outfilenames {
		file delete $f
	    }
	}
	set outfilenameserror [PWFIndOutputFilename ErrorFile $file \
		$basename $directory $ProblemDirectory]
	if { $outfilenameserror != "" } {
	    foreach f $outfilenameserror {
		file delete $f
	    }
	}
	set outfilenameswarning [PWFIndOutputFilename WarningFile $file \
		$basename $directory $ProblemDirectory]
	if { $outfilenameswarning != "" } {
	    foreach f $outfilenameswarning {
		file delete $f
	    }
	}
	
	if { [info procs InitGIDCalculation] != "" } { 
	    InitGIDCalculation $file $basename $directory $problem_dir $gidexecutable $args
	}
	regsub -all {\\} "gidproc exec \"$file\" \"$basename\" \"$directory\" \"$problem_dir\" \"$gidexecutable\" $args" {\\\\} ss
	set res [ eval $ss]
	set AnexoRunProcInfo [list [ format "{%s} {%s}" $local_drives $net_drives]]
    }
    cd $olddir
    
    if { [lindex $res 0] == "end" } {
	return 
    } elseif { [lindex $res 0] == "remote" || [lindex $res 0] != 0 } {
	after 1000
#         lappend RunProcInfo [concat [list [list $basename] [lindex $res 1] [lindex $res 0] \
#                 $outfilenames $outfilenameserror $outfilenameswarning] $AnexoRunProcInfo]
	lappend RunProcInfo [concat [list $basename [lindex $res 1] [lindex $res 0] \
		$outfilenames $outfilenameserror $outfilenameswarning] $AnexoRunProcInfo]

	catch { unset GidProcWin(nexttime) }
	ActualizeProcInfo auto
	ActualizeProcsListBox $w
    } else {
	WarnWin [concat [_ "Error executing"] " '$file $basename $directory " \
		"[file native $ProblemDirectory] $gidexecutable'"]
    }

}

proc OpenProcWin { { w .wrun  }  } {
    global GidProcWin RunProcInfo
    set GidProcWin(w) $w
    if { ![info exists RunProcInfo] } { 
	set RunProcInfo "" 
    }

    if { [winfo exists $w] } { 
	raise $w 
    } else {
	InitWindow $w [_ "Process window"] ProcWin2WindowGeom "OpenProcWin"
	ProcWin_ui $w
    }

    update idletasks

    ActualizeProcInfoBegin
    
    ActualizeProcsListBox $w
}

proc RunProcInfoDeleteJob { name } {
    global RunProcInfo tcl_platform

    set ipos 0
    foreach i $RunProcInfo {
	set inname [file tail [lindex $i 0]]
	if { $name == $inname } {
	    set uid [lindex $i 2]
	    if { $uid != "remote"  && \
		    $tcl_platform(platform) == "windows"} {
		set drives [ lindex $i 6]
		set local_drives [ lindex $drives 0]
		set net_drives [ lindex $drives 1]
		foreach i $local_drives {
		    set res [gidproc unsetdrive $i]
		    if { "$res" != ""} {
		        WarnWin [_ "unsetdrive %1\$s: - %2\$s" $i $res]
		    }
		}
		foreach i $net_drives {
		    set res [gidproc unsetnetdrive $i]
		    if { "$res" != ""} {
		        WarnWin [_ "unsetnetdrive %1\$s: - %2\$s" $i $res]
		    }
		}
	    }

	    set RunProcInfo [lreplace $RunProcInfo $ipos $ipos]
	    return
	}
	incr ipos
    }
}

proc GiveRunProcInfoName { channel } {
    global RunProcInfo

    foreach i $RunProcInfo {
	set channelin [lindex $i 8]
	if { $channel == $channelin } {
	    return [file tail [lindex $i 0]]
	}
    }
    return ""
}

proc GiveRunProcInfoState { channel } {
    global RunProcInfo

    foreach i $RunProcInfo {
	set channelin [lindex $i 8]
	if { $channel == $channelin } {
	    return [lindex $i 9]
	}
    }
    return ""
}

proc GiveRunProcInfoServer { channel } {
    global RunProcInfo

    foreach i $RunProcInfo {
	set channelin [lindex $i 8]
	if { $channel == $channelin } {
	    return [lindex $i 6]
	}
    }
    return ""
}

proc SetRunProcInfoState { channel state } {
    global RunProcInfo
    set fail 1
    set ipos 0
    foreach i $RunProcInfo {
	set channelin [lindex $i 8]
	if { $channel == $channelin } {
	    set newi [lreplace $i 9 9 $state]
	    set RunProcInfo [lreplace $RunProcInfo $ipos $ipos $newi]
	    set fail 0
	    break
	}
	incr ipos
    }
    return $fail
}

proc SetRunProcInfoCloseChannel { channel } {
    global RunProcInfo
    set fail 1
    set ipos 0
    foreach i $RunProcInfo {
	set channelin [lindex $i 8]
	if { $channel == $channelin } {
	    set newi [lreplace $i 8 8 ""]
	    set newi [lreplace $newi 13 13 [clock seconds]]
	    set RunProcInfo [lreplace $RunProcInfo $ipos $ipos $newi]
	    set fail 0
	    break 
	}
	incr ipos
    }
    return $fail
}
