# VG: GUI functions 
#
#_____________________________________________________
proc va_vvar {{line "="}} {
#  If line has no "=" sign or has next char-s "==!<>" then this function return "" and 
#   GUI will evaluate line (see process). Otherwice - no line evaluation.
# 
#	This is a replacement of ic_vvar; reason for replacement: 
#   All ic_commands are evaluated.  "=" line does not need evaluation. 
#
# Valid line format: optional_valid_name=optional_calculatable_scalar_expression
# Spaces: allowed, except within names
# Valid lines: "a=5"  "A= 3*a" "=5*8+(sin (a))"
# Invalid lines: "s u=5" "A= 3*x" (if x not defined)
# Valid definition will be kept in database.

	set line [string trim $line]
	set i [string first "=" $line]
# valid line?
	if {$i <0} return
	set line [string replace $line $i $i " "]
	foreach c {= ! > <} {
		if {[string first $c $line] >= 0} return
	}  
	set i1 [expr $i+1]
	set def [string range $line $i1 end]
	set def [string trim $def]
	if {$def != ""} {
		set res [ic_vset - $def]	
# calculatable? If not - set why
		if {$res == ""} {
			set why [ic_vset]		
			if {$why != ""} {status_message $why} 
			return 1
		}
# calculatable, but no name 
		if !$i {
			status_message $res
			return $res
		}
	}
	# name. check value if no new definition or define
	set i1 [expr $i-1] 
	set name [string trim [string range $line 0 $i1]]
	set res [ic_vset -def $name]
	if {$res == ""} {
		set why [ic_vset]
		# why is empty line if no definition.
		if {$why != ""} {
			status_message $why
			return 1
		}
	} 
	# got valid name. Check type.
	if {$def == ""} {
# GUI feature: if variable, refresh definition: it will force recalculations,
# e.g. if user changed point location, but nothing virtual was changed:  
		set def [ic_vset -def $name]
		if {$def == ""} {status_message "No data"}
		set type [ic_vset -type $name]
		if {$type == "variable"} {
			ic_vset $name $def
		} 
		set res [ic_vset $name]
		if {$res != ""} {return $res}
		set res [ic_vset]
		if {$res != ""} {return $res} 
		status_message "Cannot calculate $type $def"		
	} 
# new definition; res already was calculated; do in gui interp
	set res [ic_vdefine $name var $def]
	status_message $res
	return $res
}

#
proc va_ezcad_init {{what 0}} {
#
# This procedure will be executed just ones if tk_version.
# 
#Purpose:
# Read (source) additional ez-cad functionality files
# Set default values in va_set
#
# For med only (not ai_env):
# Init parametrical database
# Create EZ-CAD windows
#
#=============================
	global va_set env tk_version
	if ![info exists tk_version] {return 1}
#=============================
	set DIR $env(ICEM_ACN)/lib/va/EZCAD
# Next part use EZCAD directory
#
	if ![file exists $DIR] {
		ic_mess "EZ-CAD not found\n"
		return 1
	}
  foreach fi {lib.tcl ezcad_funcs.tcl ezlib.tcl
	work_plane.tcl
	} {
    if [file exists $DIR/$fi] {source $DIR/$fi}
  }
#
  set va_set(DIR) $DIR
  set va_set(design) EZCAD
  vam_read_settings $DIR/ezcad.def
#
		return 0
}
#========================================================
proc va_ezcad_load {fname {command ""}} {
  global va_set env
  if [info exists va_set($fname.loaded)] {
    if {$command != ""} {eval $command}
    return
  }
  set f $env(ICEM_ACN)/lib/va/EZCAD/$fname
  if ![file exists $f] {
    va_debug 1 "File not found: $f \n"
    return 
  }
  source $f
  set va_set($fname.loaded) 1
  if {$command != ""} {eval $command}
}
#========================================================
proc va_debug {{level 0} {text ""}} {
global va_set
if ![info exists va_set(DEBUG) ] {set va_set(DEBUG) 0}
if {$text == ""} {
  ic_mess "DEBUG level $va_set(DEBUG) -> $level\n"
  set va_set(DEBUG) $level
  return
}
if {$level > $va_set(DEBUG)} return
# Levels: 0 - default user level; blue; 
# Print nothing "va_debug -1". 
#         1 - 5 : critical  red
#         > 5    - detailed debug, black
set col red
if !$level {set col blue}
if {$level > 5} {set col black}
ic_mess "$text\n" $col
}
#---------------------------
proc med_ezcad {{switch 0}} {
    global va_set va_type va_name va_def geo_command_mode env ezcad_is_active tdv_current_viewer
    global smallfont normalfont bubble_delay bubble_help 
#
# Load functionality if ezcad called first time!!!
# Return if error loading functionality
#
    if ![info exists va_set(fun_Point)] {
# if tdv_current_viewer not defined, set it!
	global tdv_current_viewer tdv_default
	if ![info exists tdv_current_viewer] {set tdv_current_viewer $tdv_default}
	if [info exists va_set(DIR)] {vam_menu $va_set(DIR)/menus2.dat}
	ic_v_init "init med 0"
  }
  set med_geo_winds {{cadif boco repair convert gmeshparams ezcad} 
          {surface curve point material density loop}
          {create delete modify emeshparams families copymove}
  }
# Next line is an optional possibility to switch mode without clicking checkbutton
#
  if $switch {set ezcad_is_active [expr !$ezcad_is_active]} 
#
# Med windows:  
    foreach row {0 1 2} {
        set col 1
        foreach mw [lindex $med_geo_winds $row] {
      if !$ezcad_is_active { 
        grid configure .v.top.panel2.geometry.$mw -column $col\
          -pady 2 -padx 2 -row $row -sticky wens
        incr col
      } else {
        grid forget .v.top.panel2.geometry.$mw
      }
        }
    }
# Destroy ezcad windows if ezcad_is_active is 0 (switch to med)
   if !$ezcad_is_active  {
    va_ezcad_done
    return
  }
# Check, that projlib exists 
#
    if ![ic_geo_is_loaded] {
  ic_empty_tetin
  make_default_file_name tetin .tin
    }
  va_create_ezcad_gui
  if {($va_set(scr_sel_mode) == "work_plane")} { wp_draw_plane wp }
}

proc va_end_of_screen_input {{im 0} {opt ""}} {
  global va_set tdv_current_viewer
    global va_set tdv_waiting_for_click tdv_waiting_for_motion select_action

    # replace temporary images using ic_image. in va_create_xyz use image name ic_image_nn  
	if $im {
		ic_image delete im_$im
		ic_image delete text_im_$im
	} else {
		ic_image delete point_im
		ic_image delete text_im
		ic_image delete tmp_im
	} 		

    # if $im delete only particular set of images (step 25) 
    if $im {
        foreach incr {0 25 50 75} {
            set i [expr $im+$incr]
            if [info exists va_set(im_$i)] {
                $va_set(im_$i) delete
                unset va_set(im_$i)
            }
        }
        return
    }

    for {set i 1} {$i <= 100} {incr i} {
        if [info exists va_set(im_$i)] {
            catch "$va_set(im_$i) delete"
            unset va_set(im_$i)
        } 
    }
	if [info exists va_set(im_wp)] {
		catch "$va_set(im_wp) delete"
        unset va_set(im_wp)
    }

	if {$opt == "start_va_create_xyz"} return
    # More cleaning at the end:
	ic_highlight
	banner ""
    tdv_cur $tdv_current_viewer dynamics
	va_do_modify {1 1 1} end
	if [info exists va_set(banner)] {unset va_set(banner)}
    if [info exists va_set(unset_list)] {
        foreach var $va_set(unset_list) {
            if [info exists va_set($var)] {unset va_set($var)}
        }
        unset va_set(unset_list)
    }
	ic_reset_geo_selected
}

proc va_preselect_image {type name xyz} {
	global va_set
	set txt ""
	if $va_set(xyz_show_xyz) {
	 lappend txt [va_round $xyz 7]
	}
	if $va_set(xyz_show_typename) {
		lappend txt $name				 	
	}
	if [llength $txt] {
		ic_image text_im preview $xyz $txt
	}
	ic_image highlight $name
}
proc va_preselect_on_tag {type name xyz} {
	ic_highlight $type $name
# using name "preview" for text image. See select_geometry 
	ic_image text_im preview $xyz "$type $name"
}

proc va_create_xyz {{how auto} {number 1} {use_pts 1} {show_how xyz} {var ""} {param 0} {param_var ""} {extras ""}} {
    global va_set tdv_current_viewer vam_events str_option vid_options
    global select_action allow_plane_selection coords med_selection_mode tdv_mouse_bindings
    
    # Mod: Jan 9, 06: If ViD_mode use ViPoint in auto select mode
    # Mod: June 27, 08: if how="tag" and extras[tag] = "surface.locations" use first selected surface for 2-nd... picks
    # Do not use location? Or create ViP on location?
    # Validation for number & boolen params

    if [catch "format %d $number"] {set number 100}
    if {$use_pts != "0"} {set use_pts 1}
    if {$param != "1"} {set param 0} 
    # mess "DB how=$how var=$var param=$param param_var=$param_var extras=$extras\n" red
	if [catch "set vid_options(vid_mode)" vid_mode] {
		set vid_mode 0
	}
	if $str_option(point,wide) {set yellow_p_size 6} else {set yellow_p_size 4}
	
	# list of variables for each selection. add value or delete on "back"
	set va_set(xyz_vars) "pnt_or_coords names_for_coords ends_for_coords types_for_coords how_got_coords global_coords screen_coords"
    foreach v $va_set(xyz_vars) {set va_set($v) ""}
    # to support old gui set options, if not defined:
	foreach {opt val} "allow_plane_selection 1 va_set(xyz_on_mesh) 0 \
			 va_set(xyz_show_xyz) 0 va_set(xyz_show_typename) 0 va_set(xyz_show_entity) 0" {
		if ![info exists $opt] {set $opt $val}
	}

    #  guarantee var and param_var will be global variables and set defaults
    if {$how != "surface" && $how != "curve"} {set param 0}
    if {$var != ""} {
        set var ::[string trimleft $var :]
        set $var ""
    }
    if {$param_var != ""} {
        set param_var ::[string trimleft $param_var :]
        if $param {set $param_var ""}
    }
    # set tag on selected surface or curve and nearest points
	if {$how == "selected" || $how == "surface_selected" || $how == "surface_selected_edge"} {
		set sel_type ""
		if {[ic_geo_check_objects_exist surface $extras] != ""} {
			set sel_type surface
		} elseif {[ic_geo_check_objects_exist curve $extras] != ""} {
			set sel_type curve
		} else return		
		
		# if selected surface or curve is faceted - set additional 
		#    tag "geo_select_segment" for this surface/curve
		# and use extra call for coordinates with geo_select_segment + nodes
		if {[ic_geo_get_object_type $sel_type $extras] == "mesh"} {
			ic_geo_set_tag clear "" geo_select_segment 0
			ic_geo_set_tag surface $extras geo_select_segment 1		
		}							
		set sel_name $extras
		ic_geo_set_tag clear "" va_selected 0
		ic_geo_set_tag clear "" va_nearest_points 0		
		ic_geo_set_tag $sel_type $extras va_selected 1
		set pnts [ic_geo_get_points_near $sel_type $extras]
		ic_geo_set_tag point $pnts va_nearest_points 1				 
		ic_reset_geo_selected
		ic_show_geo_selected $sel_type $extras 1 white 1			 
	}
	if {$how == "surface_selected_edge"} {
		set show_how done 
		set param 1
	}
    # images selection: point_im, arrow_im, etc.
	set im [string first _im $how]
	if {$im > 0} {
		set image_type $how
		if {[lsearch [ic_image ""] $image_type] < 0} {
			ic_mess "Err image type $image_type\n"
			return
		}
		set how image
	} 

	set r_image 100
    set coords ""
	set how_got ""
    va_end_of_screen_input 0 start_va_create_xyz
    set med_selection_mode 2
    set w $tdv_current_viewer
    set n_e 1

    # Always use existing points if exists at selected coordinate
    set show_xyz 0
    set show_param 0
    set show_curve ""
    # Default: confirm selection with middle button.
    set confirm 1
    if [info exists va_set(confirm)] {
	    lappend va_set(unset_list)	confirm
	    if {$va_set(confirm) == 0} {set confirm 0}
    }

    if {[lsearch $show_how direction] >= 0} {set show_curve direction}
    if {[lsearch $show_how end] >= 0} {set show_curve end}
    if {[lsearch $show_how plane] >= 0} {set show_curve plane}
    set r_pnts 25
	set r_crvs 15
    set r_auto -10
    # nearby is a possible distance from entity to a work plane
    set nearby 1000

    # DB: delete unused
    set entt ""
    set entn ""
	set is_mesh 0
	set type ""
	set name ""
	set xyz ""
    set vam_events(onMotion) ""

    if {$how == "tag"} {
	    if ![llength [$w list_with_tag $extras]] {
		    set select_action cancel
		    return 
	    }
	    set the_tag $extras
	    set vam_events(onMotion) va_preselect_on_tag
	    set onMotionTags $the_tag
	    # valid only for tagged surfaces
	    set use_first_surface 0
        if {$extras == "surface.locations"} {set use_first_surface 1}  	
    }
    if {$how == "image"} {
	    if ![llength [$w list_with_tag $image_type]] {
		    set select_action cancel
		    return 
	    }
	    set vam_events(onMotion) va_preselect_image
	    set onMotionTags $image_type
    }
    if {[lsearch "point curve surface info" $how] >= 0} {
	    set vam_events(onMotion) DefaultMotionProc
	    set onMotionTags geom_$how
    }
    set do_on_motion [llength $vam_events(onMotion)]

    select_set_bindings 9 1 0 0 "Select location"
    set finished 0
    tdv_cur $w pick
    #ic_undo_group_begin
    while {!$finished} {
		tkwait variable select_action
		foreach "ev x y" $select_action ""
		set on_screen 0	
		switch $ev {
	    done {
			set finished 1
	    }
		cancel {
			set finished 1
		}
		nb_move {
			#set xyz ""
			if $do_on_motion {
				onMotionEventProc $x $y $how $onMotionTags
			}
			continue
		}
	    back {
			va_xyz_back_action $n_e $var $param $param_var
                              incr n_e -1
                              if {$n_e == 1 && $how == "tag" && $the_tag == "use_first_surface"} {
                                 set the_tag $extras
                              }
			if !$n_e {
				set select_action cancel
				set finished 1
			}
			va_do_when_create_xyz "" "" end $n_e
	    }
	    press - move {
			if {$n_e > $number} {
				#replace_last_selection
				va_xyz_back_action $n_e  $var $param $param_var
				incr n_e -1
			}
	        set xyz ""
            switch $how {
			tag {
			   set blk [$w pick $x $y $the_tag nodes $r_pnts]
			   if {$blk == ""} {
			     set xyz [va_try_get_nearest_xyz $x $y $the_tag $r_crvs type name]
			   } else {
			     set xyz  [lindex $blk end]
			     set name [b [lindex $blk 0] get -name]
			   }
			if {$xyz != ""} {
		             if {($n_e == 1) && $use_first_surface} {
		                 set the_tag use_first_surface
		                 ic_geo_set_tag clear "" $the_tag 0
                         ic_geo_set_tag surface $name $the_tag 1 
                         ic_highlight surface $name color "" width 1                                
		             }
			}				
			}
			surface_selected {
				set p [va_try_get_nearest_xyz $x $y va_nearest_points $r_pnts junk pnt]
				# Point was selected, but return surface name
				if {$p != ""} {
					set v "0 0 0"
				} else {	
				set pv [$tdv_current_viewer screen2world $x $y]
				set p [lindex $pv 0]
				set v [lindex $pv 1]
				set v [ic_vcalc nrm $v]
				}
				set xyz [ic_geo_project_point surface $sel_name $p $v]
				set name $sel_name
				set type srf_projected
			}
			selected {
				set xyz [va_try_get_nearest_xyz $x $y va_nearest_points $r_pnts junk pnt]
				# Point was selected, but return surface name
				if {$xyz != ""} {
					set type $sel_type
					set name $sel_name
				} else {					
				set xyz [va_try_get_nearest_xyz $x $y "va_selected nodes" $r_pnts type name]
				if {$xyz == ""} {									
				set xyz [va_try_get_nearest_xyz $x $y va_selected $r_crvs type name]
				} 
				}
			}
			surface_selected_edge {
				set xyz [va_try_get_nearest_xyz $x $y va_nearest_points $r_pnts junk pnt]
				# Point was selected, but return surface name
				if {$xyz != ""} {				
					set name $sel_name
					set type surface
				} else {
				set xyz [va_try_get_nearest_xyz $x $y va_selected $r_pnts type name]
				}
				if {$xyz == ""} continue
				foreach {u v} [ic_geo_find_nearest_srf_pnt $name $xyz] ""
				if {[expr abs($u-0.5)] > [expr abs($v-0.5)]} {
					set dir 1
				} else {
					set dir 0
				}
				set uvt "$u $v"
				va_show_srf_iso_dir_image $name $u $v $dir 
				#
			}
			faceted {
				set xyz [va_try_get_nearest_xyz $x $y "geo_select_segment node" $r_pnts type name]
				if {$xyz == ""} {
				set xyz [va_try_get_nearest_xyz $x $y "geo_select_segment bound_edges" $r_pnts type name]
				}
				if {$xyz == ""} {
				set xyz [va_try_get_nearest_xyz $x $y "geo_select_segment edges" $r_pnts type name]
				}
			}
           point {
			set xyz [va_try_get_nearest_xyz $x $y geom_point $r_pnts type name]
		   }
		   curve - surface {
				set xyz [va_try_get_nearest_xyz $x $y geom_$how $r_auto type name]
				if $param {
				    set par ""
				    if {$name != ""} {
					switch $how {
					    surface {set par [ic_geo_find_nearest_srf_pnt $name $xyz]}
					    curve {set par [ic_geo_find_nearest_crv_pnt $name $xyz]}
					}
				    }
				    set uvt $par
				}
		   }
	   info {
	   # option select entity
			set xyz [va_try_get_nearest_xyz $x $y geom_point $r_pnts type name]
			if {$xyz == ""} {
				set xyz [va_try_get_nearest_xyz $x $y geom_curve $r_crvs type name]
			}	
			if {$xyz == ""} {
				set xyz [va_try_get_nearest_xyz $x $y geom_surface $r_crvs type name]
				}
		   }
       auto {
			if $vid_mode {
				set xyz [va_get_image_name_and_xyz $x $y vidpoint_im $r_pnts name image_var]
				set type point
			}
			if {$xyz == ""} {
			    set xyz [va_try_get_nearest_xyz $x $y geom_point $r_pnts type name]
			}
			if {$xyz == "" && $va_set(xyz_on_mesh)} {
	            if [ic_uns_is_loaded] {
		            set xyz [get_nearest_unstruct_node_pos $x $y]
                }
			}
			if {$xyz == "" && $va_set(xyz_on_mesh)} {
				# get_3d_point at visibility node. It cannot return name
				set xyz [va_try_get_3d_xyz $x $y nodes $r_pnts "" "" ]
			}
			if {$xyz == ""} {
				set xyz [va_try_get_nearest_xyz $x $y geom_curve $r_crvs type name]
			}
			if {$xyz == ""} {
				set xyz [va_try_get_nearest_xyz $x $y "geo_select_segment nodes" $r_pnts type name]
			}
			if {$xyz == ""} {
				set xyz [va_try_get_nearest_xyz $x $y geom_surface $r_crvs type name]
			}
			if {$xyz == "" && $va_set(xyz_on_mesh)} {
				# get_3d_point for mesh/blocking only. Slowest picker. It cannot return name  
				set xyz [va_try_get_3d_xyz $x $y lines $r_pnts "" ""]
			}
			if {$xyz == ""} {
				set va_set(workplane) [lindex "auto auto xy xz yz" $allow_plane_selection] 
				if $allow_plane_selection {
						set xyz [vam_screen2plane $x $y]
						set on_screen 1
				}
			}
          }
          vis_plane {
			set va_set(workplane) auto 
            set xyz [vam_screen2plane $x $y]
			set on_screen 1
          }
		  result {
			set xyz [vam_get_result_xyz $x $y name]
			if {$xyz != ""} {set result_xyz $xyz}
			}		
          image {
            set xyz [va_get_image_name_and_xyz $x $y $image_type $r_image name image_var]
			set type $image_type
			set image_var $name
			# consider virtual point image as "point" type
			if {$type == "vidpoint_im"} {set type point} 
          }
          work_plane {
            set xyz [wp_project_point [lindex [$w screen2world $x $y] 0]]
			set coor [va_try_get_nearest_xyz $x $y geom_point $r_pnts type name]
			if {$coor == ""} {
				set coor [va_try_get_nearest_xyz $x $y geom_entity $r_auto type name]
			}
			if {$coor != ""} {
				if {[expr abs([lindex [ic_coords_into_local $coor] 2])] < $nearby} { 
					set xyz $coor
				}
			}
          }
        }
		if {$xyz == ""} continue
			if {$ev == "press"} {
				va_do_when_create_xyz $xyz $type start $n_e
                va_do_when_create_xyz $xyz $type continue $n_e
			} else {
				va_do_when_create_xyz $xyz $type continue $n_e
			}
		# show some selection image:
		if {($how == "curve") && ($show_curve != "")} {
			va_show_crv_dir_image $n_e $xyz $name $show_curve
		} elseif {$show_how != "done"} {
			set new [ic_image point_im im_$n_e $xyz]
			if {$new == "1"} {ic_image set im_$n_e -color yellow -pickable 0}
			if $on_screen {set siz 2} else {set siz $yellow_p_size}
			ic_image set im_$n_e -size $siz
        }

		    if {$number == 1} {
			if $param {
			    if {$param_var != ""} {
				set $param_var $uvt
				if {$var != ""} {set $var $name}
			    } elseif {$var != ""} {
				set $var $uvt
			    }
			} elseif {$var != ""} {
			    if {!$use_pts || $type != "point"} {
				set $var [ic_coords_into_local $xyz]
			    } else {
				set $var $name
			    }
			}
		    }
			set xyz_text ""
			if $va_set(xyz_show_xyz) {
				if $param {set xyz_text " $uvt"} \
				else {set xyz_text [va_round $xyz 7]}
			}
			if $va_set(xyz_show_typename) {
				if [llength $type] {lappend xyz_text $type}
				if [llength $name] {lappend xyz_text $name}				 	
			}
			if [llength $xyz_text] {
				ic_image text_im text_im_$n_e $xyz $xyz_text
			}
			 if $va_set(xyz_show_entity) {
				ic_highlight $type $name
			}
		# end of  "press - move" event
	    }

		release {
	    if {$how == "result"} {set xyz $result_xyz} 
		if {$xyz == ""} continue
		# xyz: lappend data to coords, names_for_coords, etc.
		if [info exists va_set(last_end)] {
			lappend va_set(ends_for_coords) $va_set(last_end)
		}
		lappend va_set(types_for_coords) $type
 		lappend va_set(names_for_coords) $name
		lappend va_set(how_got_coords) $how_got
		lappend va_set(global_coords) $xyz
		lappend va_set(screen_coords) "$x $y"	
		set xyz_local [ic_coords_into_local $xyz]
		if {$type == "point"} {
			lappend va_set(pnt_or_coords) $name
		} else {			
			lappend va_set(pnt_or_coords) $xyz_local
		}		
		if !$param {
			lappend coords $xyz_local
		}
		
	    if {$param && $uvt != ""} {
		    lappend coords $uvt
		    if {$param_var != ""} {set $param_var $coords}
	    }
	    if {$var != ""} {
		if {$param && $param_var != ""} {set $var $va_set(names_for_coords)} \
		else {set $var $coords}
	      }

        va_do_when_create_xyz $xyz $type end $n_e
        incr n_e
		if {$n_e > $number} {
			if !$confirm {set finished 1}	
	    }
		set type ""
		set name ""
		set xyz ""
		#Close release; close switch; close while 
	}
	}
}
    #ic_undo_group_end
    select_unset_bindings 1
     if {$select_action == "cancel"} {
       # Cleaning on cancel
        foreach v $va_set(xyz_vars) {set va_set($v) ""}
        va_do_when_create_xyz "" "" cancel ""
    }   
    # next command unset variables from  va_set(unset_list), e.g. do_when_create_xyz 
    va_end_of_screen_input
    if {($how == "tag") && $use_first_surface} {
        ic_geo_set_tag clear "" use_first_surface 0
    }
    # return variable for 1 image
	if {($how == "image") && ([llength $coords] == 1)} {
		return $image_var
	}
	if {$select_action == "cancel"} {
	    if {$param && $param_var != ""} {set $param_var ""}
	    if {$var != ""} {set $var ""}
	    return ""
	}

	if {$use_pts && !$param} {
		set ret ""		
		for {set i 0} {$i < [llength $coords]} {incr i} {
			if {[lindex $va_set(types_for_coords) $i] == "point"} {
	            # formally selection may be done with point names like "123" "a1-a2" "a1+2" a1-1 a1/2.5 etc
	            # IF MED POINT NAME include "wrong" character: use location of the point, not name
				set maybe [lindex $va_set(names_for_coords) $i]
				if {[regexp {[a-zA-Z]} [string index $maybe 0]] && [ic_vset -vec - $maybe] != ""} {
					lappend ret $maybe
				} else {
					 lappend ret [lindex $coords $i]
				}
			} else {
				lappend ret [lindex $coords $i]
			}
		}
		return $ret 
	}
    return $coords
}
proc va_xyz_back_action {n_e {var ""} {param 0} {param_var ""}} {
	global va_set coords

	incr n_e -1
    va_end_of_screen_input $n_e

	set lists coords
    foreach v $va_set(xyz_vars) {
		lappend lists va_set($v)
	}
	foreach list $lists {
		set $list [lreplace [set $list] end end]
	}
# do [info exists $var] in case this procedure is called outside of va_create_xyz
	if {$var != "" && [info exists $var]} {set $var [lreplace [set $var] end end]}
	if {$param && $param_var != "" && [info exists $param_var]} {
			set $param_var [lreplace [set $param_var] end end]
	}
# Assume function must know what to do with empty xyz:
	va_do_when_create_xyz "" "" end $n_e
}
#----------------------------------
proc va_curve_dir {crv xyz which} {
global va_set
# which default value is a curve direction to "1"
# "end" will show direction to 0 if par < 0.5
	if ![llength [ic_geo_check_objects_exist curve $crv]] {return ""}
	set par [ic_geo_find_nearest_crv_pnt $crv $xyz]
	if {$par < 0.5} {set va_set(last_end) 0} else {set va_set(last_end) 1}
# 
	set par_incr 0.01
	set par2 [expr $par + $par_incr]	 
	if {$par2 >1.0} {
		set par_incr -0.01
		set par2 [expr $par + ($par_incr)]			
	}
	set loc2 [ic_geo_get_crv_pos $par2 $crv]
	if {[llength $loc2] == 1} {set loc2 [lindex $loc2 0]}
	if {$par_incr > 0.0} {
		set vec [ic_vcalc dir $xyz $loc2]
	} else {
		set vec [ic_vcalc dir $loc2 $xyz]
	}
	if {($which == "end") && ($par < 0.5)} {
		return [ic_vcalc smult $vec -1]
	} 
	return $vec
}
#==================
proc va_show_srf_iso_dir_image {name u v dir} {
	if !$dir {set dir 1} else {set dir 0}
	set a [lindex "$u $v" $dir]
	set am [expr $a - 0.1]
	if {$am < 0} {set am 0}
	set ap [expr $a + 0.1]
	if {$ap > 1} {set ap 1}
	if !$dir {
		set p1 [ic_geo_get_srf_pos $am $v $name]
		set p2 [ic_geo_get_srf_pos $ap $v $name]
	} else {
		set p1 [ic_geo_get_srf_pos $u $am $name]
		set p2 [ic_geo_get_srf_pos $u $ap $name]
	}
	set p1 [lindex $p1 0]
	set p2 [lindex $p2 0]
	 set new [ic_image line_im tmp_im $p1 $p2]
	 if {$new == "1"} {
		ic_image set tmp_im -color yellow
	} 	
}
proc va_show_crv_dir_image {n_e xyz crv show_how} {
	global va_set tdv_current_viewer
	set w $tdv_current_viewer
	set dir [va_curve_dir $crv $xyz $show_how]
	if {$dir == ""} return
# vec has length 1. Must scale for screen usage, say, 25 pixels
# 
	set pv [$w screen2world  0 0]
	set p1 [lindex $pv 0]
	set vnorm [lindex $pv 1]
	set p2 [lindex [$w screen2world 20 0] 0]
# scale is a basic "scale". use 0.3 of the scale for head lines
	set scale [ic_vcalc distance $p1 $p2]

	if {$show_how == "plane"} {
		set n1 [ic_vcalc vec_norm $dir]
		set n2 [ic_vcalc product $dir $n1]
		set p1 [ic_vcalc sum [ic_vcalc smult $n1 $scale] $xyz]
		set p2 [ic_vcalc sum [ic_vcalc smult $n2 $scale] $xyz]
		set p3 [ic_vcalc diff [ic_vcalc smult $n1 $scale] $xyz]
		set p4 [ic_vcalc diff [ic_vcalc smult $n2 $scale] $xyz]
		set im_xyz [list $p1 $p2 $p3 $p4 $p1 $p3 $p4 $p2]		
	} else { 
	set s03 [expr $scale*0.3]
	set s05 [expr $scale*0.5]	 
	set vec [ic_vcalc smult $dir $scale]
	set vec05 [ic_vcalc smult $dir $s05]

# using xyz vec and vnorm set 3 points in screen plane 
	set vscr [ic_vcalc nrm [ic_vcalc product $vec $vnorm]]
	set vscr [ic_vcalc smult $vscr $s03] 
#
	set phead [ic_vcalc sum $xyz $vec]
	set ptip  [ic_vcalc sum $phead $vec05]
	set phead1 [ic_vcalc sum $phead $vscr]
	set phead2 [ic_vcalc diff $vscr $phead]
	set im_xyz [list $xyz $ptip $phead1 $phead2 $ptip]
	}
#
    if ![info exists va_set(im_$n_e)] {
		set im [tdv_poly_line_im -draw_dots 0 -width 3 -color yellow]
		set va_set(im_$n_e) $im
        $tdv_current_viewer add_image $im
    } else {
		set im $va_set(im_$n_e)
		$im clear_points
    }
	foreach p $im_xyz {
		$im add_point $p
	} 
}
#---------------------------------
proc vam_get_result_xyz {x y name} {
	global tdv_current_viewer surf_info
	upvar $name resname
	set resname ""
	set bloc [$tdv_current_viewer get_probed_surface $x $y 1]
	if {$bloc == ""} return
	set n [lindex $bloc 3]
	set bsp stripsurf_im__$n
	set mem surf_info($bsp,title)
	if [info exists $mem] {set resname [set $mem]}
	return [lrange $bloc 0 2]
}		
#======================================
proc va_get_image_name_and_xyz {x y type r name var} {
	global tdv_current_viewer
	upvar $name im_name
	upvar $var  im_var 
	set im_name "" 
	set im_var ""
	set bloc [$tdv_current_viewer pick $x $y $type "" $r]
	if {$bloc == ""} {return ""}
	set im_name [ic_image get_name [lindex $bloc 0]]

#	set gui_name [ic_vset -find image $im_name]
#	if {$gui_name != ""} {
#		set im_var [lindex [ic_vset $gui_name] 0] 
#	}
	return [lindex $bloc 2]
}
#------------
proc va_try_get_nearest_xyz {x y use radius type name} {
# Last mod: Apr 11 2005: pick only geometry entities
# proc va_try_get_3d_xyz {x y use radius type name} for 3d_point
# "use" may include geom mode as last word: nodes, edges, bound_edges 
	global tdv_current_viewer
	upvar $type thetype
	upvar $name thename 
	set mode ""
	set thename ""	 
	set thetype ""		 
	set tags $use
	if { ! [ info exists tdv_current_viewer ] } {
		return ""
	}
	set w $tdv_current_viewer
	# modified: pick with radius does not work for solid surface
	if {[lindex $use 0] == "geom_surface"} {
		 set bloc [$w pick $x $y $use "" 0]
		 if {$bloc == ""} return
		 set xyz [lindex $bloc 2]
		 foreach "xs ys" [eval $w world2screen $xyz] ""	 
		 set rsq [expr ($x-$xs)*($x-$xs)+($y-$ys)*($y-$ys)]
		 if {$radius && ($rsq > [expr $radius*$radius])} return
		 set bsp [lindex $bloc 0]
		 set thetype surface
		 set thename [b $bsp get -name]	
		return $xyz
	}
	if {[llength $use] > 1} {
		set m [lindex $use end]
		if {[lsearch "nodes edges bound_edges" $m] >= 0} {
			set mode $m
			set tags [lreplace $tags end end]
		}
	}
	if {$mode != ""} {
	# pick create error if selected entity is structural
		set bloc [$w pick $x $y geo_select_segment $mode $radius]
	} else {
		set bloc [$w pick $x $y $tags "" $radius]
	}
		if {$bloc != ""} {
			set bsp [lindex $bloc 0]
			switch [string range $bsp 0 2] {
			"bsp" {
			set thetype [b $bsp get -type]
			set thename [b $bsp get -name] 
				}
			"tdv" {
					set thetype $tags
					set thename [ic_image get_name [lindex $bloc 0]]
				}
			}
			return [lindex $bloc 2]
		}	
	return ""
}
#------------
proc va_try_get_3d_xyz {x y use radius tag_vis_on tag_vis_off} {
	global tdv_current_viewer
#
# This pick only for select location from block and mesh. 
# It's slow and not robust. May be replaced in the future.
# It pick any image, including "point_im"; include images in tag_vis_off
# Use specific block, mesh pickers for more options 
#
#	if {![ic_hex_blocking_loaded] && ![ic_uns_is_loaded]} {return ""}
	if {$use == "nodes"} {
		set mode 0
	} elseif {$use == "lines"} {
		set mode 1
	}
	set xyz ""
	set on_list [ic_image get $tag_vis_on]
	set off_list [ic_image get $tag_vis_off]
	foreach im $on_list {
		ic_image set $im -visible 1
	}
	foreach im $off_list {
		ic_image set $im -visible 0
	}	 
	set bloc [$tdv_current_viewer get_3d_oglpt $x $y $mode]
	if {($bloc != "") && ([lindex $bloc 4] <= $radius)} {
		set xyz [lrange $bloc 0 2]
	}
	foreach im $on_list {
		ic_image set $im -visible 0
	}
	foreach im $off_list {
		ic_image set $im -visible 1
	}	 
	return $xyz
}	 				 				
#==============================================
proc va_round {vals n} {
    global med_float_precision
    # Note: may produce text with more than n digits (E format)
    set mf $n
	if [info exists med_float_precision] {
	    if [string is integer $med_float_precision] {
	        if {$mf < $med_float_precision} {
	            set mf $med_float_precision
	            set n $mf
	        }
	    }
	}
    foreach v $vals {
        if {abs($v) < 1e-10} { set v 0 }
        set k $n
        set f "%#${mf}.${k}g"
        if [catch "format $f $v"] { return "Err" }
        set l [string length [format $f $v]]
        set m [expr $n-$l]
#        incr k $m
        if {$k < 1} { set k 1 }
        set f "%#${mf}.${k}g"
        append newvals " [format $f $v]"
    }
    return $newvals
}

#==============================================
proc vam_screen2plane {x y} {
	global tdv_current_viewer va_set
#
# Math part must be moved to ic_vcalc
# return empty line if screen is normal to workplane
# This is a main difference with previous version
# which selected visible plane automatically
# 
#
	set scr [$tdv_current_viewer screen2world $x $y]
	set p1 [lindex $scr 0]
	set x1 [lindex $p1 0]
	set y1 [lindex $p1 1]
	set z1 [lindex $p1 2]
	set vec [lindex $scr 1]
	set svx [lindex $vec 0]
	set svy [lindex $vec 1]
	set svz [lindex $vec 2]
# Check max vec direction and normalize to it. 
# Note: Assume that vector sign is not important
	set vmax 0
           foreach i {0 1 2} {
		set v [expr abs([lindex $vec $i])]
		if {$v > $vmax} { 
			set vmax $v
			set imax $i
		}
	}
	set cnorm [expr 1.0/([lindex $vec $imax])]
	set vec [ic_vcalc smult $vec $cnorm]
	set vx [lindex $vec 0]
	set vy [lindex $vec 1]
	set vz [lindex $vec 2]
# 
# workplane defined only for cartesian LCS
#
	set cur [ic_csystem_get_current]
	if {$cur != "global"} {
		set def [ic_csystem_get $cur]
		set type [lindex $def 0]
		if {$type != "cartesian"} {
			set cur global
		}
	}
#  some math. Temporary here
# Calculate view for each location, because user
# may change view selecting several locations at once!
#
# 1. Set A B C D of workplane
#
	set def [ic_csystem_get $cur]
# def: type p0 v1 v2 v3
# in 5.0 vectors Ok
	set p0 [lindex $def 1]
	set v1 [lindex $def 2]
	set v2 [lindex $def 3]
	set v3 [ic_vcalc product $v1 $v2]
#
# use xy xz yz or auto plane
	if ![info exists va_set(workplane)] {
		set method auto
	} else {
		set method $va_set(workplane)
	}
# auto: select workplane as a plane with min angle between
# normal (axis) and view axis "vec" (most visible)
	set plane [lsearch "auto yz xz xy" $method]
	if {$plane <= 0} {
	set amin 180
	foreach n {1 2 3} {
		set ax [set v$n]
		set a [ic_vcalc angle $vec $ax]
		if {$a > 90.0} {set a [expr 180.0-$a]}
		if {$a < $amin} {set amin $a; set plane $n}
	}
	} else {
		set a 0
	}
	set v [set v$plane]
	set v [ic_vcalc nrm $v]	
# A,B,C,D - plane definition
	set A [lindex $v 0]
	set B [lindex $v 1]
	set C [lindex $v 2]
	set D [expr -($A*([lindex $p0 0])+($B)*([lindex $p0 1])+($C)*([lindex $p0 2]))]			

# 2. Find crossection of view vector with workplane
#
	set rr1 [expr $A*$svx + $B*$svy+$C*$svz]
	if !$rr1 {return ""}
	set rr  [expr ($A*$x1+$B*$y1+$C*$z1+$D)/$rr1]
	set x [expr $x1-$svx*$rr]
	set y [expr $y1-$svy*$rr]
	set z [expr $z1-$svz*$rr]
	return "$x $y $z"
# 
}
#==================================================

#=====================
 proc vam_onF9 {{f9 0}} {
 global tdv_waiting_for_click tdv_current_viewer vam_events
	set w $tdv_current_viewer
	if !$f9 {
		vid_picker_stop 0 0
            bind $w <F9> "set tdv_waiting_for_click($w) F9"
#            bind $parent <F9> "set tdv_waiting_for_click($w) F9"
            tdv_cur $w dynamics
            set pb [banner "Dynamics Mode - hit F9 to return to selection mode."]
            tkwait variable tdv_waiting_for_click
            banner $pb
            vam_onF9 1
	} else {
	# Just call with last settings
		if [info exists tdv_waiting_for_click($w)] {
			unset tdv_waiting_for_click($w)
		}
		vid_picker $vam_events(type) $vam_events(onMotion) $vam_events(onB)
	}
	focus $tdv_current_viewer
}
# Renamed vam_set_selection_binding
proc vid_picker {{type curve} {onMotion DefaultMotionProc} {onB DefaultButtonProc}} {
# vam_binding set 
#	
	global tdv_current_viewer select_action vam_events
	set select_action none
	# may be unnecessary safe feature:
	if {[info exists vam_events(enable)] && $vam_events(enable)} {
		vid_picker_stop
		return
	}
	set vam_events(enable) 1 
	set vam_events(type) $type
	set vam_events(onMotion) $onMotion
	set vam_events(onB) $onB
	set vam_events(delay_before) 500
	set vam_events(delay_between) 100
	set vam_events(last_name) unknown
# unset vam_binding if any: do not delay, do not delete banner if any	
	vid_picker_stop 0 0
#
#	if {[lsearch "point curve surface" $type] < 0} return
#
	vam_binding $type <Leave>           vid_picker_stop
	vam_binding $type <KeyPress-x>      vid_picker_stop
	vam_binding $type <ButtonRelease-1> vam_unset_timer	
	vam_binding $type <ButtonRelease-3> vam_unset_timer	
	vam_binding $type <KeyPress-F9>     vam_onF9
				
	if [llength $onMotion] {			 
		vam_binding $type <Motion> $onMotion
	}
	if [llength $onB] {  
		vam_binding $type <ButtonPress-1> $onB
		vam_binding $type <ButtonPress-2> $onB
		vam_binding $type <ButtonPress-3> $onB
	}
	tkwait variable vam_events(enable)
#   
	if {$select_action != "done"} return 
	if ![info exists vam_events(last_name)] return
	return $vam_events(last_name)	 	    
}
proc vid_picker_stop {{delay 100} {banner 1}} {
# Key events require delay and must be tested on diff platforms
	global tdv_current_viewer select_action vam_events tdv_waiting_for_click va_set
	set w $tdv_current_viewer
	if {$delay > 0} {
		after $delay "vid_picker_stop 0"
		return
	}
	foreach ename [array names vam_events] {
		if {[string index $ename 0] != "<"} continue
		if ![info exists vam_events($ename)] continue
		bind $w $ename $vam_events($ename)
		unset vam_events($ename)
	}
	if [info exists tdv_waiting_for_click($w)] {
		unset tdv_waiting_for_click($w)
	}
     if [info exists va_set(im_1)] {
            $va_set(im_1) delete
            unset va_set(im_1)
     }
	 if $banner {banner ""}
	 set ret [ic_highlight]
	set vam_events(enable) 0 
}	 

proc vam_binding {t e c} {
# type event command
	global tdv_current_viewer select_action vam_events tdv_waiting_for_click
	set w $tdv_current_viewer
	set vam_events($e) [bind $w $e]
	switch $e {
	"<KeyPress-x>" - 
	"<KeyPress-F9>" -
	"<Leave>" {bind $w $e $c}
	"<Motion>" {
		bind $w $e "va_MotionEvent $w %x %y $t $c"
		}
	"<ButtonPress-2>" -
	"<ButtonPress-1>" -
	"<ButtonPress-3>" {
		bind $w $e "va_ButtonEvent $w %x %y %b $t $c"
	}	 
	"<ButtonRelease-1>" -
	"<ButtonRelease-3>" {
		bind $w $e $c
	}	 
	}
	focus $w			 
}
proc vam_unset_timer {} {
	global  vam_events 
	if [info exists vam_events(timer)] {unset vam_events(timer)} 
}
proc vam_set_timer {} {
	global  vam_events 		
	if [info exists vam_events(timer)] {
		eval $vam_events(timer_command)
		after $vam_events(delay_between) vam_set_timer
	}
}
#=============
proc va_MotionEvent {w x y tags command} {
#
	global  vam_events select_action tdv_current_viewer va_set
	if {[info exists vam_events(last_name)]} {
		set name $vam_events(last_name)
	}
	va_try_get_nearest_xyz $x $y $tags -10 type name
	if {$xyz == ""} {
		$command "" "" "" 
		return
	} 	
	# if the same name, do nothing or highlight current
	if {[info exists vam_events(last_name)]} {
		if {$name == $vam_events(last_name)} {
			return
		}
	}
	set vam_events(last_name) $name
	$command $type $name $xyz
}
proc va_ButtonEvent {w x y but tags command} {
# More or less generic procedure
# return of this command is not important: action is to call "command"
	global  vam_events select_action tdv_current_viewer
	set xyz [va_try_get_nearest_xyz $x $y $tags -10 type name]

	if {$xyz == ""} {
		$command "" "" "" $but 
		return
	} 		
	$command $type $name $xyz $but 
# For but = 1, 3 generate more commands if holding
	if {$but == 1 || $but == 3} {
		set vam_events(timer_command) [list $command $type $name $xyz $but]
		set vam_events(timer) [clock clicks]
		after $vam_events(delay_before) vam_set_timer
		}	 
}
#==================================
proc DefaultButtonProc {type name xyz but} {
	global  select_action
	switch $but {
		1 {set select_action done}
		2 {set select_action leave}
		3 {set select_action cancel}		
		default {}
	}
	vid_picker_stop
}
proc onMotionEventProc {x y what {tags ""}} {
# Generic selection procedure on Motion event
# It will call command vam_events(onMotion) (if any) only on new selection
# 
	global  vam_events select_action
# GUI control added:
	if {[info exists vam_events(do_onMotion)] && ($vam_events(do_onMotion) != "1")} return
#
	if {$tags == ""} {set tags geom_$what}

	if ![info exists vam_events(onMotion)] return 
# 
	if ![llength $vam_events(onMotion)] return
	if ![info exists  vam_events(onMotion_radius)] {
		set vam_events(onMotion_radius) -10
	}
	set xyz ""
	if ![info exists vam_events(last_name)] {
		set vam_events(last_name) ""
	}
	set name $vam_events(last_name)
	set xyz [va_try_get_nearest_xyz $x $y $tags $vam_events(onMotion_radius) type name]

	if {$xyz == ""} {
		if {[info exists vam_events(last_name)] && $vam_events(last_name) != ""} {
			ic_highlight unset $vam_events(last_name) 
		}
		set vam_events(last_name) ""
		return
	}
	if {$vam_events(last_name) == $name} return
	set vam_events(last_name) $name
	$vam_events(onMotion) $type $name $xyz
}
proc onMotionEventEndProc {} {
# delete type/name if created with above proc
# 
global va_set
	ic_highlight
#?????	ic_image delete preview
#	if ![info exists va_set(im_1)] return
#	catch "$va_set(im_1) delete"
#	unset va_set(im_1)
}
proc DefaultMotionProc {type name xyz} {
# simplest motion proc: show type & name
	ic_highlight $type $name color ""
# using name "preview" for image. See select_geometry 
	global allow_preview_name
	if {[info exists allow_preview_name] && $allow_preview_name} {
	ic_image text_im preview $xyz "$type $name"
	}
}
#==================================================
proc vam_wait_for_click {{f9_key 0}} {
  global tdv_waiting_for_click explicit_location_value va_set
  global select_action options tdv_mouse_bindings tdv_current_viewer
  global tdv_key_command tdv_key_help
    
  set w $tdv_current_viewer
  tdv_cancel_rubbox $w
  set tdv_key_command(x) "set select_action cancel;set tdv_waiting_for_click($w) 0"
  set tdv_key_help(x) ""
  set parent [winfo parent $w]
    bind $w <F9> "set tdv_waiting_for_click($w) F9"
    bind $parent <F9> "set tdv_waiting_for_click($w) F9"
    tdv_cur $w pick
    set tdv_waiting_for_click($w) 1
	focus $w
    tkwait variable tdv_waiting_for_click
    if ![info exists tdv_waiting_for_click($w)] {return 0}
    if {$select_action == "cancel"} {
        set cc 0
    } else {
        set cc $tdv_waiting_for_click($w)
    }
    unset tdv_waiting_for_click($w)
    bind $w <F9> ""
    bind $parent <F9> ""
    tdv_cur $w dynamics
    switch -- [lindex $cc 0] {
      0 -  1 -  2 - 3  {return $cc}
        F9 {
            if !$f9_key {
               bind $w <F9> "set tdv_waiting_for_click($w) F9"
               bind $parent <F9> "set tdv_waiting_for_click($w) F9"
               tdv_cur $w dynamics
               set pb [banner "Dynamics Mode - hit F9 to return to selection mode."]
               tkwait variable tdv_waiting_for_click
               banner $pb
               return [vam_wait_for_click $f9_key]
               } else {
                 return f9_key
                 }
        }
        default {
            return 0
        }
    }
}
#==================================================
proc vam_pointer_text {coor text {nn 100}} {
global va_set tdv_current_viewer
# May be screen coords
if {[llength $coor] == 2} {
    if {[scan $coor {%d %d} x y] != 2} return
    set coor [lindex [$tdv_current_viewer screen2world $x $y] 0]
}
if {[llength $coor] != 3} return
if [catch "format {%g %g %g} $coor"] return 
if ![info exists va_set(im_$nn)] {
  set va_set(im_$nn) [tdv_text_im]
  $tdv_current_viewer add_image $va_set(im_$nn)
}
$va_set(im_$nn) configure -point $coor -text $text
}
#==================================================
proc vam_tooltip { w {text ""} {text2 ""}} { 
global va_set bubble_help
    if [winfo exists .tooltip ] {destroy .tooltip }
    if [winfo exists .tooltip2 ] {destroy .tooltip2 }
if ![llength $text] return
    if ![info exists va_set(help_mode)] { set va_set(help_mode) 0 }

if ![winfo exists $w] {
    if ![catch "format %d $w"] {
        if {$w > 0 && $w <= 100} {
            vam_pointer_text $text $text2 $w
        }
  }
  return
}
    if !$va_set(help_mode) return
#
if {([llength $text] == 1) && [info exists va_set($text)]} {
set text $va_set($text)
}
if {[llength $text] == 1 && [info exists $text]} {
set text [subst $[subst $text]]
}
set n [string length $text]
set is 0
set imax 8
set jmax 0
for {set i 0} {$i < $n} {incr i} {
if {[string index $text $i] == "\n"} {
set icur [expr $i - $is+1]
if {$icur > $imax} {set imax $icur}
incr jmax
set is $i
}
}
set icur [expr $i - $is+1]
if {$icur > $imax} {set imax $icur}
incr jmax
#
toplevel .tooltip -cursor top_left_arrow 
wm override .tooltip 1 
set x [expr [winfo rootx $w ]  ] 
set y [expr [winfo rooty $w ] + [winfo height $w] +3] 
wm geometry .tooltip "+$x+$y" 
set bg LemonChiffon
if {$va_set(design) == "EZCAD"} {set bg #ffff80}
text .tooltip.help -relief groove -bg $bg -font {Courier 8 bold}\
-width $imax -height $jmax -wrap word
.tooltip.help insert end $text
    bind $w <Leave> { vam_tooltip ?} 
    pack .tooltip.help -ipadx 0
update 
if ![winfo exists .tooltip.help] return
.tooltip.help configure -width $imax
#Small extra label
if {$text2 != ""} {
  set y2 [expr $y + [winfo height .tooltip] +5]
  toplevel .tooltip2  
  wm override .tooltip2 1 
  wm geometry .tooltip2 "+$x+$y2" 
  label .tooltip2.help -text $text2 -bg $bg -relief groove
  pack .tooltip2.help -ipadx 0
  update
}
} 
#================================================= 

proc va_refresh_screen {} {
  global va_set tdv_current_viewer
  
  if {[info exists va_set(scr_sel_mode)] && ($va_set(scr_sel_mode) == "work_plane")} { 
    wp_draw_plane wp 
  }
  foreach w {.m .e} { if [winfo exists $w] { wm deiconify $w} }
  banner ""
  select_unset_bindings 1
}
#=================================================
proc va_do_modify {xyz {when never}} {
  return $xyz
} 
#=================================================
proc va_do_when_create_xyz {xyz pname when num} {
    global va_set coords
    if ![info exists va_set(do_when_create_xyz)] return
    if ![info exists va_set(do_when_create_xyz_$when)] return
    set cmds $va_set(do_when_create_xyz_$when)
    if ![llength $cmds] return
# Notes: next variables are defined during point selection
#   pname may be empty
#   when may be: start continue end
#
    set va_set(xyz_xyz) $xyz
    set va_set(xyz_name) $pname
    set va_set(xyz_when) $when
    set va_set(xyz_num) $num
    foreach com $cmds {
        if ![llength $com] continue
		set r [catch {uplevel \#0 eval \{$com\}} res]
    }
} 
#++++++++++++++++++++++++++++++++++++++++++++++++++++
# New Part: vid 
proc vid_gui {} {
global vid_def vid_result vid_new vid_w

# Every time delete tcl data and read from C
# for this gui we use name, definition and result (if any) 
#
	set thefont "Helvetica 8 bold"
	if [info exists vid_def] {unset vid_def}
	if [info exists vid_result] {unset vid_result}
	ic_vset -type_use -all
	ic_vset -set help 1
	set list [lsort -dictionary [ic_vset -names]]
	set nnames [llength $list]
	set max_name 0
	set max_def 0
	set max_res 0
	foreach name $list {
		set data   [ic_vset -def $name]
		set n [string first "=" $data]
		incr n 2
		set vid_def($name) [string range $data $n end]
		set vid_result($name) [ic_vset $name]
		set nn [string length $name]
		if {$nn > $max_name} {set max_name $nn}
		set nn [string length $vid_def($name)]
		if {$nn > $max_def} {set max_def $nn}
		set nn [string length $vid_result($name)]
		if {$nn > $max_res} {set max_res $nn}
	}
	set mfont [font measure $thefont "a"]
	incr max_name 2
	incr max_def 5
	set name_pix [expr $max_name*$mfont]
	set def_pix [expr $max_def*$mfont+$name_pix]
	set res_pix [expr $max_res*$mfont+$def_pix]
	if {[info command ScrolledWindow] == ""} {
		set bw140 0
	} else {
		set bw140 1
	}
	if ![winfo exists .vid] {
		toplevel .vid
		set vid_new(type) "-var"
		set vid_new(msg) " "
	if ![ic_geo_is_loaded] ic_empty_tetin
	wm minsize   .vid 300 350
	wm transient .vid .v
	wm title     .vid "Variables & Vectors"
#
#NEXT SWITCH BETWEEN BWidget1.4.0 (AI*Env) and 1.3.3 (old MED GUI)
# Two small proc added for BWidget1.3.3 to simulate PanedWindow  
	

	if !$bw140 {
		set w_main .vid
		set w_data [canvas $w_main.0]
		set w_help [frame $w_main.1]
		set vid_w(w_data) $w_data
		set vid_w(w_help) $w_help
		set w_scr [canvas $w_main.01 -width 2 -bd 1 -bg gray \
		                -relief raised  -cursor sb_h_double_arrow]
		set vid_w(w_scr) $w_scr

		bind $w_scr <ButtonPress> "va_simple_scroll w_scr X %X -width w_data"
		bind $w_scr <B1-Motion> "va_simple_scroll_motion %X"	
		bind $w_scr <Leave> "$w_scr configure -relief raised"	
		pack $w_data -side left -expand 0 -fill y
		pack $w_scr -side left -fill y
		pack $w_help -side left -fill both

		set w_ww [frame $w_data.ww]
			set w_ww $w_data.ww
		set w_list [canvas $w_ww.0]	
		set w_bot  [canvas $w_ww.1]
		set w_scr1 [canvas $w_ww.01 -height 2 -bd 1 -bg gray -width 100\
		                -relief raised  -cursor sb_v_double_arrow]
		set vid_w(w_scr1) $w_scr1
		set vid_w(w_list) $w_list
		bind $w_scr1 <ButtonPress> "va_simple_scroll w_scr1 Y %Y -height w_can"
		bind $w_scr1 <B1-Motion> "va_simple_scroll_motion %Y"	
		bind $w_scr1 <Leave> "$w_scr1 configure -relief raised"
		$w_data create window 10 10 -window $w_ww	 -anchor nw -tag w_list
		pack $w_list $w_scr1 $w_bot -side top
		set w_ftext $w_help
#		frame $w_ftext
#		$w_help create window 0 0 -window $w_ftext -anchor nw

	} else {
		set w_main [PanedWindow .vid.vvv -side top -weights available -width 6]
		pack $w_main -side top -fill both -expand 1
		$w_main add -weight 1
		$w_main add -weight 0
		set w_data [$w_main getframe 0]
		set w_ftext [$w_main getframe 1]
		set w_ww [PanedWindow $w_data.ww -side left -weights available -width 6]
		$w_ww add -weight 5
		$w_ww add -weight 2
		set w_list [$w_ww getframe 0]	
		set w_bot  [$w_ww getframe 1]
		grid rowconfigure $w_bot 0 -weight 1	
		grid columnconfigure $w_bot 0 -weight 1	
		grid $w_ww -row 1 -column 1 -sticky nsew
		grid rowconfigure $w_data 1 -weight 1
		grid columnconfigure $w_data 1 -weight 1
		grid rowconfigure $w_list 1 -weight 1
		grid columnconfigure $w_list 1 -weight 1 
	}
		set w_scrl $w_list.scrl


		set w_can  [canvas $w_list.can -width $res_pix -height 200 \
	  -scrollregion {0 0 200 200} -yscrollcommand "$w_scrl set"]
		set vid_w(w_can) $w_can
		scrollbar $w_scrl -command "$w_can yview" 
		pack $w_scrl -side right -fill y
		pack $w_can -side left -expand 1
#==========================		
		frame $w_bot.1
		frame $w_bot.1.type 
		radiobutton $w_bot.1.type.fun -variable vid_new(type) -value "-var" -text "f()"
		radiobutton $w_bot.1.type.vec -variable vid_new(type) -value "-vec" -text "xyz"
		grid $w_bot.1.type.fun $w_bot.1.type.vec
		entry $w_bot.1.name -width 8 -textvar vid_new(name)
		entry $w_bot.1.def  -width 20 -textvar vid_new(def)
		grid $w_bot.1.name $w_bot.1.type $w_bot.1.def -sticky we
		bind $w_bot.1.def  <Return> vid_new_name
		label $w_bot.msg -textvar vid_new(msg)
		frame $w_bot.2
		button $w_bot.2.0 -text Read -command vid_read
		button $w_bot.2.1 -text Save -command vid_save
		button $w_bot.2.3 -text Done -command vid_done
		grid $w_bot.2.0 $w_bot.2.1 $w_bot.2.3
		grid $w_bot.msg -sticky we
		grid $w_bot.1 -sticky we
		grid $w_bot.2 -sticky we
# help
		set w $w_ftext
		set vid_w(w_help) $w
		text $w.text -font "Helvetica 8 bold" -yscrollcommand "$w.scr set"
		scrollbar $w.scr -command "$w.text yview"
		pack $w.scr -side left -fill y
		pack $w.text -side left -fill both -expand 1
		vid_help
# set initial reasonable window size
		if {$res_pix > 300} {
			wm geometry .vid ${res_pix}x350
		} else {
			update 
			set geoinit [wm geometry .vid]
			set geoinit [split $geoinit "x+"]
			if {[lindex $geoinit 0] > 350} {
				wm geometry .vid 350x[lindex $geoinit 1]
			}
		}
#	
# End of "! winfo exists .vid"
	}
#================
	set w_can $vid_w(w_can)
	$w_can delete all
	set h [expr $nnames*20+10]
	if {$res_pix < 350} {set res_pix 350}
	$w_can configure -scrollregion "0 0 200 $h" -width $res_pix

	set w_par [winfo parent $w_can]
	foreach ch [winfo children $w_can] {destroy $ch}
	set n 10
	foreach name $list {
		label $w_can.n$name -width $max_name -text $name -bd 1 \
		 -relief ridge -font $thefont
		entry $w_can.d$name -width $max_def  -textvar vid_def($name) -bd 1\
		 -relief ridge -font $thefont		
		label $w_can.r$name -width $max_res -textvar vid_result($name) -bd 1 \
		 -relief ridge -anchor w -font $thefont	
		$w_can create window 0 $n -window $w_can.n$name -tag all -anchor w
		$w_can create window $name_pix $n -window $w_can.d$name -tag all -anchor w	 
		$w_can create window $def_pix $n -window $w_can.r$name -tag all -anchor w
		incr n 20
		bind $w_can.d$name <Return> "vid_new_def $name"
	}
	$w_can yview moveto 1
}
# 
# 
#  -------------------
# Primitives for BWidget1.3.3
#  
proc va_simple_scroll {w_scroll dir XY what w_do} {
global vid_w
	set w $vid_w($w_do)
	$vid_w($w_scroll) configure -relief sunken
	set vid_w(command) "$w configure $what"
	set vid_w(scr_was) [lindex [eval $vid_w(command)] end]
	set vid_w(scr_ptr_was) $XY
}
proc va_simple_scroll_motion {XY} {
global vid_w
set value [expr $vid_w(scr_was)+($XY-$vid_w(scr_ptr_was))]
set com "$vid_w(command) $value"
eval $com
}
# End of Primitives for BWidget1.3.3
#------------------------------

proc vid_help {} {
	global vid_w
	if ![info exists vid_w(w_help)] return
	set w $vid_w(w_help).text
	if ![winfo exists $w] return
# HELP TEXT:
	$w insert 1.0 {
	
	
___________________________________
   GUI for Variables and Vectors:
___________________________________
Type name, select type: variable "f()" or vector "xyz", type definition, press Enter.
Examples: 
	x11A f() R * sin (phi) + X0
	y11A f() R*cos(phi)+Y0
	p321 xyz x11A y11A 125 
___________________________________
         Scripting command: 
___________________________________
	ic_vset [option] [name] [definition]

Options: -variable -vector -delete -write -read -names -info
Option may be abbreviated upto 4 chars: -var -vec -set etc.
Only one option for command!. Default option: -variable
Examples:
	ic_vset x11A "R * sin (phi) + X0"		// set or change definition
	ic_vset -variable y11A "R*cos(phi)+Y0"  // 
	ic_vset -vec p321 "x11A y11A 125"       //
	ic_vset -names							// return all names
	ic_vset -delete xxx  // delete variable or vector xxx
	ic_vset -write <filename> write variables and vectors in file
	ic_vset -read  <filename> read  variables and vectors from file	 
	ic_vset xxx			// return value of xxx (if possible) or empty string
	ic_vset -info xxx   // info on xxx: "name" "type" "=" "definition"
}
# End help text
}
#===================
proc vid_new_def {name} {
global vid_def vid_result vid_new
	set vid_new(msg) " "
	if ![llength $vid_def($name)] {
		ic_vset -delete $name
		vid_gui	
	}	
	set res [ic_vset $name $vid_def($name)]
	if ![llength $res] {
		set vid_new(msg) [ic_vset]
		if [llength $vid_new(msg)] return
	}
	foreach nm [array names vid_result] {
		set vid_result($nm) [ic_vset $nm]
	}
}
#===================
proc vid_new_name {} {
global vid_def vid_result vid_new
# Only -vec[tor] and -var[iable] types here
	set vid_new(msg) " "
	set name   [string trim $vid_new(name)]
	set option [string trim $vid_new(type)] 
	set def  $vid_new(def)
	if ![llength $name] {set name "-"}
	if {$name == "-"} {
		set option  "-var" 
		set vid_new(type) "-var"
	} 
	if ![llength $def] {set option "-delete"}
	set vid_new(msg) [ic_vset $option $name $def]
	if ![llength $vid_new(msg)] {set vid_new(msg) [ic_vset]}
	if {$name == "-"} return
	vid_gui
}
#-------------------
proc vid_read {} {
	set fi [tk_getOpenFile]
	ic_vset -read $fi
	vid_gui
}
proc vid_save {} {
	set fi [tk_getSaveFile]
	ic_vset -write $fi
	vid_gui
}
proc vid_done {} {
	destroy .vid 
	foreach g {vid_def vid_result vid_new vid_w} {
		global $g
		if [info exists $g] {unset $g}
	}
}
#===================

proc ic_current_view {args} {
## Change GUI view.  Arguments are:
## <ul>
## <li> <b>-pos</b> <i>position</i>  
## <li> <b>-rot</b> <i>rotation</i> 
## <li> <b>-scale</b> <i>scale</i> 
## <li> <b>-center</b> <i>center</i>
## <li> <b> returns old values; may be used without new values; all args optional</b>
## </ul>
	global tdv_center tdv_rot tdv_scale tdv_pos tdv_current_viewer batch_mode
    if $batch_mode return
	if ![info exists tdv_current_viewer] return
 	set w $tdv_current_viewer
	if ![winfo exists $w] return
#	replay_record_command "ic_current_view $args"
          set options "-pos -rot -scale -center"
          if {$args == ""} {set args $options}
          set nargs [llength $args]
          # if results were saved in variable - it's one argument
          # instead of "eval" on top level, try it here:
          if {$nargs == 1} {
             set args [lindex $args 0]
             set nargs [llength $args]
          }
          set result ""
          for {set i 0} {$i < $nargs} {incr i} {
            set key [lindex $args $i]
            if {[lsearch $options $key] < 0} continue
  	  if {$key == "-pos"}    {lappend result $key $tdv_pos($w)}
	  if {$key == "-rot"}    {lappend result $key $tdv_rot($w)}
	  if {$key == "-scale"}  {lappend result $key $tdv_scale($w)}
	  if {$key == "-center"} {lappend result $key $tdv_center($w)}        
            set ival [expr $i+1]
            if {$ival >= $nargs} continue
            set val [lindex $args $ival]
            if {[lsearch $options $val] >= 0} continue
            # check erroneous input values or screen problem may occur
            # Note: -rot (4 numbers)
            set err 0            
            if {$key == "-rot"} {
              set nscan [scan $val "%g %g %g %g %s" ju ju ju ju errtext]
              if {$nscan != 4} {set err 1}
            } else {
              set nscan [scan $val "%g %g %g %s" ju ju ju errtext]
              if {$nscan != 3} {set err 1}            
            }
            if $err {
              status_message "Error in ic_current_view definitions" red
              return $result
            }              
	  if {$key == "-pos"}    {set tdv_pos($w)    $val}
	  if {$key == "-rot"}    {set tdv_rot($w)    $val}
	  if {$key == "-scale"}  {set tdv_scale($w)  $val}
	  if {$key == "-center"} {set tdv_center($w) $val}
	}
	tdv_trans_update $w
	return $result
}
#---------------------
proc va_get_other_color {c} {
return red
	# do not change white to black!
	set m [lindex [winfo rgb . white] 0]
	set mm [expr $m/2]
	set m [expr $m/8]
	foreach "r g b" [winfo rgb . $c] ""
	set cnew #
	foreach n "r g b" {
		if {[set $n] < $mm} {incr $n $m} else {incr $n -$m}
		append cnew [format %04x [set $n]]
	}
	return $cnew 
}
#==================================================
proc va_get_faceted_in_circle {tag center x_ax normal radius} {
  # get with tag geo_select_segment
  # 
    global tdv_default batch_mode
    if $batch_mode return 
    set radius [expr 1.001*$radius]
    set pvec [ic_vcalc nrm_smult $x_ax $radius]
    set ppnt [ic_vcalc sum $center $pvec]
    if {$ppnt == ""} return
    set sel [$tdv_default pick_circle $tag $normal $center $ppnt all]
    set names ""
    foreach ob $sel {
      lappend names [b $ob get -name]
    }
    return $names
}
 
#==================================================
  va_ezcad_init

