
# This code creates the user interface for the mesh editor.
#
# Copyright (c) 1997 Pacific Marketing and Consulting, Inc,
#       and ICEM Systems, GmbH.  All rights reserved.
# Author:  Wayne A. Christopher, wayne@icemcfd.com
# Author:  Jari Spaete, jari.spaete@ansys.com
# $Revision$ on $Date$

# This file contains special comments of the form ## html ... which are
# used to automatically generate documentation

## <h3>Misc mesh editor functions</h3>

## Rename the specified family in the tetin database and the unstructured
## mesh (domain file).

proc ic_rename_family {old new} {
    global projlib uns_cur
    
    ic_geo_rename_family $old $new
    if {$uns_cur != ""} {
        $uns_cur rename_family $old $new
    }
}

## Write hardcopy or image file output.
## The arguments are:
## <ul>
## <li> <b>format</b> <i>form</i> : one of:
## <ul>
## <li> <b>ps</b>
## <li> <b>ppm</b>
## <li> <b>x</b>
## <li> <b>tiff</b>
## <li> <b>gif</b>
## <li> <b>jpeg</b>
## <li> <b>rgb</b>
## <li> <b>win</b>
## </ul>
## <li> <b>generate_new</b> <i></i> : generate a new filename based on the
## outfile argument
## <li> <b>invert</b> <i>on</i> : swap black and white
## <li> <b>jpeg_quality</b> <i>qual</i> : the quality factor for JPEG, between
## 0 and 100
## <li> <b>landscape</b> <i>on</i> : if 1 then swap the X and Y axes
## <li> <b>outfile</b> <i>filename</i> : the file to create (without the
## suffix which is automatically added)
## <li> <b>ps_color</b> <i>opt</i> : either color, gray, or mono
## <li> <b>ps_direct</b> <i>on</i> : if 1 then write a vector-based ps output,
## otherwise do raster
## <li> <b>ps_frame</b> <i>on</i> : if 1 draw a frame around the ps output
## <li> <b>ps_label</b> <i>text</i> : the label to put at the bottom right
## of the postscript output
## <li> <b>ps_title</b> <i>text</i> : the title to put at the top of the
## postscript output
## <li> <b>scale</b> <i>val</i> : scale factor
## <li> <b>send_to_printer</b> <i>on</i> : if 1 then the postscript file will
## be printed using lp
## </ul>

proc ic_print {args} {
    gui_hardcopy_create $args
}

## What is the current vector into the screen?  Returns 0 0 0 in batch mode.

proc ic_view_zvector {} {
    global tdv_default batch_mode
    if $batch_mode {
        return "0 0 0"
    } else {
        return [lindex [$tdv_default screen2world 0 0] 1]
    }
}

##
##  Introduce a comment line into script file, e.g.
##  <pre>
##  ic_comment "Why was this command added to the API?"
##  </pre>
##  command has no effect on program execution

proc ic_comment { text }  {
#
#  Last modified ---
#    08/16/01 - AWM - tested successfully
#
}

##  Returns number of processors

proc ic_get_n_processors {} {
    return [get_n_processors]
}
set dont_record_command(ic_get_n_processors) 1

# gui update related commands

proc ic_gui_update {{what ""}} {
    global batch_mode tdv_default

    if $batch_mode return
    
    if {$what == ""} {
        foreach type "geom mesh block group" {
            ic_gui_update $type
        }
    }  
    aie_update_gui $what
}

proc ic_set_global {name value {field ""}} {
    return [aie_set_global $name $value $field]
}

proc ic_unset_global {name {field ""}} {
    return [aie_unset_global $name $field]
}

proc ic_get_global {name {field ""}} {
    return [aie_get_global $name $field]
}

proc ic_get_global_array_names {name} {
    return [aie_get_global_array_names $name]
}

proc ic_get_meshing_param_value {type param} {
    foreach {n v} [ic_get_meshing_params $type 0] {
        if {$n == "$param"} {
            return $v
        }
    }
    return "___NA___"
}
set dont_record_command(ic_get_meshing_param_value) 1

proc ic_autosizing {type {force 0}} {
    global batch_mode

    if ![ic_geo_is_loaded] { return 0 }
    
    set gmax 0
    foreach {u v} [ic_get_meshing_params global 0] {
        if {$u == "gmax"} {
            if {$v != ""} { set gmax $v }
            break
        }
    }

    if [expr $gmax >= 0.0] {
        if !$force { if [expr $gmax > 0.0] { return $gmax } }
        set bbox [ic_geo_model_bounding_box]
        set dist [eval ic_vcalc distance $bbox]
	    set max_size [expr 0.1 * $dist]
        if !$force { if [expr $gmax > 0.0 && $gmax < $max_size] { return $gmax } }
        foreach s [ic_geo_get_objects surface ""] {
	        set size [lindex [ic_get_meshing_params surface $s] 1]
            if {([string is double -strict $size] || [string is integer -strict $size])} {
                if !$force { if [expr $size > 0.0 && $size < $max_size] { return $gmax } }
            }
        }
	    foreach c [ic_geo_get_objects curve ""] {
	        set size [lindex [ic_get_meshing_params curve $c] 1]
            if {([string is double -strict $size] || [string is integer -strict $size])} {
                if !$force { if [expr $size > 0.0 && $size < $max_size] { return $gmax } }
            }
        }
    }

    switch $type {
	    quad {
	        set new_size [expr [ic_geo_default_topo_tolerance] * 25.0 / [ic_geo_get_ref_size]]
	        foreach c [ic_geo_get_objects curve ""] {
		        set size [lindex [ic_get_meshing_params curve $c] 1]
		        if {$size < 1e-38} {
		            break
		        } elseif {$size > $new_size} {
		            set new_size $size
		        }
	        }
	        return $new_size
	    }
        tetra {
	        set new_size [expr [ic_geo_default_topo_tolerance] * 50.0 / [ic_geo_get_ref_size]]
	        foreach s [ic_geo_get_objects surface ""] {
		        set size [lindex [ic_get_meshing_params surface $s] 1]
		        if {$size < 1e-38} {
		            break
		        } elseif {$size > $new_size} {
		            set new_size $size
		        }
	        }
	        return $new_size
	    }
	}
	return $gmax
}

proc ic_get_non_empty_parts {} {
    set non_empty ""
    foreach t "geo uns hex" {
        foreach p [ic_${t}_non_empty_families] {
            if ![info exists tmp($p)] {
                lappend non_empty $p
                set tmp($p) 1
            }
        }
    }
    return "$non_empty"
}
set dont_record_command(ic_get_non_empty_parts) 1

proc ic_solution_set_solver {ch getbc} {
    solution_set_solver $ch $getbc
}

proc ic_socket_set_server_info {what value} {
    global serverInfo
    
    set serverInfo($what) $value
}
set dont_record_command(ic_socket_set_server_info) 1

proc ic_socket_get_server_info {what} {
    global serverInfo
    
    if [info exists serverInfo($what)] {
        return $serverInfo($what)
    } else {
        return ""
    }
}
set dont_record_command(ic_socket_get_server_info) 1

proc ic_socket_output_server_info {} {
    global serverInfo
    
    foreach n [lsort [array names serverInfo]] {
        mess "$n : $serverInfo($n)\n"
    }
}
set dont_record_command(ic_socket_output_server_info) 1

proc ic_socket_unset_server_info {{what ""}} {
    global serverInfo
    
    if {$what == ""} {
        if [info exists serverInfo] {
            unset serverInfo
        }
    } elseif [info exists serverInfo($what)] {
        unset serverInfo($what)
    }
}
set dont_record_command(ic_socket_unset_server_info) 1

proc ic_socket_puts {sock line} {   
    if {$sock == ""} {
        ic_socket_error "missing socket"; return
    }
    if {$line == ""} {
        ic_socket_error "missing line"; return
    }
    fconfigure $sock -buffering line -blocking 0
    puts $sock $line
    flush $sock
    fconfigure $sock -buffering line -blocking 1
}
set dont_record_command(ic_socket_puts) 1

proc ic_socket_gets {sock} {
    if {$sock == ""} {
        ic_socket_error "missing socket"; return
    }
    fconfigure $sock -buffering line -blocking 0
    set line [gets $sock]; update
    fconfigure $sock -buffering line -blocking 1
    return $line
}
set dont_record_command(ic_socket_gets) 1

proc ic_socket_connect_client_to_server {port {client ""}} {
    if {$port == ""} {
        ic_socket_error "missing port number"
        return
    }
    if {$client == ""} {
        ic_socket_connect_client_to_server1 $port
    } else {
        ic_socket_connect_client_to_server2 $port $client
    }
    return
}
set dont_record_command(ic_socket_connect_client_to_server) 1

proc ic_socket_connect_client_to_server1 {port} {
    if {[ic_socket_get_server_info client_server1,port] == "$port"} {
        ic_socket_error "already connected to port $port"
        return
    }
    if {[catch {socket localhost $port} sock]} {
        ic_socket_error "cannot connect; $sock"
        return
    }
    fconfigure $sock -buffering line -blocking 0
    fileevent $sock readable
    ic_socket_set_server_info client_server1,sock $sock
    ic_socket_message "Client connected to server through port $port\n" blue
}
set dont_record_command(ic_socket_connect_client_to_server1) 1

proc ic_socket_connect_client_to_server2 {port client} {
    if {[ic_socket_get_server_info client_server2,port] == "$port"} {
        ic_socket_error "already connected to port $port"
        return
    }
    if {[ic_socket_get_server_info client_server2,client] == "$client"} {
        ic_socket_error "already connected to client $client"
        return
    }   
    set sock [ic_socket_get_server_info client_server2,$client,sock]
    if {$sock == ""} {
        if {[catch {socket localhost $port} sock]} {
            ic_socket_error "cannot connect; $sock"
            return
        }
        fconfigure $sock -buffering line -blocking 0
        fileevent $sock readable
        ic_socket_set_server_info client_server2,port $port
        ic_socket_set_server_info client_server2,client $client
        ic_socket_set_server_info client_server2,$client,sock $sock
    } else {
        ic_socket_error "client $client already connected to port $port"
    }
}
set dont_record_command(ic_socket_connect_client_to_server2) 1

proc ic_socket_disconnect_server {} {
    global serverInfo is_win
    
    set port [ic_socket_get_server_info server,port]
    if {$port == ""} {
        ic_socket_error "disconnect; missing server port number"
        return
    }
    set sock [ic_socket_get_server_info server,sock]
    if {$sock == ""} {
        ic_socket_error "disconnect; missing server socket"
        return
    }
    if [catch { close $sock } res] {
        ic_socket_error "$res"
    } else {
        ic_socket_message "Server ICEM CFD network connection to port $port closed at [clock format [clock seconds] -format "%D %T"]\n" blue
    }
    after 1000
    set serverInfo($port,forever) 1
}
set dont_record_command(ic_socket_disconnect_server) 1

proc ic_socket_error {error} {
    mess "Network Connection Error: $error\n" red
}
set dont_record_command(ic_socket_error) 1

proc ic_socket_message {mess {color blue}} {
    global env
    if {[info exists env(BUILD_SITE)] && $env(BUILD_SITE) == "hnv"} {
        mess "$mess" $color
    }
}
set dont_record_command(ic_socket_message) 1

proc ic_socket_send_to_wb2 {line} {
    global env
    
    # ignore commands during replay file run
    if [ic_wb2_input_parameter_mode] { return 0 }
    
    ic_socket_message "Send command \"$line\" to client workbench\n" darkgreen
    set sock [ic_socket_get_server_info client,workbench,sock]
    if {$sock != ""} {
        if [catch {fconfigure $sock -buffering line -blocking 0} res] {
            ic_socket_error "$res"; return 1
        }
        if [catch {puts $sock $line} res] {
            ic_socket_error "$res"; return 1
        }
        if [catch {flush $sock} res] {
            ic_socket_error "$res"; return 1
        }
        if [catch {fconfigure $sock -buffering line -blocking 1} res] {
            ic_socket_error "$res"; return 1
        }
    } else {
        ic_socket_error "missing socket from client workbench"
        return 1
    }
    after 500
    return 0
}
set dont_record_command(ic_socket_send_to_wb2) 1

proc ic_socket_exec_client_command {sock} {
    global env
    
    set client [ic_socket_get_server_info server,client]
    if {[eof $sock] || [catch {gets $sock line}]} {
        ic_socket_message "Closing connection to client $client\n" blue
	    close $sock	    
    } else {
        ic_socket_message "Received command from client $client: \"$line\"\n" blue
        if {$line != ""} {
            if [info exists env(WB2_ICEM_PERFORMANCE)] { set time [clock clicks -milliseconds] }
            set ret [eval $line]
            ic_socket_message "Command \"$line\" returns <$ret>\n" purple
            if [catch {puts $sock $ret} res] {
                ic_socket_error "$res"
            }
            if [info exists env(WB2_ICEM_PERFORMANCE)] { ic_mess "Executed command $line: Finished in [expr ([clock clicks -milliseconds] - $time) / 1000.0] second(s)\n" blue }
	    } else {
	        ic_socket_error "received an empty command string from client $client"
	    }
    }
}
set dont_record_command(ic_socket_exec_client_command) 1

proc ic_socket_is_client_connection_alive {client} {
    if {[ic_socket_get_server_info client,$client,sock] != ""} {
        return 1
    } else {
        return 0
    }
}
set dont_record_command(ic_socket_is_client_connection_alive) 1

proc ic_socket_connect_client {sock addr port} {
    set client [ic_socket_get_server_info server,client]
    ic_socket_set_server_info client,$client,sock $sock
    ic_socket_set_server_info client,$client,port $port 
    ic_socket_set_server_info client,$client,addr $addr
    fconfigure $sock -buffering line
    fileevent $sock readable [list ic_socket_exec_client_command $sock]
    ic_socket_message "Network connection to client $client opened at [clock format [clock seconds] -format "%D %T"]\n" blue
}
set dont_record_command(ic_socket_connect_client) 1

proc ic_socket_connect_icemcfd_server {port} {
    global serverInfo
    
    if {[catch { socket -server ic_socket_connect_client $port } sock]} {
        ic_socket_error "unable to start server at port $port; $sock\n"
        ic_socket_unset_server_info
        return
    }
    ic_socket_set_server_info server,port $port
    ic_socket_set_server_info server,sock $sock
    ic_socket_set_server_info server,addr localhost
    ic_socket_message "Server ICEM CFD network connection to port $port opened at [clock format [clock seconds] -format "%D %T"]\n" blue
    vwait serverInfo($port,forever)
    ic_socket_unset_server_info
}
set dont_record_command(ic_socket_connect_icemcfd_server) 1

proc ic_socket_start_icemcfd_server {port {client "workbench"}} {
    if {$port != ""} {
        if {[ic_socket_get_server_info server,port] == "$port"} {
             ic_socket_error "server ICEM CFD already connected at port $port"
             return
        }
        if {[ic_socket_get_server_info server,client] == "$client"} {
             ic_socket_error "server ICEM CFD already connected to client $client"
             return
        }
        ic_socket_set_server_info server,client $client
        ic_socket_connect_icemcfd_server $port
    } else {
        ic_socket_error "unable to start ICEM CFD server: missing port number"
    }
}
set dont_record_command(ic_socket_start_icemcfd_server) 1