proc aie_tree { action {type ""} {args ""}} {

	switch $action {
		init	        { ::AIEnv::GUIManagement::Tree::treeInit $args }
		add		        { ::AIEnv::GUIManagement::Tree::treeAdd $type $args  }
		delete          { ::AIEnv::GUIManagement::Tree::treeDelete $type $args  }
		clear           { ::AIEnv::GUIManagement::Tree::treeClear }
		collapse        { ::AIEnv::GUIManagement::Tree::treeCollapse }
		open            { ::AIEnv::GUIManagement::Tree::treeOpen $type }
		close           { ::AIEnv::GUIManagement::Tree::treeClose $type }
		update_families { ::AIEnv::GUIManagement::Tree::treeUpdateFamilies }
	    add_group       { eval ::AIEnv::GUIManagement::Tree::AddGroup $type $args} 
	    delete_group    { eval ::AIEnv::GUIManagement::Tree::DeleteGroup $type $args} 
		default         { mess "  Not a valid Action" ; return 0 }
	}
}

namespace eval ::AIEnv::GUIManagement::Tree {

}


proc ::AIEnv::GUIManagement::Tree::treeInit { theTree } {
    variable ::AIEnv::GUIManagement::TreeFrame
    variable ::AIEnv::GUIManagement::BGColor
    variable ::AIEnv::GUIManagement::CATRootDir
    variable ::AIEnv::GUIManagement::IconDir
    variable aieTree
    variable VisibilityImages
    variable BubbleHelp
    global aie_geoTypeVis aie_meshTypeVis env aie_guiOpt icon_size1 

    array set aie_geoTypeVis { curve 2 point 0 surface 2 body 2 density 0}
    array set aie_meshTypeVis {
        line 2 node 0 shell 2 volume 0 tri 2 quad 2 hexa 2 tetra 2 penta 2 pyra 2
    }

    set IconDir "icons"

    # create the frame
    set ScrollWin [ScrolledWindow $theTree.f -auto both -scrollbar both]

    # create the tree, linked to scrolls
    set trp ::AIEnv::GUIManagement::Tree::
    set aieTree [ Tree $ScrollWin.theTree -width 40 -height 5 -bg white \
		      -opencmd ${trp}OnNodeExpand \
		      -linesfill gray50 -dragenabled 1 -dropenabled 1 \
		      -dragevent 1 -dropovermode n -draginitcmd ${trp}CanDrag \
		      -dropovercmd ${trp}CanDrop -dropcmd ${trp}DoDrop]

    $ScrollWin setwidget $aieTree
    pack $ScrollWin -fill both -expand yes

    # Put the name of the frame in TreeFrame
    set TreeFrame $ScrollWin
    set icon_size3 12
    if { $icon_size1 == 24 } {set icon_size3 12}
    if { $icon_size1 == 35 } {set icon_size3 16}
    #build icons
    set isVisImg [image create photo -format GIF \
		      -file [file join $CATRootDir "$IconDir/treeShow$icon_size3.gif" ]]
    set notVisImg [image create photo -format GIF \
		       -file [file join $CATRootDir "$IconDir/treeNoShow$icon_size3.gif" ]]
    set someVisImg [image create photo -format GIF \
			-file [file join $CATRootDir "$IconDir/treeShowGray$icon_size3.gif" ]]
    set isVisInactiveImg [image create photo -format GIF \
		      -file [file join $CATRootDir "$IconDir/treeShowInactive$icon_size3.gif" ]]
    set notVisInactiveImg [image create photo -format GIF \
		       -file [file join $CATRootDir "$IconDir/treeNoShowInactive$icon_size3.gif" ]]

    set VisibilityImages(isVisImg) $isVisImg
    set VisibilityImages(notVisImg) $notVisImg
    set VisibilityImages(someVisImg) $someVisImg
# Additional icons for inactive connectors. These should be identical with the current
# icons for active connectors if the feature is to be flagged as Beta, Anand.
    set VisibilityImages(isVisInactiveImg) $isVisInactiveImg
    set VisibilityImages(notVisInactiveImg) $notVisInactiveImg

    # Build the root base branches

    if {$aie_guiOpt(withMedModel)} {
       global tdv_default
       initModel $tdv_default
    }

    setupBindings
}

# -----------------

proc ::AIEnv::GUIManagement::Tree::delayedInsert {pos parent name args} {
    variable InsertNodeCmd
    variable ChildNodeOrder
    
    #puts [list delayedInsert $pos $parent $name $args]
    
    if ![info exists InsertNodeCmd($name)] {
	set InsertNodeCmd($name) [concat [list $pos $parent $name] $args]
	if {![info exists ChildNodeOrder($parent)] || ![lmember $ChildNodeOrder($parent) $name]} {
	    lappend ChildNodeOrder($parent) $name
	}
    }
}

proc ::AIEnv::GUIManagement::Tree::doInsert {pos parent name args} {
    variable InsertNodeCmd
    variable aieTree
    variable doInsertAlso
    variable ChildNodeOrder

    set par $parent
    if ![$aieTree exists $par] {
	if ![info exists InsertNodeCmd($par)] {
	    error "parent tree node $par doesn't exist"
	}
	eval doInsert $InsertNodeCmd($par)
	#catch {unset InsertNodeCmd($par)} ;# could have been already deleted
    }
    if ![$aieTree exists $name] {
	eval $aieTree insert $pos $parent $name $args
    }
    if [info exists doInsertAlso($name)] {
	foreach name2 $doInsertAlso($name) {
	    if {![$aieTree exists $name2] && [info exists InsertNodeCmd($name2)]} {
		eval doInsert $InsertNodeCmd($name2)
		#unset InsertNodeCmd($name2)
	    }
	}
	# for example, when we have subsets we may want to add them later
	#unset doInsertAlso($name)
    }
    if [info exists ChildNodeOrder($parent)] {
	set order ""
	set alldone 1
	foreach n $ChildNodeOrder($parent) {
	    if [$aieTree exists $n] {
		lappend order $n
	    } else {
		set alldone 0
	    }
	}
	$aieTree reorder $parent $order
	#if $alldone { unset ChildNodeOrder($parent) }
    }
}

proc ::AIEnv::GUIManagement::Tree::doInsertIfNeeded {name} {
    variable InsertNodeCmd
    variable aieTree

    if {![$aieTree exists $name] && [info exists InsertNodeCmd($name)]} {
	eval doInsert $InsertNodeCmd($name)
	#catch {unset InsertNodeCmd($name)}
    }
}

proc ::AIEnv::GUIManagement::Tree::doInsertAll {} {
    variable InsertNodeCmd
    variable aieTree
    global doInsertAllDone

    set doInsertAllDone 1
    foreach name [array names InsertNodeCmd] {
        if {![$aieTree exists $name]} {
            eval doInsert $InsertNodeCmd($name)
            #catch {unset InsertNodeCmd($name)}
        }
    }
}

# -----------------

proc ::AIEnv::GUIManagement::Tree::initModel {win} {
    variable aieTree
    variable VisibilityImages
    variable BubbleHelp
    variable NodeCommand
    variable InsertNodeCmd
    variable doInsertAlso
    global aie_geoTypeVis aie_meshTypeVis env aie_guiOpt aie_tree_nodes
    global aie_tree_param_nodes aie_tree_nodes_no_glasses

    set isVisImg  $VisibilityImages(isVisImg)
    set notVisImg $VisibilityImages(notVisImg)

    # Rather than inserting all the nodes up-front just add the command to the
    # InsertNodeCmd array, so it will be created on-demand.  (This one is immediate
    # but the others are delayed)
    doInsert end root modelNode -text Model -open 1 -data "model $win *"

    #delayedInsert end modelNode familyNode -text Families

    #set BubbleHelp(geomNode,0) "Geometry display options"
    set BubbleHelp(geomNode,1) "Display/blank Visible Geometry"
    delayedInsert end modelNode geomNode -text Geometry \
	-image $notVisImg -data "geometry *"

    set BubbleHelp(meshNode,0) "Mesh display options"
    set BubbleHelp(meshNode,1) "Display/blank Visible Mesh"
    delayedInsert end modelNode meshNode -text Mesh \
	-image $notVisImg -data "mesh *"

    # blocking
    set BubbleHelp(blockingNode,1) "Display/blank Blocking"
    delayedInsert end modelNode blockingNode -text "Blocking" \
        -data "blocking *" -image $notVisImg

    delayedInsert end modelNode lcsNode -text "Local Coord Systems" \
	-data "lcs *"  ;# -image $isVisImg
    
    if {![info exists env(AI_ENV_CFD_ONLY)] || !$env(AI_ENV_CFD_ONLY)} {

        delayedInsert end modelNode tblNode -text "Tables" \
            -data "tbl *"

        delayedInsert end modelNode partbcNode -text "Element Properties" \
            -data "elem *" -image $notVisImg

	foreach nn [lsort [array names aie_tree_nodes]] {
	    if [info exists aie_tree_nodes_no_glasses($nn)] {
		set im ""
	    } else {
		set im $isVisImg
	    }
	    delayedInsert end modelNode ${nn}Node -text $aie_tree_nodes($nn) \
		-image $im -data "$nn *"
	}
    }
    foreach name [lsort [array names aie_tree_param_nodes]] {
	set tn $aie_tree_param_nodes($name)
	set par [lindex $tn 0]; if {$par == ""} { set par model }
	set cmd [lindex $tn 1]
	set text [lindex $tn 2]
	set bub [lindex $tn 3]
	doInsert end ${par}Node ${name}Node -text $text -data "$name *"
	foreach n {0 1} { set BubbleHelp(${name}Node,$n) $bub }
	set NodeCommand(${name}Node) $cmd
    }
    
    delayedInsert end modelNode partNode -text "Parts" \
	-image $isVisImg -data "part *"
    set BubbleHelp(partNode,0) "Create a new part"
    set BubbleHelp(partNode,1) "Display/blank all parts"

    if {![info exists env(AI_ENV_CFD_ONLY)] || !$env(AI_ENV_CFD_ONLY)} {
        delayedInsert end modelNode paramsNode -text "Parameters" \
            -data "params *"

	delayedInsert end modelNode subcaseNode -text "Subcases" \
	    -data "subcase *" ;# -image $isVisImg

	delayedInsert end modelNode lsdynaParamsNode -text "LS-Dyna Parameters" \
	    -data "lsdyna_params *" ;# -image $isVisImg
    }

    # Fixed children: for geom
    set BubbleHelp(geomPointNode,0) "Point display options"
    set BubbleHelp(geomPointNode,1) "Display/blank visible points"
    #delayedInsert end geomNode geomPointNode -text Points -image $isVisImg

    set BubbleHelp(geomCurveNode,0) "Curve display options"
    set BubbleHelp(geomCurveNode,1) "Display/blank visible curves"
    #delayedInsert end geomNode geomCurveNode -text Curves -image $isVisImg

    set BubbleHelp(geomSurfNode,0) "Surface display options"
    set BubbleHelp(geomSurfNode,1) "Display/blank visible surfaces"
    #delayedInsert end geomNode geomSurfNode -text Surfaces -image $isVisImg

    set BubbleHelp(geomBodyNode,0) "Body display options"
    set BubbleHelp(geomBodyNode,1) "Display/blank visible bodies"
    #delayedInsert end geomNode geomBodyNode -text Bodies -image $isVisImg

    set BubbleHelp(geomDensityNode,0) "Density display options"
    set BubbleHelp(geomDensityNode,1) "Display/blank visible densities"
    #delayedInsert end geomNode geomDensityNode -text Densities -image $isVisImg

    delayedInsert end geomNode geom_subsetNode -text "Subsets" \
	-image $isVisImg -data "geom_subset *"
    set BubbleHelp(geom_subsetNode,0) "Create a new geometry subset"
    set BubbleHelp(geom_subsetNode,1) "Display/blank all geometry subsets"

    lappend doInsertAlso(geomNode) geom_subsetNode

    # Fixed children: for Unsmesh
    set BubbleHelp(meshPointNode,0) "Point display options"
    set BubbleHelp(meshPointNode,1)  "Display/blank visible points"
    #delayedInsert end meshNode meshPointNode -text "Points" -image $notVisImg

    set BubbleHelp(meshLineNode,0) "Line display options"
    set BubbleHelp(meshLineNode,1)  "Display/blank visible Lines"
    #delayedInsert end meshNode meshLineNode -text "Lines" -image $notVisImg

    set BubbleHelp(meshShellNode,0) "Shell display options"
    set BubbleHelp(meshShellNode,1)  "Display/blank visible Shells"
    #delayedInsert end meshNode meshShellNode -text "Shells" -image $notVisImg

    set BubbleHelp(meshVolumeNode,0) "Volume display options"
    set BubbleHelp(meshVolumeNode,1)  "Display/blank visible Volumes"
    #delayedInsert end meshNode meshVolumeNode -text "Volumes" -image $notVisImg

    delayedInsert end meshNode mesh_subsetNode -text "Subsets" \
	-image $isVisImg -data "mesh_subset *"
    set BubbleHelp(mesh_subsetNode,0) "Create a new mesh subset"
    set BubbleHelp(mesh_subsetNode,1) "Display/blank all mesh subsets"

    lappend doInsertAlso(meshNode) mesh_subsetNode

    #delayedInsert end meshNode mesh_contactNode -text "Contact" -image $notVisImg -data "mesh_contact *"
    #lappend doInsertAlso(meshNode) mesh_subsetNode mesh_contactNode

    # Fixed children: for Strmesh
    set BubbleHelp(mesh_domainNode,0) "Domain display options"
    set BubbleHelp(mesh_domainNode,1)  "Display/blank visible Domains"
    #delayedInsert end meshNode mesh_domainNode -text "Domains" -data "strmesh domain" -image $notVisImg

    set BubbleHelp(mesh_subfaceNode,0) "Subface display options"
    set BubbleHelp(mesh_subfaceNode,1)  "Display/blank visible Subfaces"
    #delayedInsert end meshNode mesh_subfaceNode -text "Subfaces" -data "strmesh subface" -image $notVisImg

    set BubbleHelp(mesh_edgeNode,0) "Edge display options"
    set BubbleHelp(mesh_edgeNode,1)  "Display/blank visible Edges"
    #delayedInsert end meshNode mesh_edgeNode -text "Edges" -data "strmesh edge" -image $notVisImg

    set BubbleHelp(mesh_vertexNode,0) "Vertex display options"
    set BubbleHelp(mesh_vertexNode,1)  "Display/blank visible Vertices"
    #delayedInsert end meshNode mesh_vertexNode -text "Vertices"  -data "strmesh vertex" -image $notVisImg

    # Fixed children: for Blocking
    #set BubbleHelp(block_curveNode,0) "Comp-curves display options"
    #set BubbleHelp(block_curveNode,1)  "Display/blank visible Comp-curves"
    #delayedInsert end blockingNode block_curveNode -text "Comp-Curves" -data "blocking curve" -image $notVisImg    
    set BubbleHelp(block_subsetNode,0) "Create a new Block subset"
    set BubbleHelp(block_subsetNode,1) "Display/blank all Block subsets"
    delayedInsert end blockingNode block_subsetNode -text "Subsets" \
	-image $isVisImg -data "block_subset *"
    lappend doInsertAlso(blockingNode) block_subsetNode

    set BubbleHelp(block_vertNode,0) "Vertices display options"
    set BubbleHelp(block_vertNode,1)  "Display/blank visible Vertices"
    #delayedInsert end blockingNode block_vertNode -text "Vertices" -data "blocking vert" -image $notVisImg

    set BubbleHelp(block_edgeNode,0) "Edges display options"
    set BubbleHelp(block_edgeNode,1)  "Display/blank visible Edges"
    #delayedInsert end blockingNode block_edgeNode -text "Edges" -data "blocking edge" -image $isVisImg

    set BubbleHelp(block_faceNode,0) "Faces display options"
    set BubbleHelp(block_faceNode,1)  "Display/blank visible Faces"
    #delayedInsert end blockingNode block_faceNode -text "Faces" -data "blocking face" -image $notVisImg

    set BubbleHelp(block_blockNode,0) "Blocks display options"
    set BubbleHelp(block_blockNode,1)  "Display/blank visible Blocks"
    #delayedInsert end blockingNode block_blockNode -text "Blocks" -data "blocking block" -image $notVisImg

    set BubbleHelp(block_meshNode,1) "Display/blank Preview-Mesh"
    #delayedInsert end blockingNode block_meshNode -text "Pre-Mesh" -data "blocking mesh" -image $notVisImg

}


proc ::AIEnv::GUIManagement::Tree::setupBindings {} {
    variable aieTree
    global aie_geoTypeVis aie_meshTypeVis env aie_guiOpt

    $aieTree bindText <ButtonRelease-1> {::AIEnv::GUIManagement::Tree::treeSelect 0}
    $aieTree bindImage <ButtonRelease-1> {::AIEnv::GUIManagement::Tree::treeSelect 1}

    $aieTree bindText <Shift-ButtonRelease-1> {::AIEnv::GUIManagement::Tree::treeShiftSelect 0}
    $aieTree bindImage <Shift-ButtonRelease-1> {::AIEnv::GUIManagement::Tree::treeShiftSelect 1}

    $aieTree bindText <Control-ButtonRelease-1> {::AIEnv::GUIManagement::Tree::treeControlSelect 0}
    $aieTree bindImage <Control-ButtonRelease-1> {::AIEnv::GUIManagement::Tree::treeControlSelect 1}

    $aieTree bindText <ButtonPress-3> {::AIEnv::GUIManagement::Tree::treeRightClick %X %Y 0}
    $aieTree bindImage <ButtonPress-3> {::AIEnv::GUIManagement::Tree::treeRightClick %X %Y 1}

    # Do not set Double-1 event for image: Interferance with slow "visibility toggle" command
    # For Text: Double-1 is the same as "treeSelect 1" (e.g. toggle part visibility if image exists)
    $aieTree bindText <Double-1> {::AIEnv::GUIManagement::Tree::treeDoubleClick 0}

    $aieTree bindImage <Shift-ButtonRelease-1> \
	::AIEnv::GUIManagement::Tree::treeShiftClick
    $aieTree bindImage <Control-ButtonRelease-1> \
	::AIEnv::GUIManagement::Tree::treeControlClick

    $aieTree bindText <Shift-ButtonRelease-1> \
	::AIEnv::GUIManagement::Tree::treeShiftClick
    $aieTree bindText <Control-ButtonRelease-1> \
	::AIEnv::GUIManagement::Tree::treeControlClick
    $aieTree bindText <Button-1> ""
    $aieTree bindImage <Button-1> ""
    $aieTree bindText <Enter> "::AIEnv::GUIManagement::Tree::treeHighlight 1 0"
    $aieTree bindText <Leave> "::AIEnv::GUIManagement::Tree::treeHighlight 0 0"
    $aieTree bindImage <Enter> "::AIEnv::GUIManagement::Tree::treeHighlight 1 1"
    $aieTree bindImage <Leave> "::AIEnv::GUIManagement::Tree::treeHighlight 0 1"

    CreateVisibilityFunctionMap
    
    bind . <KeyPress-f> {aie_tree update_families}
}

proc ::AIEnv::GUIManagement::Tree::CanDrag {xtree node {topl ""}} {
    global aie_prop_subtype
    
    set type [lindex [$xtree itemcget $node -data] 0]
    set name [lindex [$xtree itemcget $node -data] 1]
    if [info exists aie_prop_subtype($type)] {
	    set type $aie_prop_subtype($type)
    }
    
    # This is needed to make drag and drop work correctly
    if {[$xtree selection get] == ""} { $xtree selection set $node }
    
    switch $type {
        part {
            if {$name == "*"} { return "" }
            return [list TREE_NODE move $node]
        }
        default {
            if {[info command aie_get_${type}_set] != ""} {
                return [list TREE_NODE move $node]
            } else {
                return ""
            }
        }
    }
}

proc ::AIEnv::GUIManagement::Tree::CanDrop {xtree dummy droploc op dtype node} {
    global aie_prop_subtype
    
    set dest [lindex $droploc 1]
    # Make sure we are not moving something to itself or a child or its parent.
    for {set pp $dest} {$pp != "root"} {set pp [$xtree parent $pp]} {
        if {$pp == $node} { return "2 node" }
    }
    if {[$xtree parent $node] == $dest} { return "2 node" }
    set dtype [lindex [$xtree itemcget $dest -data] 0]
    set dname [lindex [$xtree itemcget $dest -data] 1]
    set stype [lindex [$xtree itemcget $node -data] 0]
    set sname [lindex [$xtree itemcget $node -data] 1]

    if [info exists aie_prop_subtype($dtype)] {
        set dtype $aie_prop_subtype($dtype)
    }
    if [info exists aie_prop_subtype($stype)] {
        set stype $aie_prop_subtype($stype)
    }
    
    if {($dtype == "part") && ($stype == "part")} {
	    # How do we know the destination is an assembly?
	    # For now just say the color is black (or SystemWindowText).
	    # Also don't allow renaming ORFN
        if {$sname == "ORFN"} {
            return "2 node"
        } elseif {[$xtree itemcget $dest -fill] == "black" || [$xtree itemcget $dest -fill] == "SystemWindowText"} {
            return "3 node"
        } else {
            return "2 node"
        }
    } elseif {[info command aie_get_${dtype}_set] != ""} {
        if {($dtype != $stype) || ($dname != "\#")} {
            return "2 node"
        } else {
            return "3 node"
        }
    } else {
        return "2 node"
    }
}

proc ::AIEnv::GUIManagement::Tree::DoDrop {xtree dummy droploc op dtype dummynode} {
    variable aieTree
    
    set dest [lindex $droploc 1]
    if [catch {$xtree itemcget $dest -data} ddata] {
        mess "Internal error: the node $dest was not in the tree!\n" red
        return
    }
    foreach node [$xtree selection get] {
        if {$node == $dest} continue
        set sdata [$xtree itemcget $node -data]
        switch [lindex $sdata 0] {
            part {
		        if {[$xtree parent $node] != $dest} {
		            if {[lindex $sdata 1] == "*"} {
		                $aieTree selection clear
		                return
		            }
		            aie_move_assembly [lindex $sdata 1] [lindex $ddata 1]
		        }
	        }
	        default {
		        if {[lindex $ddata 1] == "\#"} {
		            aie_change_set [lindex $sdata 0] [lindex $sdata 1] [lindex $ddata 2]
		            aie_edit_[lindex $sdata 0] [lindex $sdata 1]
		        }
	        }
	    }
    }
}

proc ::AIEnv::GUIManagement::Tree::getSelection {what} {
    variable aieTree
    set ret ""
    foreach node [$aieTree selection get] {
	    set data [$aieTree itemcget $node -data]
	    if {([lindex $data 0] == $what) && ([lindex $data 1] != "*")} {
	        lappend ret [lindex $data 1]
	    }
    }
    return $ret
}

# Delete any stuff that we created in the process of loading up the data

proc ::AIEnv::GUIManagement::Tree::clear {what} {
    variable aieTree
    global aie_subents aie_tree_nodes
    variable VisibilityImages

    switch $what {
	everything {
	    $aieTree delete [$aieTree nodes modelNode]
	}
	geom {
	    # If there is mesh still don't touch this	  	    
	    if ![ic_uns_is_loaded] {
		foreach n {part} {
		    if [$aieTree exists ${n}Node] {
			$aieTree delete [$aieTree nodes ${n}Node]
		    }
		}
		catch {unset aie_subents}
	    }
	    UpdateGeomNodes
	}
	mesh {
	    # If there is geometry still don't touch this
	    if {(![ic_geo_is_loaded]) && (![ic_hex_blocking_loaded])} {
		foreach n {part} {
		    if [$aieTree exists ${n}Node] {
			$aieTree delete [$aieTree nodes ${n}Node]
		    }
		}
		catch {unset aie_subents}
	    }
	    UpdateMeshNodes	    
	}
	blocking {
	    if {(![ic_uns_is_loaded]) && (![ic_geo_is_loaded])} {
		foreach n {part} {
		    if [$aieTree exists ${n}Node] {
			$aieTree delete [$aieTree nodes ${n}Node]
		    }
		}
		catch {unset aie_subents}
	    }
	    UpdateBlockingNodes
	}
	attr {
	    foreach n [array names aie_tree_nodes] {
		if [$aieTree exists ${n}Node] {
		    $aieTree delete [$aieTree nodes ${n}Node]
		}
	    }
	    if [$aieTree exists partbcNode] {
		$aieTree delete [$aieTree nodes partbcNode]
	    }
	}
	params {
	    # FIXME
	
	    foreach n {mat lcs tbl params subcase lsdyna_params} {
		if [$aieTree exists ${n}Node] {
		    $aieTree delete [$aieTree nodes ${n}Node]
		}
	    }
	}
	default {
	    # e.g., {"connector" == $what}
	    if [$aieTree exists ${what}Node] {
		$aieTree delete [$aieTree nodes ${what}Node]	    
		if ![llength [$aieTree nodes ${what}Node]] {
		    $aieTree itemconfigure ${what}Node -image $VisibilityImages(notVisImg)
		}
	    }
	}
    }
}

proc ::AIEnv::GUIManagement::Tree::AddTopo {name {vis 0}} {
    variable aieTree
    variable VisibilityImages
    
    set type topo
    set parent topo
    set nname $type-$name
    
    set par ${parent}Node  
    if $vis {
	set visim $VisibilityImages(isVisImg)
    } else {
	set visim $VisibilityImages(notVisImg)
    }
   
    if ![$aieTree exists $nname] {
	doInsert end $par $nname
	SortChildren $par
    } else {
	return
    }
    $aieTree itemconfigure $nname -text  $name \
	-data [list $type $name] -image $visim
}

# ------------------------------------------------------------

proc ::AIEnv::GUIManagement::Tree::addMultipleParam {par name tn} {
    variable NodeCommand
    variable BubbleHelp
    variable aieTree
    
    if ![$aieTree exists ${par}Node] {
	mess "Error: tree node for parameter $par does not exist\n" red
	return
    }
    
    set node $par/${name}Node
    set dezname edit_${par}_DEZ
    regsub -all : $dezname _ dezname
    
    doInsert end ${par}Node $node -text $name -data [list $par $name]
    
    set cmd [lindex $tn 1]
    set bub [lindex $tn 3]
    foreach n {0 1} { set BubbleHelp($node,$n) $bub }
    
    set NodeCommand($node) [list bcc_edit_param_node $par $par/$name $dezname]
}

proc ::AIEnv::GUIManagement::Tree::deleteMultipleParam {type name} {
    variable aieTree
    
    $aieTree delete $type/${name}Node
}

proc ::AIEnv::GUIManagement::Tree::renameMultipleParam {type name newname} {
    variable aieTree
    variable NodeCommand
    variable BubbleHelp
    
    set onode $type/${name}Node
    set nnode $type/${newname}Node
    set par ${type}Node
    set ind [$aieTree index $onode]
    doInsert $ind $par $nnode -text $newname -data [list $type $name]
    $aieTree delete $onode
    
    foreach n {0 1} {
	if [info exists BubbleHelp($onode,$n)] {
	    set BubbleHelp($nnode,$n) $BubbleHelp($onode,$n)
	}
    }
    set NodeCommand($nnode) $NodeCommand($onode)
}

# ------------------------------------------------------------

proc ::AIEnv::GUIManagement::Tree::treeHighlight {on image node} {
    variable BubbleHelp
    variable aieTree
    variable prev_node_color
    
    if ![$aieTree exists $node] return
    
    if [info exists BubbleHelp($node,$image)] {
	if $on {
	    bubble_action enter $aieTree $BubbleHelp($node,$image)
	} else {
	    bubble_action leave $aieTree
	}
    }

    set data [$aieTree itemcget $node -data]
    set type [lindex $data 0]

    if $on {
	# Don't want to overwrite the previously remembered color.
	if [info exists prev_node_color($node)] return
	
	set prev_node_color($node) [$aieTree itemcget $node -fill]
	#mess $prev_node_color($node)\n
	# On windows SystemWindowText is used instead of black.  Not sure why.
	if {($prev_node_color($node) == "black") || ($prev_node_color($node) == "SystemWindowText")} {
	    $aieTree itemconfigure $node -fill red
	} else {
	    $aieTree itemconfigure $node -fill black
	}
    } elseif [info exists prev_node_color($node)] {
	$aieTree itemconfigure $node -fill $prev_node_color($node)
	unset prev_node_color($node)
    } elseif {(($type == "part") || ($type == "geom_subset") || ($type == "mesh_subset") || ($type == "contact")) && ([$aieTree itemcget $node -fill] == "red")} {
	$aieTree itemconfigure $node -fill black
	
    }
}
    
# Hard wire a table of functions to be called based on the type of
# node. The last arguement is left off 

proc ::AIEnv::GUIManagement::Tree::CreateVisibilityFunctionMap {} {
    variable VisibilityFunctionMap	
    variable VisibilityContextMenuMap
    variable NodeExpandMap
    variable NodeNameToTypeMap

    array set VisibilityFunctionMap {
        geomNode         {::AIEnv::GUIManagement::Tree::ToggleGeoVisible All}
        geomPointNode    {::AIEnv::GUIManagement::Tree::ToggleGeoVisible point}
        geomCurveNode    {::AIEnv::GUIManagement::Tree::ToggleGeoVisible curve}
        geomSurfNode     {::AIEnv::GUIManagement::Tree::ToggleGeoVisible surface }
        geomBodyNode     {::AIEnv::GUIManagement::Tree::ToggleGeoVisible body}
        geomDensityNode  {::AIEnv::GUIManagement::Tree::ToggleGeoVisible density}
        meshNode         {::AIEnv::GUIManagement::Tree::ToggleMeshVisible}
        meshPointNode    {::AIEnv::GUIManagement::Tree::ToggleUnsMeshVisible node}
        meshLineNode     {::AIEnv::GUIManagement::Tree::ToggleUnsMeshVisible line}
        meshShellNode    {::AIEnv::GUIManagement::Tree::ToggleUnsMeshVisible shell }
        meshVolumeNode   {::AIEnv::GUIManagement::Tree::ToggleUnsMeshVisible volume}
        meshTriNode      {::AIEnv::GUIManagement::Tree::ToggleUnsMeshVisible tri}
        meshQuadNode     {::AIEnv::GUIManagement::Tree::ToggleUnsMeshVisible quad}
        meshTetraNode    {::AIEnv::GUIManagement::Tree::ToggleUnsMeshVisible tetra}
        meshHexaNode     {::AIEnv::GUIManagement::Tree::ToggleUnsMeshVisible hexa}
        meshPyraNode     {::AIEnv::GUIManagement::Tree::ToggleUnsMeshVisible pyra}
        meshPentaNode    {::AIEnv::GUIManagement::Tree::ToggleUnsMeshVisible penta}
        matNode          {::AIEnv::GUIManagement::Tree::ShowGroup mat}
        lcsNode          {::AIEnv::GUIManagement::Tree::ShowGroup lcs}
        tblNode          {::AIEnv::GUIManagement::Tree::ShowGroup tbl}
        paramsNode       {::AIEnv::GUIManagement::Tree::ShowGroup params}
        lsdynaParamsNode {::AIEnv::GUIManagement::Tree::ShowGroup lsdyna_params}
        partNode         {::AIEnv::GUIManagement::Tree::ShowGroup part}
        XXgeom_subsetNode  {::AIEnv::GUIManagement::Tree::ToggleGeoVisible subset}
        XXmesh_subsetNode  {::AIEnv::GUIManagement::Tree::ToggleUnsMeshVisible subset}
        contactNode      {::AIEnv::GUIManagement::Tree::ToggleUnsMeshVisible contact}
	    subcaseNode      {::AIEnv::GUIManagement::Tree::ShowGroup subcase}
    }
    
    array set VisibilityContextMenuMap {
        modelNode     modelContextMenu
        geomPointNode   pointContextMenu
        geomCurveNode   curveContextMenu
        geomSurfNode    surfContextMenu
        geomBodyNode    bodyContextMenu
        geomDensityNode densityContextMenu
        geomNode geomContextMenu
        meshNode meshContextMenu
        meshLineNode   lineContextMenu
        meshShellNode  shellContextMenu
        meshVolumeNode volumeContextMenu
        mesh_domainNode  domainContextMenu
        mesh_subfaceNode subfaceContextMenu
        mesh_edgeNode    edgeContextMenu
        mesh_vertexNode  vertexContextMenu
        blockingNode  blockingContextMenu
        block_vertNode  blockVertContextMenu
        block_edgeNode  blockEdgeContextMenu
        block_faceNode  blockFaceContextMenu
        block_blockNode blockBlockContextMenu
        block_meshNode  blockMeshContextMenu
    }
    
    array set NodeExpandMap {
        geomNode {::AIE::GUIManagement::Tree::ExpandGeometry}
    }
    
    array set NodeNameToTypeMap {
        geomNode        geometry
        geomPointNode   point
        geomCurveNode   curve
        geomSurfNode    surface
        geomBodyNode    body
        geomDensityNode density
        meshNode        mesh
        meshPointNode   node
        meshLineNode    line
        meshShellNode   shell
        meshVolumeNode  volume
        meshTriNode     tri
        meshQuadNode    quad
        meshTetraNode   tetra
        meshHexaNode    hexa
        meshPentaNode   penta
        meshPyraNode    pyra
    }
}

proc ::AIEnv::GUIManagement::Tree::treeSelect {image theNode} {
    variable VisibilityFunctionMap
    variable VisibilityImages
    variable aieTree
    global aie_bctypes_used aie_prop_subtype

    if {$theNode == "lcsNode"} return
    if {[$aieTree parent $theNode] == "lcsNode"} {
        ShowLCS $image $theNode
        return
    }
    set data [$aieTree itemcget $theNode -data]
    set type [lindex $data 0]
	if {$type == "part"} {
		$aieTree selection set $theNode
		if $image {
            Parts toggle [lindex $data 1]
		}
		return
	}
    #puts "treeSelect $image $theNode $data"
    
    if !$image {
	switch $type {
	    geom_subset - mesh_subset - contact - part {
		$aieTree selection set $theNode
		
		# For now disable this because double-click makes stuff flash and that
		# is not nice
		# set image 1
	    }
	    v3surfgrp - v3surfgrp_root - v3surfgrp_cycle {
		# $aieTree selection set $theNode
		SfgTree::selecttree 1 $aieTree $theNode
                
		# For now disable this because double-click makes stuff flash and that
		# is not nice
		# set image 1
	    }
	    v3surface {
		SfgTree::selecttree 1 $aieTree $theNode   
                
		# For now disable this because double-click makes stuff flash and that
		# is not nice
		# set image 1
	    }
	    v3strmgrp {
		StrmTree::selecttree 1 $aieTree $theNode
		v3StrmPropertiesDEZ show
                
		# For now disable this because double-click makes stuff flash and that
		# is not nice
		# set image 1
	    }
	    v3doc_root - v3doc_summary - v3doc_cfd - v3doc_efd \
		  - v3doc_chapter - v3doc_section \
		  - v3doc_graphics - v3doc_text - v3doc_table {
		aie_v3p_doc_select $aieTree $theNode $type 1
	    }
            gsView {
                aie_gsview_cmd $aieTree $theNode apply
            }
	    default {
                $aieTree selection clear
		# If nothing else is supposed to happen then treat a click on the
		# name the same as on the image
		
		# For now disable this because double-click makes stuff flash and that
		# is not nice
		# set image 1
	    }
	}
    }
    if $image {
	if {[array names VisibilityFunctionMap $theNode] != ""} {
	    eval "$VisibilityFunctionMap($theNode) $theNode"
	} else {
	    # this is a mess.  It's got to be fixed ****
	    switch $theNode {
		element_prop_0d_partbcNode - element_prop_1d_partbcNode -
		element_prop_2d_partbcNode - element_prop_3d_partbcNode { set type elem }
	    }
	    switch $type {		
		blocking - block_subset { ToggleBlockingVisibility $type [lindex $data 1] }
		topo {     ToggleTopoVisibility $type [lindex $data 1]}
		strmesh  { ToggleStrMeshVisibility $type [lindex $data 1]}
                v3surface - v3surfgrp - v3surfgrp_root {
                   if {[info command aie_toggle_$type] != ""} {
                      aie_toggle_$type $aieTree $theNode
                   }
                }
                v3strmgrp_root - v3strmgrp {
                   if {[info command aie_toggle_$type] != ""} {
                      aie_toggle_$type $aieTree $theNode
                   }
                }
                vpcolormap {
                   if {[info command aie_toggle_$type] != ""} {
                      aie_toggle_$type $aieTree $theNode
                   }
                }
                vframe_root - vframe {
                   if {[info command ::VFrameTree::toggle] != ""} {
                      VFrameTree::toggle $aieTree $theNode
                   }
                }
                v3pts_root - v3pts {
                   if {[info command aie_toggle_$type] != ""} {
                      aie_toggle_$type $aieTree $theNode
                   }
                }
		elem {
		    # This is a mess.  It's got to be fixed ***
		    set ta [tdv_active 0]
		    busy 1
		    set im [$aieTree itemcget $theNode -image]
		    if {$im == $VisibilityImages(isVisImg)} { set on 0 } else { set on 1 }
		    foreach ch [DescendantsWithData $aieTree $theNode ""] {
			set dat [$aieTree itemcget $ch -data]
			::AIEnv::GUIManagement::Tree::ToggleGroupVisibility [lindex $dat 0] \
			    [lindex $dat 1] $on
			if $on {
			    $aieTree itemconfigure $ch -image $VisibilityImages(isVisImg)
			} else {
			    $aieTree itemconfigure $ch -image $VisibilityImages(notVisImg)
			}
		    }
		    if $on {
			$aieTree itemconfigure $theNode -image $VisibilityImages(isVisImg)
		    } else {
			$aieTree itemconfigure $theNode -image $VisibilityImages(notVisImg)
		    }
		    busy 0
		    tdv_active $ta
		}
		default {
		    if 0 {
			if [info exists aie_bctypes_used($type)] {
			    set stuff $type
			    if [info exists aie_prop_subtype($type)] {
				set stuff $aie_prop_subtype($type)
			    }
			    ShowGroup $stuff $theNode
			}
		    }
		    ToggleGroupVisibility $type [lindex $data 1]
		}
	    }
	}
    }

    set topNode $theNode
    while {[set p [$aieTree parent $topNode]] != "root"} {set topNode $p}
    global tdv_current_viewer
    set viewer [lindex [$aieTree itemcget $topNode -data] 1]
    if {($tdv_current_viewer != $viewer) && [winfo exist $viewer]} {
       workspace_add $viewer [$aieTree itemcget $topNode -text]
       set tdv_current_viewer $viewer
    }
}

proc ::AIEnv::GUIManagement::Tree::treeShiftSelect {image theNode} {
    variable aieTree
    
    set data [$aieTree itemcget $theNode -data]
    set type [lindex $data 0]
    
    switch $type {
	geom_subset - mesh_subset - contact - part {
	    set sel [$aieTree selection get]
	    if {$sel == ""} {
		treeSelect $image $theNode
	    } else {
		set last [lindex $sel end]
		$aieTree selection add $theNode
		set p1 [$aieTree parent $last]
		set p2 [$aieTree parent $theNode]
		if {$p1 == $p2} {
		    set i1 [$aieTree index $last]
		    set i2 [$aieTree index $theNode]
		    if {$i2 < $i1} { set i3 $i1; set i1 $i2; set i2 $i3 }
		    set nodes [$aieTree nodes $p1 $i1 $i2]
		    eval $aieTree selection add $nodes
		}
	    }
	}
    }
}

proc ::AIEnv::GUIManagement::Tree::treeControlSelect {image theNode} {
    variable aieTree
    
    set data [$aieTree itemcget $theNode -data]
    set type [lindex $data 0]
    
    switch $type {
	geom_subset - mesh_subset - contact - part {
	    set sel [$aieTree selection get]
	    if {$sel == ""} {
		treeSelect $image $theNode
	    } elseif {[lsearch $sel $theNode] < 0} {
		$aieTree selection add $theNode
	    } else {
		$aieTree selection remove $theNode
	    }
	}
    }
}

proc ::AIEnv::GUIManagement::Tree::treeDoubleClick {image theNode} {
# DoubleClick on image - no bind
# DoubleClick on Text - change visibility if there is image; Modify if no image
    variable VisibilityImages
    variable aieTree
    variable NodeCommand
    
	if $image return
    if [llength [$aieTree itemcget $theNode -image]] {
		treeSelect 1 $theNode
		return
	}		
    
    set data [$aieTree itemcget $theNode -data]
    
    #puts "treeDoubleClick $theNode $data"
    
    set type [lindex $data 0]
    set name [lindex $data 1]
    
    if [info exists NodeCommand($theNode)] {
	eval $NodeCommand($theNode)
    } elseif {($data == "mesh_subset *") || ($data == "geom_subset *")  || ($data == "contact *") || ($data == "part *")} {
	aie_edit_$type $name
    } elseif {($name != "*") && ($name != "Set") && ([info proc ::aie_edit_$type] != "")} {
	aie_edit_$type $name
    } elseif {($name != "*") && ($name != "Set") && ([info proc ::aie_editnode_$type] != "")} {
        aie_editnode_$type $aieTree $theNode $name
    } elseif [string equal [aie_connectors_attribute_name] $type] {
	aie_edit_[aie_connectors_attribute_name] $name
    }
}

proc ::AIEnv::GUIManagement::Tree::ToggleGeoVisible {geoType treeNode {make_on ""}} {
    variable VisibilityImages
    variable aieTree
    global aie_geoTypeVis
    # Three cases are possible.
    # 1. All of the objects are visible -> toggle them all
    #    to invisible
    # 2. Some of the objects are visible -> toggle them all
    #    to visible
    # 3. All of the objects are invisible ->toggle them all
    #    to visible

    if ![ic_geo_is_loaded] return
    
    if {$geoType == "All"} {
        set vis 2
        foreach type {point curve surface body density} {
            if [GetVisibility $type] {
                set vis 0
                break
            }
        }
        ShowGeometry $vis
        return
    }
    if {$geoType == "subset"} {
        if {$make_on == ""} {
            set n [lindex [$aieTree itemcget $treeNode -data] 1]
            set on [expr {[$aieTree itemcget $treeNode -image] == $VisibilityImages(isVisImg)}]
            aie_geom_subset_set_visible $n [expr !$on]
        } else {
            aie_geom_subset_set_visible * $make_on
        }
        return
    }
    if {([info exists aie_geoTypeVis($geoType)]) && ($aie_geoTypeVis($geoType) != 0)} {
        $aieTree itemconfigure $treeNode -image $VisibilityImages(notVisImg)
        set aie_geoTypeVis($geoType) 0
    } else {
        $aieTree itemconfigure $treeNode -image $VisibilityImages(isVisImg)
        set aie_geoTypeVis($geoType) 2
    }
    aie_updateGeoVis $geoType
}

proc ::AIEnv::GUIManagement::Tree::ToggleMeshVisible {treeNode} {
    variable VisibilityImages
    variable aieTree

    if [ic_uns_is_loaded] {
        ToggleUnsMeshVisible All meshNode	
    }
    if [ic_str_is_loaded] {
        ToggleStrMeshVisibility "" *
    }
}

proc ::AIEnv::GUIManagement::Tree::ToggleUnsMeshVisible {MeshType treeNode {on ""}} {
    variable VisibilityImages
    variable aieTree
    global aie_meshTypeVis

    if ![ic_uns_is_loaded] return
    if ![$aieTree exists $treeNode] return
    
    if {$MeshType == "subset"} {
	    set n [lindex [$aieTree itemcget $treeNode -data] 1]
	    if {$on != ""} {
	        aie_mesh_subset_set_visible $n $on
	        if $on {
		        set vi $VisibilityImages(isVisImg)
	        } else {
		        set vi $VisibilityImages(notVisImg)
	        }
	    } else {
	        if {[$aieTree itemcget $treeNode -image] == $VisibilityImages(isVisImg)} {
		        aie_mesh_subset_set_visible $n 0
		        set vi $VisibilityImages(notVisImg)
	        } else {
		        aie_mesh_subset_set_visible $n 1
		        set vi $VisibilityImages(isVisImg)
	        }
	    }
	    $aieTree itemconfigure $treeNode -image $vi
	    if {$n == "*"} {
	        foreach sn [$aieTree nodes $treeNode] {
		        $aieTree itemconfigure $sn -image $vi
	        }
	    }
	    return
    }
    if {$MeshType == "contact"} {
	    set n [lindex [$aieTree itemcget $treeNode -data] 1]
	    if {$on != ""} {
	        aie_show_contact $n $on
	        if $on {
		        set vi $VisibilityImages(isVisImg)
	        } else {
		        set vi $VisibilityImages(notVisImg)
	        }
	    } else {
	        if {[$aieTree itemcget $treeNode -image] == $VisibilityImages(isVisImg)} {
		        aie_show_contact $n 0
		        set vi $VisibilityImages(notVisImg)
	        } else {
		        aie_show_contact $n 1
		        set vi $VisibilityImages(isVisImg)
	        }
	    }
	    $aieTree itemconfigure $treeNode -image $vi
	    if {$n == "*"} {
	        foreach sn [$aieTree nodes $treeNode] {
		        $aieTree itemconfigure $sn -image $vi
	        }
	    }
	    return
    }
    if {$MeshType == "All"} {
	    if {([$aieTree itemcget meshNode -image] != $VisibilityImages(notVisImg)) || ($on == "0")} {
	        foreach t1 {node line shell volume tri quad tetra hexa penta pyra} t2 {Point Line Shell Volume Tri Quad Tetra Hexa Penta Pyra} {
		        if [$aieTree exists mesh${t2}Node] {
		            $aieTree itemconfigure mesh${t2}Node -image $VisibilityImages(notVisImg)
		        }
		        set aie_meshTypeVis($t1) 0
	        }
	        ToggleGroupVisibility mesh_subset * $on
	    } else {
            set shell_mesh 0
            set list1 {line shell tri quad}
            set list2 {Line Shell Tri Quad}
	        foreach t {Shell Tri Quad} {
		        if [$aieTree exists mesh${t}Node] {
		            set shell_mesh 1
		        }
	        }
            if !$shell_mesh {
                set list1 [concat $list1 {volume tetra hexa penta pyra}]
                set list2 [concat $list2 {Volume Tetra Hexa Penta Pyra}]
            }
	        foreach t1 $list1 t2 $list2 {
		        if [$aieTree exists mesh${t2}Node] {
		            $aieTree itemconfigure mesh${t2}Node -image $VisibilityImages(isVisImg)
		        }
		        set aie_meshTypeVis($t1) 2
	        }
	    }
    } else {
	    set types $MeshType
	    switch $MeshType {
	        shell { set types {tri quad} }
	        volume { set types {tetra hexa penta pyra} }
	    }
	    set isvis [expr {[$aieTree itemcget $treeNode -image] == $VisibilityImages(isVisImg)}]
	    foreach type $types {
	        if {$type == "node"} {
		        set treeNode meshPointNode ;# should fix inconsistent naming
	        } else {
		        set treeNode mesh[string totitle $type]Node
	        }
	        if ![$aieTree exists $treeNode] continue
	        # If its visible, toggle visibility off, otherwise turn it on
	        if {($on == "0") || (($on == "") && $isvis)} {
		        if [$aieTree exists $treeNode] {
		            $aieTree itemconfigure $treeNode -image $VisibilityImages(notVisImg)
		        }
		        set aie_meshTypeVis($type) 0
	        } else {
		        if [$aieTree exists $treeNode] {
		            $aieTree itemconfigure $treeNode -image $VisibilityImages(isVisImg)
		        }
		        set aie_meshTypeVis($type) 2
	        }
	        UpdateAncestors $treeNode
	    }
    }
    aie_updateMeshVis
}

proc ::AIEnv::GUIManagement::Tree::SaveVisibility {} {
    variable savedMeshVisibility
    variable savedGeomVisibility
    variable savedPartVisibility
    variable aieTree
    variable VisibilityImages
    global aie_meshTypeVis
    
    if ![info exists savedMeshVisibility] {
	set savedMeshVisibility ""
	foreach i {pyra penta tetra line hexa node quad tri} {
	    lappend savedMeshVisibility $i $aie_meshTypeVis($i)
	}
    }
    if ![info exists savedPartVisibility] {
	set savedPartVisibility ""
	foreach name [aie_list_parts 0] {
	    set nname part-$name
	    regsub -all {[ \t\n]} $nname _ nname
	    if ![$aieTree exists $nname] continue
	    
	    set im [$aieTree itemcget $nname -image]
	    if {$im == $VisibilityImages(isVisImg)} { set on 1 } else { set on 0 }
	    lappend savedPartVisibility $name $on
	}
    }
}

proc ::AIEnv::GUIManagement::Tree::RestoreVisibility {} {
    variable savedMeshVisibility
    variable savedGeomVisibility
    variable savedPartVisibility
    
    set ta [tdv_active 0]
    if [info exists savedMeshVisibility] {
	foreach {n v} $savedMeshVisibility {
	    ToggleUnsMeshVisible $n mesh[string totitle $n]Node $v
	}
	unset savedMeshVisibility
    }
    if [info exists savedPartVisibility] {
	foreach {p v} $savedPartVisibility {
	    ::AIEnv::GUIManagement::Tree::ToggleGroupVisibility part $p $v
	}
	unset savedPartVisibility
    }
    tdv_active $ta
}

proc ::AIEnv::GUIManagement::Tree::ToggleStrMeshVisibility {type ent {on ""}} {
    variable VisibilityImages
    variable aieTree
    global str_type_visible

    if ![ic_str_is_loaded] { return }

    if {$ent == "*"} {
        set nname meshNode
        set im [$aieTree itemcget $nname -image]
        if {$im == $VisibilityImages(notVisImg)} { 	   
	        set on 1
	        set ents {domain}
	        $aieTree itemconfigure $nname -image $VisibilityImages(isVisImg)
	    } else { 
	        set on 0
	        set ents {domain subface edge vertex}
	        $aieTree itemconfigure $nname -image $VisibilityImages(notVisImg)
	    }
	    foreach ent $ents {
	        ToggleStrMeshVisibility $type $ent $on
	    }
	    UpdateAncestors mesh_domainNode
    }
    
    set nname mesh_${ent}Node
    set up_a 0
    if {$on == ""} {
        set im [$aieTree itemcget $nname -image]
        if {$im == $VisibilityImages(isVisImg)} { set on 0 } else { set on 1 }
        set up_a 1
    }

    if $on {
        $aieTree itemconfigure $nname -image $VisibilityImages(isVisImg)
    } else {
        $aieTree itemconfigure $nname -image $VisibilityImages(notVisImg)
    }

    set str_type_visible($ent) $on
    disp_change_overall_visible $ent
    if $up_a { UpdateAncestors $nname }
}

proc ::AIEnv::GUIManagement::Tree::ToggleBlockingVisibility {type ent {on ""}} {
    variable VisibilityImages
    variable aieTree
    global display_flag
    global fam_visible 
    
    if ![ic_hex_blocking_loaded] { return }
    set up_a 0
    if {$on == ""} {
        set up_a 1	
    }
    if {$type == "block_subset"} {
	if {$ent == "*"} {
	    set nname block_subsetNode 
	    set im [$aieTree itemcget $nname -image]
	    if {$on == ""} {
		if {$im == $VisibilityImages(notVisImg)} {
		    set on 1
		} else {
		    set on 0
		}
	    }
	    if $on {
		$aieTree itemconfigure $nname -image $VisibilityImages(isVisImg)
	    } else {
		$aieTree itemconfigure $nname -image $VisibilityImages(notVisImg)
	    }

	    foreach child [$aieTree nodes block_subsetNode] {
		ToggleBlockingVisibility block_subset [string trimleft $child  block_subset-] $on
	    }
	} else {
	    set nname block_subset-$ent
	    set im [$aieTree itemcget $nname -image]
	    if {$on == "same" } {
		if {$im == $VisibilityImages(notVisImg)} { set on 0	} else { set on 1 }
	    }
	    if {$on == "" } {
		if {$im == $VisibilityImages(notVisImg)} { set on 1	} else { set on 0 }
	    }	
	    if $on {
		$aieTree itemconfigure $nname -image $VisibilityImages(isVisImg)
	    } else {
		$aieTree itemconfigure $nname -image $VisibilityImages(notVisImg)
	    }
	    set fam_visible($ent) $on
	    hex_update_display
	    aie_hex_display_named_selection_subset
	    if $up_a {
		UpdateAncestors $nname
	    }
	}
    } elseif {$ent == "*"} {
        set nname blockingNode
        set im [$aieTree itemcget $nname -image]
	if {$im == $VisibilityImages(notVisImg)} {
	    set on 1
# Bug 11759 requests to just turn on edges, not blocks.
#	    set ents {edge block} 
	    set ents {edge}
	    $aieTree itemconfigure $nname -image $VisibilityImages(isVisImg)
	} else {
	    set on 0
	    set ents {vert edge face block mesh}
	    $aieTree itemconfigure $nname -image $VisibilityImages(notVisImg)
	}

	foreach ent $ents {
	    ToggleBlockingVisibility $type $ent $on
	}
	UpdateBlockAncestors block_vertNode
    } else {        
	set nname block_${ent}Node
	set up_a 0
	if {$on == ""} {
	    set im [$aieTree itemcget $nname -image]
	    if {$im == $VisibilityImages(isVisImg)} { set on 0 } else { set on 1 }
	    set up_a 1
	}

	if $on {
	    $aieTree itemconfigure $nname -image $VisibilityImages(isVisImg)
	} else {
	    $aieTree itemconfigure $nname -image $VisibilityImages(notVisImg)
	}

	set display_flag($ent) $on
	hex_update_display $ent
	if $up_a { UpdateBlockAncestors $nname }
    }
}

proc ::AIEnv::GUIManagement::Tree::GetBlockingSubsetVisibility {on} {
    variable VisibilityImages
    variable aieTree

    set ret ""
    foreach child [$aieTree nodes block_subsetNode] {
        set name [string trimleft $child block_subset-]
        if ![ic_hex_subset_named_selection $name] continue
        if $on {
            if {[$aieTree itemcget $child -image] == $VisibilityImages(isVisImg)} {
                lappend ret $name
            }
        } else {
            if {[$aieTree itemcget $child -image] == $VisibilityImages(notVisImg)} {
                lappend ret $name
            }
        }
    }
    return $ret
}

proc ::AIEnv::GUIManagement::Tree::IsBlockingSubsetVisible {subset} {
    variable VisibilityImages
    variable aieTree

    set ret ""
    foreach child [$aieTree nodes block_subsetNode] {
        set name [string trimleft $child block_subset-]
        if ![ic_hex_subset_named_selection $name] continue
        if {$name != $subset} continue
        if {[$aieTree itemcget $child -image] == $VisibilityImages(isVisImg)} {
            return 1
        }
    }
    return 0
}

# This is special as we don't want to consider topo node as
# part of blocking but it actually lies inside blocking
proc ::AIEnv::GUIManagement::Tree::UpdateBlockAncestors {nname} {
    variable VisibilityImages
    variable aieTree

    UpdateAncestors $nname
    set allon 0
    foreach node {vert edge face block mesh} {
        set im [$aieTree itemcget block_${node}Node -image]
        if {$im == $VisibilityImages(isVisImg) } {
            incr allon 1
        }
    }
    if !$allon {
        $aieTree itemconfigure blockingNode -image $VisibilityImages(notVisImg)
    } elseif {[expr $allon % 6] == 0} {
        $aieTree itemconfigure blockingNode -image $VisibilityImages(isVisImg)
    }
}

proc ::AIEnv::GUIManagement::Tree::ToggleTopoVisibility {type name {on ""}} {
    variable VisibilityImages
    variable aieTree
    global display_flag top_current

    if ![ic_hex_blocking_loaded] { return }
    if {$name == "*"} {
        # Nothing for now
        return
    }

    set nname $type-$name
    set parent [$aieTree parent $nname]
    foreach child [$aieTree nodes $parent] {
        $aieTree itemconfigure $child -image $VisibilityImages(notVisImg)
    }
    $aieTree itemconfigure $nname -image $VisibilityImages(isVisImg)
    if {[info exists top_current] && "$top_current" == "$name"} return
    switch_topology $name
}

proc ::AIEnv::GUIManagement::Tree::SetPartVisibleIcons {} {
    variable aieTree
    variable VisibilityImages
    global fam_visible
    
    foreach fam [array names fam_visible] {
        set pn [lindex [split $fam :] 0]
        if {$pn == ""} continue
        set tn part-$pn
        if $fam_visible($fam) {
            $aieTree itemconfigure $tn -image $VisibilityImages(isVisImg)
        } else {
            $aieTree itemconfigure $tn -image $VisibilityImages(notVisImg)
        }
    }
    UpdateVisFlag partNode
}

proc ::AIEnv::GUIManagement::Tree::UpdateVisFlag {Node} {
    variable aieTree
    if ![$aieTree exists $Node] return
    set ch [lindex [$aieTree nodes $Node] 0]
    if {$ch != ""} { UpdateAncestors $ch }
}


proc ::AIEnv::GUIManagement::Tree::UpdateAncestors {Node} {
	variable VisibilityImages
  	variable aieTree
  	# Look at all of my siblings and configure my parent
  	# accordingly
  	set Parent [$aieTree parent $Node]
  	if { $Parent == "root" } {
		return
	}
	set Siblings [$aieTree nodes $Parent]
	if { $Siblings != "" } {
		set OneChildVisible 0
		set OneChildInvisible 0
		foreach i $Siblings {
			set Image [$aieTree itemcget $i -image]
			if { $Image == $VisibilityImages(isVisImg) || $Image == $VisibilityImages(isVisInactiveImg) } {
				set OneChildVisible 1
			} elseif { $Image == $VisibilityImages(notVisImg) || $Image == $VisibilityImages(notVisInactiveImg) } {
				set OneChildInvisible 1
			} elseif { $Image == $VisibilityImages(someVisImg) } {
				set OneChildVisible 1
				set OneChildInvisible 1
			} 
		}
		if { $OneChildVisible == 1 } {
			if { $OneChildInvisible == 1} {
				$aieTree itemconfigure $Parent -image $VisibilityImages(someVisImg)
			} else {
				$aieTree itemconfigure $Parent -image $VisibilityImages(isVisImg)
			}
		} elseif { $OneChildInvisible == 1 } {
			$aieTree itemconfigure $Parent -image $VisibilityImages(notVisImg)
		} else {
			$aieTree itemconfigure $Parent -image ""
		}
	}
	UpdateAncestors $Parent
}

proc ::AIEnv::GUIManagement::Tree::OnNodeExpand {NodeID} {
	variable aieTree
	variable VisibilityImages
	variable NodeExpandMap
        variable NodeNameToTypeMap

	if { [array names NodeExpandMap $NodeID] != "" } {	
		set Children [$aieTree nodes $NodeID]
		foreach Child $Children {
			# Visibility state is one of the three
			# 0 - no items in the group are visible
			# 1 - some items in the group are visible
			# 2 - all items in the group are visible
			if { [array names NodeNameToTypeMap $Child] != "" } {
				set Type $NodeNameToTypeMap($Child)
				set TypeVisibilityState [GetVisibility $Type]

				if { $TypeVisibilityState == 0 } {
					$aieTree itemconfigure $Child -image $VisibilityImages(notVisImg)
				} elseif { $TypeVisibilityState == 1 } {
					$aieTree itemconfigure $Child -image $VisibilityImages(someVisImg)
				} elseif { $TypeVisibilityState == 2 } {
					$aieTree itemconfigure $Child -image $VisibilityImages(isVisImg)
				} else {
					$aieTree itemconfigure $Child -image $VisibilityImages(notVisImg)
				}
			} else {
				$aieTree itemconfigure $Child -image $VisibilityImages(notVisImg)
			}
		}
		if { $Children != "" } {
			UpdateAncestors [lindex $Children 0]
		}
	} else {
		# Part node expend: (assembly or partbc)
		# check names 
		if {$NodeID == "partNode"} {
			aie_set_prop_names_for_part
		} elseif {[string range $NodeID 0 4] == "part-"} {
			aie_set_prop_names_for_part [string range $NodeID 5 end]
		}
	}
}

proc ::AIEnv::GUIManagement::Tree::NodeVisibility {node} {
    variable aieTree
    variable VisibilityImages
    if ![$aieTree exists $node] { # error actually but safe
	return 0 
    }
    return [expr {[$aieTree itemcget $node -image] == $VisibilityImages(isVisImg)}]
}

proc ::AIEnv::GUIManagement::Tree::GetVisibility { Type } {
    global aie_geoTypeVis aie_meshTypeVis

    set visible 0
    switch $Type {
        point - curve - surface - body - density {
	        if [info exists aie_geoTypeVis($Type)] {
                return $aie_geoTypeVis($Type)
	        }
	        if ![ic_geo_is_loaded] { return 0 }
	        set ents [ic_geo_get_objects $Type]
	        set nvis 0
	        foreach ent $ents {
                if [ic_geo_get_visibility $Type $ent] { incr nvis }
	        }
	        if !$nvis {
                set visible 0
	        } elseif {($nvis == [llength $ents])} {
                set visible 2
	        } else {
                set visible 1
	        }
	    }
        node - line - shell - volume {
	        if [info exists aie_meshTypeVis($Type)] {
                return $aie_meshTypeVis($Type)
	        }
	        if ![ic_uns_is_loaded] { return 0 }
	        set nvel 0; set nel 0
	        set vismap [ic_uns_subset_get_current]
	        foreach et [aie_listElementTypes $Type] {
                incr nel [ic_count_elements $et]
                incr nvel [ic_uns_subset_count_elements $vismap $et]
	        }
	        if !$nvel {
                set visible 0
	        } elseif {$nel == $nvel} {
                set visible 2
	        } else {
                set visible 1
	        }
        }
    }
    return $visible    
}

proc ::AIEnv::GUIManagement::Tree::ExpandGeometry {} {
	variable aieTree
	variable VisibilityImages
}

proc ::AIEnv::GUIManagement::Tree::ExpandMesh {} {
	variable aieTree
	variable VisibilityImages
}

proc ::AIEnv::GUIManagement::Tree::treeRightClick { X Y image theNode } {
    variable RightClickNode
    variable VisibilityContextMenuMap
    variable NodeNameToTypeMap
    variable NodeExpandMap
    variable aieTree
    variable NodeCommand
    global aie_bctypes_used aie_param_multiple aie_tree_param_nodes
    global aie_bcclass_is_part env
    global use_workbench mesh_subset_shading
    global solver_setup solver_setup_global solve_format beta_mode
    
    if {$solver_setup != "-1"} {
       set solve_format $solver_setup
    } else {
       set solve_format $solver_setup_global
    }

    set nodetype [lindex [$aieTree itemcget $theNode -data] 0]
    set nodename [lindex [$aieTree itemcget $theNode -data] 1]

    set mm $aieTree.m$nodetype
    catch {destroy $mm}
    menu $mm -tearoff 0

    switch $nodetype {
       geom_subset - mesh_subset - contact - part {
          set sel [$aieTree selection get]
          if {$sel == "" } {
             $aieTree selection add $theNode
          } elseif {$sel != "" && [lsearch $sel $theNode] < 0} {
             foreach sub $sel {
                $aieTree selection remove $sub
             }
             $aieTree selection add $theNode
          }
       }
       default {
          $aieTree selection clear
       }
    }
    set allnodes [$aieTree selection get]
    set allnames [list $nodename]
    foreach n $allnodes {
        set dat [$aieTree itemcget $n -data]
        if {[lindex $dat 0] == $nodetype} {
            set n1 [lindex $dat 1]
            if {($n1 != "*") && ($n1 != $nodename)} {
                lappend allnames $n1
            }
        }
    }
    if [string match "Set *" $nodename] {
        destroy $mm
    } elseif {$nodename != "*"} {
        switch $nodetype {
            material {
                if {[info exists use_workbench] && $use_workbench} {
                    $mm add command -label "Delete" \
                        -command [list aie_delete_material $nodename]
                    $mm add command -label "Modify" \
                        -command [list aie_edit_material $nodename 0]
                    $mm add command -label "Advanced Modify" \
                        -command [list aie_edit_material $nodename 1]
                 } else {
                    $mm add command -label "Delete" \
                        -command [list aie_delete_material $nodename]
                    $mm add command -label "Rename" \
                        -command [list aie_rename_material $nodename]
                    $mm add command -label "Modify" \
                        -command [list aie_edit_material $nodename]
                    $mm add command -label "Copy" \
                        -command [list aie_copy_material $nodename]
                 }
            }
            material_tbl {
                $mm add command -label "Delete" \
                    -command [list aie_delete_material_tbl $nodename]
                $mm add command -label "Rename" \
                    -command [list aie_rename_material_tbl $nodename]
                $mm add command -label "Modify" \
                    -command [list aie_edit_material_tbl $nodename]
            }
            params {
                $mm add command -label "Delete" \
                    -command [list aie_delete_params $nodename]
                $mm add command -label "Rename" \
                    -command [list aie_rename_params $nodename]
                $mm add command -label "Modify" \
                    -command [list aie_edit_params $nodename]
            }
            lsdyna_params {
                $mm add command -label "Delete" \
                    -command [list aie_delete_lsdyna_params $nodename]
#           $mm add command -label "Rename" \
#               -command [list aie_rename_lsdyna_params $nodename]
                $mm add command -label "Modify" \
                    -command [list aie_edit_lsdyna_params $nodename]
            }
            part {
                # If this is an assembly then only allow rename.
                set isasm 0
                foreach sub [$aieTree nodes $theNode] {
                    if {[lindex [$aieTree itemcget $sub -data] 0] == "part"} {
                        set isasm 1
                        break
                    }
                }
                if $isasm {
                    $mm add command -label "Rename" \
                        -command [list aie_rename_part $nodename]
                    $mm add command -label "Blank" \
                        -command [list aie_blank_$nodetype $allnames]
                    $mm add command -label "Show" \
                        -command [list aie_unblank_$nodetype $allnames]
                    $mm add command -label "Merge to part" \
                        -command [list aie_merge_assembly_to_part $allnames]
                    $mm add command -label "Create Sub-Assembly" \
                        -command [list aie_create_assembly $nodename]
                    $mm add command -label "Delete" \
                        -command [list aie_delete_part $allnames]
                } else {
                    $mm add command -label "Info" \
                        -command [list aie_info_$nodetype $allnames]
                    $mm add command -label "Blank" \
                        -command [list ::AIEnv::GUIManagement::Tree::Parts hide $allnames]				
                    $mm add command -label "Show" \
                        -command [list ::AIEnv::GUIManagement::Tree::Parts show $allnames]			    
                    $mm add command -label "Add to Part" \
                        -command [list aie_edit_$nodetype $nodename]
                    if {($nodename != "VORFN") && ($nodename != "ORFN")} {
                        $mm add command -label "Break by connectivity" \
                            -command [list aie_break_up_$nodetype $allnames]
                        $mm add command -label "Change Color" \
                            -command [list aie_color_part $allnames]
                        $mm add command -label "Rename" \
                            -command [list aie_rename_part $nodename]
                        $mm add command -label "Delete" \
                            -command [list aie_delete_part $allnames]
                    }
                }
            }
            lcs {
                $mm add command -label "Delete" \
                    -command [list aie_delete_lcs $nodetype $nodename]
                $mm add command -label "Modify" \
                    -command [list aie_edit_$nodetype $nodename]
                $mm add command -label "Rename" \
                    -command [list aie_rename_lcs $nodename]
                $mm add command -label "Flip Axes" \
                    -command [list aie_flip_axes_lcs $nodename]
            }
            mesh_subset - geom_subset - block_subset {
                $mm add command -label "Info" \
                    -command [list aie_info_$nodetype $nodename]
                $mm add command -label "Modify" \
                    -command [list aie_edit_$nodetype $nodename]
                $mm add command -label "Delete" \
                    -command [list aie_delete_$nodetype $allnames]
                $mm add command -label "Rename" \
                    -command [list aie_rename_$nodetype $nodename]
                if {$nodetype != "block_subset"} {
                    $mm add command -label "Copy" \
                        -command [list aie_copy_$nodetype $nodename]
                    $mm add command -label "Clear" \
                        -command [list aie_clear_$nodetype $allnames]
                    if {$nodetype == "mesh_subset"} {
                        $mm add command -label "Add 1 layer" \
                            -command [list ic_uns_subset_add_layer $nodename 1 all surf]
                    }
                    $mm add command -label "Add" \
                        -command [list aie_add_to_$nodetype $nodename]
                    $mm add command -label "Remove" \
                        -command [list aie_remove_from_$nodetype $nodename]
                    if {[info exists env(AI_ENV_CFD_ONLY)] && $env(AI_ENV_CFD_ONLY)} {} else {
                        if {$nodetype == "mesh_subset"} {
                            $mm add command -label "Make Element set" \
                                -command [list aie_promote_to_elset_$nodetype $nodename]
                            $mm add command -label "Make Node set" \
                                -command [list aie_promote_to_nset_$nodetype $nodename]
                        }
                    }
                }
                if $beta_mode {
                    if {$nodetype == "mesh_subset"} {
                        $mm add command -label "Break by Parts" -command [list aie_break_by_part_$nodetype $nodename]
                        $mm add command -label "Break by Connectivity" -command [list aie_break_by_connectivity_$nodetype $nodename]
                    }
                }
            }
            contact {
                if {[ic_param_get_values :contact/$nodename] != ""} {
                    $mm add command -label "Modify" \
                        -command [list aie_edit_$nodetype $nodename]
                    $mm add command -label "Switch contact/target" \
                        -command [list aie_switch_$nodetype $nodename]
                    $mm add command -label "Delete" \
                        -command [list aie_delete_$nodetype $nodename]
                    $mm add command -label "Rename" \
                        -command [list aie_rename_$nodetype $nodename]
                } else {
                    destroy $mm
                }
            }
            subcase {
                $mm add command -label "Modify subcase" \
                    -command "aie_edit_subcase $nodename"
                $mm add command -label "Delete subcase" \
                    -command "aie_delete_subcase $nodename"
            }
            topo {
                $mm add command -label "Copy" \
                    -command [list aie_copy_topo $nodename]
                $mm add command -label "Merge" \
                    -command [list aie_merge_topo $nodename]	
                $mm add command -label "Rename" \
                    -command [list aie_rename_topo $nodename]
                $mm add command -label "Delete" \
                    -command [list aie_delete_topo $nodename]
                $mm add command -label "Save" \
                    -command [list aie_save_topo $nodename]
            }
            v3doc_root - v3doc_summary - v3doc_cfd - v3doc_efd \
                - v3doc_chapter - v3doc_section \
                - v3doc_graphics - v3doc_text - v3doc_table {
                $mm add command -label "Delete" \
                    -command [list aie_v3p_doc_delete $aieTree $theNode $nodetype]
            }
            vframe_root - vframe {
                aie_${nodetype}_menu $mm $aieTree $theNode $nodename
            }
            v3surfgrp - v3surfgrp_root - v3surfgrp_cycle {
                aie_${nodetype}_menu $mm $aieTree $theNode
            }
            v3surface {
                aie_v3surface_menu $mm $aieTree $theNode
            }
            v3strmgrp_root {
                aie_v3strmgrp_root_menu $mm $aieTree $theNode
            }
            v3strmgrp {
                aie_v3strmgrp_menu $mm $aieTree $theNode $nodename
            }
            v3pts_root {
                aie_v3pts_rootmenu $mm $aieTree $theNode $nodename
            }
            v3pts {
                aie_v3pts_menu $mm $aieTree $theNode $nodename
            }
            v3dset {
                aie_v3dset_win_menu $mm $theNode $nodename
            }
            v32d {
                destroy $mm
                set m [tdv_post_menu_cmd $nodename]
                if {[winfo exist $m] && ([winfo class $m] == "Menu")} {
                    $m configure -tearoff 0
                    tk_popup $m $X $Y; return
                }
            }
            v3diff {
                destroy $mm
                set m [tdv_post_menu_cmd $nodename]
                if {[winfo exist $m] && ([winfo class $m] == "Menu")} {
                    $m configure -tearoff 0
                    tk_popup $m $X $Y; return
                }
            }
            vpcolormap {
                aie_vpcolormap_menu $mm $aieTree $theNode $nodename
            }
            onedwin {
                aie_oned_win_menu $mm $theNode $nodename
            }
            onedaxis - onedaxes - onedaxtitle - onedlegend - onedplots - onedplot {
                set k [string range $nodetype 4 end]
                aie_oned_${k}_menu $mm $theNode $nodename
            }
            gsView {
                aie_gsview_menu $mm $aieTree $theNode $nodename
            }
            connector {
                # fixme me for the Renaming parts...--jka
                # $mm add command -label "Rename" \
                # -command [list aie_connectors_rename_group_directive $nodename]
                $mm add command -label "Modify" \
                    -command [list aie_connectors_edit_group_directives $nodename]
                $mm add command -label "Delete" \
                    -command [list aie_connectors_delete_group_directive $nodename]		
            }
            default {
                if [info exists aie_bctypes_used($nodetype)] {
                    if {($nodetype == "rigidwall" || $nodetype == "singlecontact" || \
                        $nodetype == "constrainednodes" || $nodetype == "velocity") && \
                        ($solve_format != "2" && $solve_format != "4")} {
                        mess "Menu only available if \"LS-Dyna\" is selected as solver\n"
                        destroy $mm
                    } else {
                        $mm add command -label "Delete" \
                            -command [list aie_delete_property $nodetype $nodename]
                        if ![info exists aie_bcclass_is_part($nodetype)] {
                            $mm add command -label "Rename" \
                                -command [list aie_rename_property $nodetype $nodename]
                        }
                        $mm add command -label "Modify" \
                            -command [list aie_edit_$nodetype $nodename]
#                       $mm add checkbutton -label "Labels On All" \
                            -variable aie_all_labels($nodetype,$nodename) \
                            -command [list aie_toggle_all_labels $nodetype $nodename]
                    }
                } elseif [info exists aie_param_multiple($nodetype)] {
                    $mm add command -label "Delete" \
                        -command [list bcc_delete_mult_param $nodetype $nodename]
                    $mm add command -label "Rename" \
                        -command [list bcc_rename_mult_param $nodetype $nodename]
                    $mm add command -label "Modify" \
                        -command $NodeCommand($theNode)
                } elseif [info exists aie_tree_param_nodes($nodetype)] {
                    $mm add command -label "Modify" \
                        -command $NodeCommand($theNode)
                } else {
                    destroy $mm
                }
            }
        }
    } else {
        switch $nodetype {
            part {
                $mm add command -label "Create Part" -command [list aie_edit_$nodetype *]
                $mm add command -label "Create Assembly" -command aie_create_assembly
                $mm add command -label "Remove Assembly" -command aie_remove_assembly
                set cm $mm.cm
                $mm add cascade -label "Show Parts Info" -menu $cm
                menu $cm -tearoff 0
                    $cm add command -label "All Parts" -command "aie_info_all_part all" 
                    $cm add command -label "Geometry Parts" -command "aie_info_all_part geom" 
                    $cm add command -label "Mesh Parts" -command "aie_info_all_part mesh" 
                    $cm add command -label "Blocking Parts" -command "aie_info_all_part block" 
                    if $beta_mode {
                        $cm add command -label "Boundary Condition Parts" -command "aie_info_all_part bc"
                    }
                $mm add command -label "Show All" \
                    -command "::AIEnv::GUIManagement::Tree::Parts show"
                $mm add command -label "Hide All" \
                    -command "::AIEnv::GUIManagement::Tree::Parts hide"		
                $mm add command -label "Reverse Blank All" \
                    -command "::AIEnv::GUIManagement::Tree::Parts reverse"		
                $mm add command -label "Expand All" \
                    -command "::AIEnv::GUIManagement::Tree::treeOpen partNode"
                $mm add command -label "Collapse All" \
                   -command "::AIEnv::GUIManagement::Tree::treeClose partNode"
                $mm add command -label "Blank Selected" \
                   -command "::AIEnv::GUIManagement::Tree::Parts hide selected"			
                $mm add command -label "Restrict Selected" \
                    -command "::AIEnv::GUIManagement::Tree::Parts show selected"		
                $mm add command -label "Delete Empty Parts" \
                    -command [list aie_delete_empty_parts 1]
                $mm add command -label "Expose Component Parts" \
                    -command [list aie_unique_parts 1]
                $mm add command -label "Move Component Parts" \
                    -command [list aie_move_parts 1]
                $mm add command -label "Edit Attributes" \
                    -command "aie_part_table_create attributes"
                $mm add command -label "Part Mesh Setup" \
                    -command "aie_part_table_create meshsizes"
                $mm add command -label "\"Good\" Colors" \
                    -command "aie_good_colors 0"
                if {[info command aie_parse_bcs_element_prop_0d] != ""} {
                    $mm add command -label "Color By Material" \
                        -command "aie_good_colors 1"
                }
            }
            mesh_subset - geom_subset {
                if {$nodetype == "mesh_subset"} {
                    set what UnsMesh
                } else {
                    set what Geo
                }
                $mm add command -label "Create" \
                    -command [list aie_edit_$nodetype *]
                if {$nodetype == "mesh_subset"} {
                    $mm add command -label "Find Worst" -command [list aie_mesh_subset_worst_element Quality]
                }
                $mm add command -label "Show All" \
                    -command "::AIEnv::GUIManagement::Tree::Toggle${what}Visible subset ${nodetype}Node 1"
                $mm add command -label "Hide All" \
                    -command "::AIEnv::GUIManagement::Tree::Toggle${what}Visible subset ${nodetype}Node 0"
                if {$nodetype == "geom_subset"} {
                    $mm add command -label "Create Part" -command aie_geom_subsets_into_parts
                }
                if {$nodetype == "mesh_subset"} {
                    $mm add separator
                    set cm $mm.cm
                    $mm add cascade -label "Shadings" -menu $cm
                    menu $cm -tearoff 0
                    $cm add radiobutton -label "Inherited" -command "aie_subset_mesh_shading Inherited" -variable mesh_subset_shading -value Inherited
                    $cm add radiobutton -label "Wire Frame" -command "aie_subset_mesh_shading Wire" -variable mesh_subset_shading -value Wire
                    $cm add radiobutton -label "Solid" -command "aie_subset_mesh_shading Solid" -variable mesh_subset_shading -value Solid
                    $cm add radiobutton -label "Solid & Wire" -command "aie_subset_mesh_shading Solid/wire" -variable mesh_subset_shading -value "Solid/wire"
                }
                               
            }
            block_subset {
                $mm add command -label "Create" \
                    -command [list aie_edit_$nodetype *]
                $mm add command -label "Show All" \
                    -command "::AIEnv::GUIManagement::Tree::ToggleBlockingVisibility block_subset * 1"
                $mm add command -label "Hide All" \
                    -command "::AIEnv::GUIManagement::Tree::ToggleBlockingVisibility block_subset * 0"
            }
            subcase {
                # nothing yet
            }
            elem {
                $mm add command -label "Delete Empty Properties" \
                    -command "::AIEnv::GUIManagement::Tree::UpdateElemPropNodes"
            }
            mat - tbl - params - lsdyna_params {
                # there used to be show all and hide all but this doesn't make
                # sense for these
                destroy $mm
            }
            topo {
                $mm add command -label "Create sub-topo" \
                    -command aie_topo_extract
            }
            connector {
                $mm add command -label "Create" \
                    -command [list aie_edit_connector $nodename]
                if [aie_connectors_exist_on_model] {
                    $mm add command -label "Make All Active" \
                        -command [list aie_connectors_activate_all_directives 1]
                    $mm add command -label "Make All Inactive" \
                        -command [list aie_connectors_activate_all_directives 0]
                    $mm add command -label "Delete All" \
                        -command [list aie_connectors_tree_delete_all_directives [$aieTree nodes connectorNode]]
                }
            }
            contact {
                $mm add command -label "Create" -command "createContactDEZ show"
            }
            singlecontact {
                $mm add command -label "Create" -command "createSingleContactDEZ show"
            }
            velocity {
                $mm add command -label "Create" -command "createVelocityDEZ show"
            }
            rigidwall {
                $mm add command -label "Create" -command "createRigidwallDEZ show"
            }
            constrainednodes {
                $mm add command -label "Create" -command "createConstrainedNodesDEZ show"
            }
            default {
                if [info exists aie_bctypes_used($nodetype)] {
                    $mm add command -label "Show All" \
                        -command "::AIEnv::GUIManagement::Tree::ShowGroup $nodetype ${nodetype}Node 2"
                    $mm add command -label "Hide All" \
                        -command "::AIEnv::GUIManagement::Tree::ShowGroup $nodetype ${nodetype}Node 0"
                    #$mm add command -label "Delete Empty Sets" \
                        -command "::AIEnv::GUIManagement::Tree::DeleteEmptyGroup $nodetype"
                } else {
                    destroy $mm
                }
            }
        }
    }

    if [winfo exists $mm] { tk_popup $mm $X $Y; return }

    if { [array names VisibilityContextMenuMap $theNode] != "" } {
        set RightClickNode $theNode
        set PopupMenu $VisibilityContextMenuMap($theNode)
        ::AIEnv::GUIManagement::Popup $PopupMenu $X $Y
    }
}

proc ::AIEnv::GUIManagement::Tree::treeShiftClick {node} {
    variable aieTree
    
    set data [$aieTree itemcget $node -data]
    set sel [$aieTree selection get]
    if {$sel == ""} {
	treeSelect 0 $node
    } else {
	set last [lindex $sel end]
        ::AIEnv::GUIManagement::Tree::removeSelectedParent $node
        ::AIEnv::GUIManagement::Tree::removeSelectedChildren $node
	$aieTree selection add $node
	set p1 [$aieTree parent $last]
	set p2 [$aieTree parent $node]
	if {$p1 == $p2} {
	    set i1 [$aieTree index $last]
	    set i2 [$aieTree index $node]
	    if {$i2 < $i1} { set i3 $i1; set i1 $i2; set i2 $i3 }
	    set nodes [$aieTree nodes $p1 $i1 $i2]
            foreach n $nodes {
               ::AIEnv::GUIManagement::Tree::removeSelectedParent $n
               ::AIEnv::GUIManagement::Tree::removeSelectedChildren $n
            }
	    eval $aieTree selection add $nodes
	}
    }
}


proc ::AIEnv::GUIManagement::Tree::removeSelectedParent {node} {
   variable aieTree

   set p [$aieTree parent $node]; set pp ""
   while {$p != "root"} {
      foreach n [$aieTree selection get] {
         if {$n == $p} {$aieTree selection remove $n}
      }
      set p [$aieTree parent $p]
   }
}

proc ::AIEnv::GUIManagement::Tree::removeSelectedChildren {node} {
   variable aieTree

   foreach s [$aieTree nodes $node] {

      ::AIEnv::GUIManagement::Tree::removeSelectedChildren $s

      foreach n [$aieTree selection get] {
         if {$n == $s} {$aieTree selection remove $n}
      }
   }
}

proc ::AIEnv::GUIManagement::Tree::treeControlClick {node} {
    variable aieTree
    
    set data [$aieTree itemcget $node -data]
    set sel [$aieTree selection get]

    if {$sel == ""} {
	treeSelect 0 $node
    } elseif {[lsearch $sel $node] < 0} {
        ::AIEnv::GUIManagement::Tree::removeSelectedParent $node
        ::AIEnv::GUIManagement::Tree::removeSelectedChildren $node
	$aieTree selection add $node
    } else {
	$aieTree selection remove $node
    }
}

proc ::AIEnv::GUIManagement::Tree::treeAdd {type args} {
	variable ValidGUITreeTypes
	variable TypeToParentNodeMap
	variable aieTree
	
	if {[lsearch $ValidGUITreeTypes $type] != -1} {
		if { [array names TypeToParentNodeMap $type] != "" } {
			set ParentNode $TypeToParentNodeMap($type)
			set Name [lindex $args 0]
			doInsert end $ParentNode $Name 
		        SortChildren $ParentNode
		} else {
			RuntimeError "Unable to map the type: \"$type\" to a parent node in the GUI tree."
		}
	} else {
		set TypeList [join $ValidGUITreeTypes ", "]
		set TypeList [linsert $TypeList "end-1" "or"]
		RuntimeError "Bad type passed to treeAdd.  Must be $TypeList"
	}
}

proc ::AIEnv::GUIManagement::Tree::treeUpdateFamilies {} {
    return ;# don't do this for now
	variable aieTree
	set Families [ic_geo_list_families]
	set FamilyNodes [$aieTree nodes familyNode]
	$aieTree delete $FamilyNodes
	set i 0
	foreach Family $Families {
		doInsert end familyNode fam${i} -text "$Family"
		incr i
	}
}

proc ::AIEnv::GUIManagement::Tree::treeDelete {node args} {
    variable aieTree
    $aieTree delete $node
}

proc ::AIEnv::GUIManagement::Tree::treeClear {} {
	
}

proc ::AIEnv::GUIManagement::Tree::treeCollapse {} {
	variable aieTree
	$aieTree closetree modelNode
}

proc ::AIEnv::GUIManagement::Tree::treeOpen {node} {
    variable aieTree

    set parent $node
    if ![$aieTree exists $parent] {
        puts "Error: $parent doesn't exist"
        return
    }

    $aieTree opennode $parent
    foreach child [$aieTree nodes $parent] {
        treeOpen $child
    }
}

proc ::AIEnv::GUIManagement::Tree::treeClose {node} {
    variable aieTree

    set parent $node
    if ![$aieTree exists $parent] {
        puts "Error: $parent doesn't exist"
        return
    }

    $aieTree closenode $parent
    foreach child [$aieTree nodes $parent] {
        treeClose $child
    }
}

proc ::AIEnv::GUIManagement::Tree::ShowNames {type} {
    global aie_ShowNames str_option
  	
    set str_option($type,names) $aie_ShowNames($type)
    update_geom_visible $type p 0  
}

proc ::AIEnv::GUIManagement::Tree::ShowWide {type} {
    global aie_ShowWide str_option
  	
    set str_option($type,wide) $aie_ShowWide($type)
    update_geom_visible $type p 0
}

proc ::AIEnv::GUIManagement::Tree::ShowDormant {type} {
    global aie_ShowDormant str_option tdv_default fam_visible

    set str_option($type,dormant) -1
    set show $aie_ShowDormant($type)
    set partlist ""
    if $show {
	    foreach part [array names fam_visible] {
	        if !$fam_visible($part) continue
	        lappend partlist $part
	    }
    } 
    ic_set_dormant_pickable $type $show $partlist

}

proc ::AIEnv::GUIManagement::Tree::ShowProtectPoints {} {
    global aie_ShowProtect str_option
    
    set str_option(point,protect) 0
    if $aie_ShowProtect {
        set str_option(point,protect) 1
    }
    update_geom_visible point p 0
}

proc ::AIEnv::GUIManagement::Tree::ShowCurveAttachment {attach} {
    global aie_ShowCurveAttachment str_option

    set str_option(curve,$attach) $aie_ShowCurveAttachment($attach)
    update_geom_visible curve p 0
}

proc ::AIEnv::GUIManagement::Tree::CurveColorByCount {} {
    global aie_CurveColorByCount str_option aie_ShowCurveAttachment aie_CurveComposite

    foreach attach { show0 show1 show2 show3 } {
	if ![info exists str_option(curve,$attach)] {
	    set str_option(curve,$attach) $aie_ShowCurveAttachment($attach)
	}
    }
    set aie_CurveComposite 0
    set str_option(curve,show_composite) $aie_CurveComposite
    set str_option(curve,count) $aie_CurveColorByCount
    update_geom_visible curve p 0
}

proc ::AIEnv::GUIManagement::Tree::CurveComposite {} {
    global str_option aie_CurveColorByCount aie_CurveComposite

    if ![ic_hex_blocking_loaded] {
        if $aie_CurveComposite {
            mess "Warning: \"Show Composite\" can be set only if blocking is loaded.\n" red
            set aie_CurveComposite 0
            return
        }
    }
    set aie_CurveColorByCount 0
    set str_option(curve,count) $aie_CurveColorByCount
    set str_option(curve,show_composite) $aie_CurveComposite
    update_geom_visible curve p 0
}

proc ::AIEnv::GUIManagement::Tree::ShowCurveQuadSizes {} {
    global aie_ShowCurveQuads  aie_ShowCurveHexas aie_ShowCurveTetras str_option

    if $aie_ShowCurveQuads {
	set str_option(curve,sizes) quad
	set aie_ShowCurveTetras 0
	set aie_ShowCurveHexas 0
    } else {
	set str_option(curve,sizes) none
    }
    update_geom_visible curve p 0
}

proc ::AIEnv::GUIManagement::Tree::ShowCurveQuadCount {} {
    global aie_ShowCurveQuadsCount aie_ShowCurveQuads aie_ShowCurveHexas aie_ShowCurveTetras str_option

    if $aie_ShowCurveQuadsCount {
	if $aie_ShowCurveQuads {
	    set str_option(curve,sizes) quad
	}
	set str_option(curve,count_quad) 1
	set aie_ShowCurveTetras 0
	set aie_ShowCurveHexas 0
    } else {
        if $aie_ShowCurveQuads {
            set str_option(curve,sizes) quad
        } else {
	    set str_option(curve,sizes) none
	}
	set str_option(curve,count_quad) 0
    }
    update_geom_visible curve p 0
}

proc ::AIEnv::GUIManagement::Tree::ShowCurveTetraSizes {} {
    global aie_ShowCurveTetras aie_ShowCurveHexas aie_ShowCurveQuads aie_ShowCurveQuadsCount str_option

    if $aie_ShowCurveTetras {
        set str_option(curve,sizes) tetra
        set aie_ShowCurveQuads 0
        set aie_ShowCurveHexas 0
        set aie_ShowCurveQuadsCount 0
    } else {
        set str_option(curve,sizes) none
    }
    update_geom_visible curve p 0
}

proc ::AIEnv::GUIManagement::Tree::ShowCurveHexaSizes {} {
    global aie_ShowCurveHexas aie_ShowCurveQuads aie_ShowCurveTetras aie_ShowCurveQuadsCount str_option

    if $aie_ShowCurveHexas {
        set str_option(curve,sizes) hexa
        set aie_ShowCurveQuads 0
        set aie_ShowCurveTetras 0
        set aie_ShowCurveQuadsCount 0
    } else {
        set str_option(curve,sizes) none
    }
    update_geom_visible curve p 0
}

proc ::AIEnv::GUIManagement::Tree::ShowDensityTetraSizes {} {
    global aie_ShowDensityTetras str_option

    if $aie_ShowDensityTetras {
        set str_option(density,sizes) tetra
    } else {
        set str_option(density,sizes) none
    }
    update_geom_visible density p 0
}
proc ::AIEnv::GUIManagement::Tree::ShowSurfaceNormalsColor {} {
   global aie_ShowSurfaceNormals aie_ColorByNormal str_option aie_SurfStyle
    if $aie_ShowSurfaceNormals {
        set aie_ShowSurfaceNormals 0
    }
	if $aie_ColorByNormal {
		set aie_SurfStyle(flat_wire) 1
		aie_changeSurfStyle flat_wire
		set str_option(surface,norms) 2
	} else {
		set aie_SurfStyle(wire) 1
		aie_changeSurfStyle wire
		set str_option(surface,norms) 0
	}
    update_geom_visible surface p 0
}
proc ::AIEnv::GUIManagement::Tree::ShowSurfaceNormals {} {
   global aie_ShowSurfaceNormals aie_ColorByNormal str_option aie_SurfStyle
    if $aie_ColorByNormal {
        set aie_ColorByNormal 0
		set aie_SurfStyle(wire) 1
		aie_changeSurfStyle wire
    }
    if $aie_ShowSurfaceNormals {
	    set str_option(surface,norms) 1
    } else {
	    set str_option(surface,norms) 0
    }
    update_geom_visible surface p 0
}

proc ::AIEnv::GUIManagement::Tree::ShowThickness {} {
    global aie_ShowThickness str_option

    if $aie_ShowThickness {
        set str_option(surface,thickness) 1
    } else {
        set str_option(surface,thickness) 0
    }
    update_geom_visible surface p 0
}

proc ::AIEnv::GUIManagement::Tree::ShowOrientation {} {
    global aie_ShowOrientation str_option

    if $aie_ShowOrientation {
        set str_option(surface,orientation) 1
    } else {
        set str_option(surface,orientation) 0
    }
    update_geom_visible curve p 0
}

proc ::AIEnv::GUIManagement::Tree::ShowBodySurfs {} {
    global aie_ShowBodySurfs str_option

    set str_option(body,lshow1) $aie_ShowBodySurfs
    update_geom_visible body p 0
}

proc ::AIEnv::GUIManagement::Tree::ShowShrink {} {
    global aie_meshShrink aie_meshShrinkBackup

    if [info exists aie_meshShrinkBackup(uns_shrink)] {
        set aie_meshShrink($aie_meshShrinkBackup(uns_shrink)) 0
    }   
    if $aie_meshShrink(50) {
        set shrink 50
    } elseif $aie_meshShrink(90) {
        set shrink 90
    } else {
        set shrink 100
    }
    set aie_meshShrinkBackup(uns_shrink) $shrink
    aie_changeMeshDisplay shrink $shrink
}

proc ::AIEnv::GUIManagement::Tree::ShowNodes {} {
    global aie_meshNodes aie_meshNodesBackup

    if [info exists aie_meshNodesBackup(uns_node_type)] {
        set aie_meshNodes($aie_meshNodesBackup(uns_node_type)) 0
    }   
    if $aie_meshNodes(Dots) {
        set nodes Dots
    } elseif $aie_meshNodes(Nums) {
        set nodes Nums
    } elseif $aie_meshNodes(Coords) {
        set nodes Coords
    } elseif $aie_meshNodes(Indices) {
        set nodes Indices
    } elseif $aie_meshNodes(Indices_Triad) {
        set nodes Indices_Triad
    } elseif {[info exists aie_meshNodes(Couplings)] && $aie_meshNodes(Couplings)} {
        set nodes Couplings
    } else {
        set nodes None
    }
    set aie_meshNodesBackup(uns_node_type) $nodes
    aie_changeMeshDisplay nodes $nodes
}

proc ::AIEnv::GUIManagement::Tree::ShowFaceNormals {} {
    global aie_meshDisplay aie_meshDisplayBackup
    if $aie_meshDisplay(normals) {
        if $aie_meshDisplay(normals_colored) {
            set aie_meshDisplay(normals_colored) 0
            ::AIEnv::GUIManagement::Tree::ShowNormalsColored
            set aie_meshDisplay(normals) 1
        }
    }
    aie_changeMeshDisplay
}

proc ::AIEnv::GUIManagement::Tree::ShowNormalsColored {} {
    global aie_meshDisplay aie_meshStyle disp_options
    global aie_meshDisplayBackup aie_meshStyleBackup
    
    if ![info exists aie_meshStyleBackup(uns_disp)] {
        set aie_meshStyleBackup(uns_disp) $disp_options(uns_disp)
    } else {
        set types { Wire Solid Solid/wire "Hidden line" "By dimension" color_by_quality }
        foreach val $types { set aie_meshStyle($val) 0 }
        set aie_meshStyle($aie_meshStyleBackup(uns_disp)) 1
        set disp_options(uns_disp) $aie_meshStyleBackup(uns_disp)
        unset aie_meshStyleBackup(uns_disp)
    }
    aie_changeMeshDisplay
    set aie_meshDisplay(normals) 0
}

proc ::AIEnv::GUIManagement::Tree::ShowCutPlanes {} {    
    if ![cutPlaneDEZ isbuilt] {
        cutPlaneDEZ show
    } else {
        aie_cutplane_set active
    }
}

proc ::AIEnv::GUIManagement::Tree::ShowInfo {type} {
    if ![ic_geo_is_loaded] {
	    mess "Warning: No Geometry Database Available\n" red
	    return
    }
    set skip_highlight 0
    set names [geo_select $type]
    foreach name $names {
	    set part [ic_geo_get_part $type $name]
	    mess "\n[string toupper $type 0 0] Name: $name\n" blue
	    mess "Part: $part\n" blue
	    switch $type {
	        point {
		        set pt [ic_geo_get_point_location $name]
		        set lcs [ic_csystem_get_current]
				if {$lcs != "global"} {
					mess "Location: $pt (in $lcs: [ic_coords_into_local $pt $lcs])\n" blue
			    } else {
		            mess "Location: $pt\n" blue
		        }
	        }
	        curve - surface {
		        set gtype [ic_geo_stats $type $name]
		        mess "Geometry type: $gtype\n" blue
		        if {$type == "surface"} {
		            if {[lindex [split $gtype ,] 0] == "mesh"} { set skip_highlight 1 }
		            foreach {n v} [ic_get_meshing_params surface $name] {
                        switch $n {
                            "etyp" {
                                if {$v != -1} {
                                    mess "Mesh type: [aie_global_get_mesh_type_name $v]\n" blue
                                }
                            }
                            "emethod" {
                                if {$v != -1} {
                                    mess "Mesh method: [aie_global_get_mesh_method_name $v]\n" blue
                                }
                            }
                        }
                    }
		        }
	        }
	        body {
		        set surfs ""; set curves ""; set points ""
		        foreach {t n} [ic_geo_body_lower_entities $name] {
		            switch $t {
			            surface {append surfs "$n "}
			            curve   {append curves "$n "}
			            point   {append points "$n "}
		            }
		        }
		        if {$surfs != ""} { mess "Surfaces: $surfs\n" blue }
#		        if {$curves != ""} { mess "Curves: $curves\n" blue }
#		        if {$points != ""} { mess "Points: $points\n" blue }
		        set pt [ic_geo_get_body_location $name]
		        set lcs [ic_csystem_get_current]
				if {$lcs != "global"} {
					mess "Location: $pt (in $lcs: [ic_coords_into_local $pt])\n" blue
				} else {		        
		            mess "Location: $pt\n" blue
		        }
		        set mat [ic_geo_get_body_matlpnt $name]
		        if {$mat != ""} { mess "Material Point Name: $mat\n" blue }
	        }
            density {
                set npts [ic_geo_num_nodes density $name]
                for {set n 0} {$n < $npts} {incr n} {
                    mess "Point [expr $n + 1]: [ic_geo_get_node density $name $n]\n" blue
                }
            }
	    }
    }
    
    aie_reset_geo_selected
    if !$skip_highlight {
        ic_highlight $type $names
    }
}

# ---------------------------------------------------------------

proc ::AIEnv::GUIManagement::Tree::PutMaterials {mats clear} {
    variable aieTree
    if {$clear && [$aieTree exists matNode]} {
	$aieTree delete [$aieTree nodes matNode]
    }
    foreach m $mats {
	set name [lindex $m 0]
	set nname $name
	regsub -all {[ \t\n]} $nname _ nname
	if [$aieTree exists material-$nname] continue
	doInsert end matNode material-$nname -text $name \
	    -data [list material $name]
    }
    SortChildren matNode
}

proc ::AIEnv::GUIManagement::Tree::DeleteMaterials {names} {
    variable aieTree
    foreach nname $names {
	regsub -all {[ \t\n]} $nname _ nname
	catch {$aieTree delete material-$nname}
    }
}

proc ::AIEnv::GUIManagement::Tree::RenameMaterial {from to} {
    DeleteMaterials [list $from]
    PutMaterials [list $to] 0
}

proc ::AIEnv::GUIManagement::Tree::CopyMaterial {from to} {
    PutMaterials [list $to] 0
}
# ---------------------------------------------------------------

proc ::AIEnv::GUIManagement::Tree::PutMaterialTbls {tbls clear} {
    variable aieTree
    if {$clear && [$aieTree exists tblNode]} {
	$aieTree delete [$aieTree nodes tblNode]
    }
    foreach m $tbls {
	set name [lindex $m 0]
	set nname $name
	regsub -all {[ \t\n]} $nname _ nname
	if [$aieTree exists tbl-$nname] continue
	doInsert end tblNode tbl-$nname -text $name \
	    -data [list material_tbl $name]
    }
    SortChildren tblNode
}

proc ::AIEnv::GUIManagement::Tree::DeleteMaterialTbl {names} {
    variable aieTree
    foreach nname $names {
	regsub -all {[ \t\n]} $nname _ nname 
	catch {$aieTree delete tbl-$nname}
    }
}

proc ::AIEnv::GUIManagement::Tree::RenameMaterialTbl {from to} {
    DeleteMaterialTbl [list $from]
    PutMaterialTbls [list $to] 0
}

# ---------------------------------------------------------------

proc ::AIEnv::GUIManagement::Tree::PutParams {params clear} {
    variable aieTree
    if {$clear && [$aieTree exists paramsNode]} {
	$aieTree delete [$aieTree nodes paramsNode]
    }
    foreach m $params {
	set name [lindex $m 0]
	set nname $name
	regsub -all {[ \t\n]} $nname _ nname
	if [$aieTree exists params-$nname] continue
	doInsert end paramsNode params-$nname -text $name \
	    -data [list params $name]
    }
    SortChildren paramsNode
}

proc ::AIEnv::GUIManagement::Tree::DeleteParams {names} {
    variable aieTree
    foreach nname $names {
	regsub -all {[ \t\n]} $nname _ nname 
	catch {$aieTree delete params-$nname}
    }
}

proc ::AIEnv::GUIManagement::Tree::RenameParams {from to} {
    DeleteParams [list $from]
    PutParams [list $to] 0
}

# ---------------------------------------------------------------

proc ::AIEnv::GUIManagement::Tree::PutLsdynaParams {params clear} {
    variable aieTree
    if {$clear && [$aieTree exists lsdynaParamsNode]} {
	$aieTree delete [$aieTree nodes lsdynaParamsNode]
    }
    foreach m $params {
	set name [lindex $m 0]
	set nname $name
	regsub -all {[ \t\n]} $nname _ nname
	if [$aieTree exists lsdyna_params-$nname] continue
	doInsert end lsdynaParamsNode lsdyna_params-$nname -text $name \
	    -data [list lsdyna_params $name]
    }
    SortChildren lsdynaParamsNode
}

proc ::AIEnv::GUIManagement::Tree::DeleteLsdynaParams {names} {
    variable aieTree
    foreach nname $names {
	regsub -all {[ \t\n]} $nname _ nname 
	catch {$aieTree delete lsdyna_params-$nname}
    }
}

proc ::AIEnv::GUIManagement::Tree::RenameLsdynaParams {from to} {
    DeleteLsdynaParams [list $from]
    PutLsdynaParams [list $to] 0
}

# ---------------------------------------------------------------

proc ::AIEnv::GUIManagement::Tree::PutLCS {lcs clear} {
    variable aieTree
    variable VisibilityImages
    if {$clear} {
       ic_csystem_display all 0
       aie_set_lcs_current type global
    }
    if {$clear && [$aieTree exists lcsNode]} {
	$aieTree delete [$aieTree nodes lcsNode]
    }
    foreach m $lcs {
	set name [lindex $m 0]
	if [$aieTree exists lcs-$name] continue
	doInsert end lcsNode lcs-$name -text $name \
	    -data [list lcs $name] -image $VisibilityImages(notVisImg)   
    }
    SortChildren lcsNode
}

proc ::AIEnv::GUIManagement::Tree::DeleteLCS {names} {
    variable aieTree
    foreach name $names {
	$aieTree delete lcs-$name
    }
}

proc ::AIEnv::GUIManagement::Tree::RenameLCS {from to} {
    DeleteLCS [list $from]
    PutLCS [list $to] 0
}

# ---------------------------------------------------------------

proc ::AIEnv::GUIManagement::Tree::PutSubcases {scs clear} {
    variable aieTree
    if {$clear && [$aieTree exists subcaseNode]} {
	$aieTree delete [$aieTree nodes subcaseNode]
    }
    foreach m $scs {
	set name [lindex $m 0]
	if [$aieTree exists subcase-$name] continue
	doInsert end subcaseNode subcase-$name -text $name \
	    -data [list subcase $name]
    }
    SortChildren subcaseNode
}

proc ::AIEnv::GUIManagement::Tree::DeleteSubcases {names} {
    variable aieTree
    foreach name $names {
	$aieTree delete subcase-$name
    }
}

proc ::AIEnv::GUIManagement::Tree::SortChildren {par} {
    variable aieTree
    if [$aieTree exists $par] {
	$aieTree reorder $par [lsort [$aieTree nodes $par]]
    }
}

# ---------------------------------------------------------------

proc ::AIEnv::GUIManagement::Tree::GroupExists {type name} {
    variable aieTree
    
    set nname $type-$name
    regsub -all {[ \t\n]} $nname _ nname
    
    return [$aieTree exists $nname]
}

proc ::AIEnv::GUIManagement::Tree::AddGroup {type name {vis 1} {open 0} {color ""} {index end}} {
    variable aieTree
    variable VisibilityImages
    global aie_prop_subtype fam_visible aie_bcclass_is_part
    
    if {$type == "part" && [string match *:* $name]} error
    set parent $type
    if [info exists aie_prop_subtype($parent)] {
        set parent $aie_prop_subtype($parent)
    }
    set nname $type-$name
    regsub -all {[ \t\n]} $nname _ nname
    set names [split $name /] 
    set setproc [info command aie_get_${type}_set]
    if {$setproc != ""} {
	    set ss [$setproc $name]
	    if {$ss != ""} {
	        set names [concat [list "Set $ss"] $names]
	    }
    }
    
    set par ${parent}Node
    switch $type {
	    subcase {
	        set visim ""
	    }
	    default {
	        if $vis {
		        set visim $VisibilityImages(isVisImg)
	        } else {
		        set visim $VisibilityImages(notVisImg)
	        }
	    }
    }
    set maybe_black 0
    if {$color == ""} {
	    set color black
	    if {$type == "part"} {
	        set color [family_color_for_name $name]
	        set maybe_black 1
	    }
    }
    set subname ""
    foreach nn [lrange $names 0 end-1] {
	    set tt $type
	    set dat +
	    if [string match "Set *" $nn] {
	        set dat "\# $ss"
	        set tt $parent
	    }
	    if {$subname != ""} { append subname / }
	    append subname $nn
	    set sub ${tt}-$subname
	    regsub -all {[ \t\n]} $sub _ sub
	    if ![$aieTree exists $sub] {
	        doInsert end $par $sub -text $nn -image $visim -data [list $tt $subname] -fill black
	        SortChildren $par
	    } else {
	        $aieTree itemconfigure $sub -text $nn -image $visim -data [list $tt $subname] -fill black
	    }
	    if $open {
	        $aieTree itemconfigure $sub -open 1
	    }
	    set par $sub
    }
    if ![$aieTree exists $nname] {
	    doInsert $index $par $nname
	    SortChildren $par
    } elseif {[$aieTree parent $nname] != $par} {
	    $aieTree move $par $nname $index
	    SortChildren $par
    }
    if $maybe_black {
	    foreach sub [$aieTree nodes $nname] {
	        set data [$aieTree itemcget $sub -data]
	        if [info exists aie_bcclass_is_part([lindex $data 0])] {
		        set color black
		        break
	        }
	    }
    }

    set backcol [from_tkcolor_get auto_contrast $color [$aieTree cget -bg]]
    $aieTree itemconfigure $nname -text [lindex $names end] -data [list $type $name] -image $visim -fill $color -backfill $backcol

    UpdateAncestors $nname
    if {$type == "part"} {
	    # If we have a parent make sure the parent's color is black because
	    # it's an assembly and not a part.
	    set par [$aieTree parent $nname]
	    $aieTree itemconfigure $par -fill black
    }
    
    if {$setproc != ""} {
	    # This may not be the best place to do this
	    foreach nn [$aieTree nodes ${parent}Node] {
	        if {[string match ${parent}-Set_* $nn] && ([$aieTree nodes $nn] == "")} {
	            $aieTree delete $nn
	        }
	    }
    }
}

# ---------------------------------------------------------------

# A convenience function

proc ::AIEnv::GUIManagement::Tree::NewPart {part} {
    if {![::AIEnv::GUIManagement::Tree::GroupExists part $part]} {
	::AIEnv::GUIManagement::Tree::AddGroup part $part
	::AIEnv::GUIManagement::Tree::ToggleGroupVisibility part $part same
    }
}

proc ::AIEnv::GUIManagement::Tree::RefreshPartVisibility {} {
    tdv_active 0
    ::AIEnv::GUIManagement::Tree::ToggleGroupVisibility part * same
    tdv_active 1
}

# ---------------------------------------------------------------

proc ::AIEnv::GUIManagement::Tree::PartBCExists {bcclass part} {
    variable aieTree
    
    set nname $bcclass-$part
    regsub -all {[ \t\n]} $nname _ nname
    
    return [$aieTree exists $nname]
}

proc ::AIEnv::GUIManagement::Tree::AddPartBC {bcclass part {vis 0} {open 0} {color "black"}} {
    variable aieTree
    variable VisibilityImages
    global aie_prop_subtype fam_visible aie_bcclass_title
    
    set parent part-$part
    
    # TODO: make this more generic
    AddPartBCType $bcclass $part $vis
    
    set nname $bcclass-$part
    regsub -all {[ \t\n]} $nname _ nname
    
    if $vis {
	set visim $VisibilityImages(isVisImg)
    } else {
	set visim $VisibilityImages(notVisImg)
    }
    
    if ![$aieTree exists $nname] {
	doInsert end $parent $nname
	SortChildren $parent
    }

    set backcol [from_tkcolor_get auto_contrast $color [$aieTree cget -bg]]
    $aieTree itemconfigure $nname -text $aie_bcclass_title($bcclass) \
	-data [list $bcclass $part] -image $visim -fill $color -backfill $backcol
	# fix name:
	aie_set_prop_names_for_part $part
}

proc ::AIEnv::GUIManagement::Tree::AddPartBCType {type part vis} {
    variable aieTree
    variable VisibilityImages
    global aie_bcclass_title aie_bctypes_used
    
    if $vis {
	set visim $VisibilityImages(isVisImg)
    } else {
	set visim $VisibilityImages(notVisImg)
    }
    
    set pnode ${type}_partbcNode
    if ![$aieTree exists $pnode] {
	doInsert end partbcNode $pnode -text $aie_bcclass_title($type) \
	    -image $visim -data [list partbctype $type]
    }
    foreach poss $aie_bctypes_used($type) {
	if {[ic_boco_get $part $poss] != ""} {
	    if [info exists aie_bcclass_title($poss)] {
		set subtitle "$aie_bcclass_title($poss) ($poss)"
	    }
	    set subbc $poss
	    break
	}
    }
    if [info exists subtitle] {
	set p2node partbc-$subbc
	if ![$aieTree exists $p2node] {
	    doInsert end $pnode $p2node -text $subtitle \
		-data [list partbc $subbc] -image $visim
	}
    }
}

# -------------------------------------------------------------------------

proc ::AIEnv::GUIManagement::Tree::ChangeColor {type name color} {
    variable aieTree
    set node ${type}-$name
    regsub -all {[ \t\n]} $node - node
    if [$aieTree exists $node] {
        set backcol [from_tkcolor_get auto_contrast $color [$aieTree cget -bg]]
        $aieTree itemconfigure $node -fill $color -backfill $backcol
    }
}

proc ::AIEnv::GUIManagement::Tree::GetColor {type name} {
    variable aieTree
    set node ${type}-$name
    regsub -all {[ \t\n]} $node - node
    if [$aieTree exists $node] {
        return [$aieTree itemcget $node -fill]
    } else {
        return ""
    }
}

proc ::AIEnv::GUIManagement::Tree::DeleteGroup {type name empty_parents} {
    variable aieTree
    variable VisibilityImages

    set nname $type-$name
    regsub -all {[ \t\n]} $nname _ nname

    if ![$aieTree exists $nname] {
        return { 1 "" end }
    }
    if {[$aieTree itemcget $nname -image] == $VisibilityImages(isVisImg)} {
        set vis 1
    } else {
        set vis 0
    }
    set col [$aieTree itemcget $nname -fill]
    set par [$aieTree parent $nname]
    set ind [$aieTree index $nname]
    $aieTree delete $nname
    if $empty_parents {
        while {([lindex [$aieTree itemcget $par -data] 1] != "*") && ![llength [$aieTree nodes $par]]} {
            set par2 [$aieTree parent $par]
            if {![string match part-* $par]} {
                $aieTree delete $par
            }
            set par $par2
        }
    }
    return [list $vis $col $ind]
}

# This has to deal with the hierarchy thing

proc ::AIEnv::GUIManagement::Tree::RenameGroup {type old new {vis ""}} {
    set vci [DeleteGroup $type $old 0]
    if {$vis == ""} {set vis [lindex $vci 0]}
    AddGroup $type $new $vis 1 [lindex $vci 1]
}

# ---------------------------------------------------------------

proc ::AIEnv::GUIManagement::Tree::AssemblyChildren {type group} {
    variable aieTree
    
    regsub -all {[ \t\n]} $group _ group
    return [$aieTree nodes $type-$group]
}

proc ::AIEnv::GUIManagement::Tree::DescendantsWithData {tree parent pat} {
    set ret {}
    foreach n [$tree nodes $parent] {
	if {($pat == "") || [string match $pat [$tree itemcget $n -data]]} {
	    lappend ret $n
	    set ret [concat $ret [DescendantsWithData $tree $n $pat]]
	}
    }
    return $ret
}

proc ::AIEnv::GUIManagement::Tree::GetChildren {par} {
    variable aieTree
    if [$aieTree exists $par] {
	return [$aieTree nodes $par]
    }
}

#===fast=parts==========================
proc ::AIEnv::GUIManagement::Tree::Parts {{what show} {parts ""}} {
    variable aieTree
    variable VisibilityImages
    global fam_visible

    foreach im [array names VisibilityImages] {
		set $im $VisibilityImages($im)
	}
	# notVisImg, isVisInactiveImg, notVisInactiveImg, someVisImg, isVisImg   
    if {$parts == "*"} { set parts "" }
    set n_show [lsearch "hide show reverse" $what]
    if {$n_show < 0} { set n_show 1 }
    if {$what == "toggle"} {
		# must be 1 part, only on select
		if {$parts == ""} {
		    set parts [array names fam_visible]
			set im [$aieTree itemcget partNode -image]
            if [ic_hex_blocking_loaded] {
                set vorfn [lsearch $parts "VORFN"]
            }
        } else {
			set im [$aieTree itemcget part-$parts -image]
		}
		if {$im == $notVisImg} {
			set n_show 1
		} else {
			set n_show 0
		}
        if [info exists vorfn] {
            if {$vorfn >= 0 && $n_show == 1} {
                set parts [lreplace $parts $vorfn $vorfn]
            }
            unset vorfn
        }
    }
    set ims "$notVisImg $isVisImg"

    # parts: "" == all, "select" == select, or aieTree list (may be mixed with ass-s)
      
    # update Tree (default, on == ""): add/delete nodes if necessary
    # change visibility: $parts 1/0: parts = "" -> all parts 
    # change Parts image if necessary
    # do nothing if "selected" mode, but no selection:
    set selection_list ""
    
    # 1. Update Tree (always). 
		aie_part_update_nodes
		# update bocos; if all parts - set as parts visibility; if some parts - inherit
		if {$parts == ""} {
			set on_prop $n_show
		} else {
			set on_prop 2
		}
	# do not update 	::AIEnv::GUIManagement::Tree::UpdateElemPropNodes $on_prop
		aie_set_prop_names_for_part
	#	2. which parts	
		set parts_list ""	
		if {$parts == "selected"} {
			set selection_list [geo_select entity]
			if {$selection_list == ""} return
			# use temporary array: may be multiply selection of the same part
			if [info exists tmp_arr] { unset tmp_arr } 				
			foreach entity $selection_list {
			    foreach {type name} $entity ""
                set fam [ic_geo_get_family $type $name]
				set part [ic_boco_get_part_of_fam $fam]
				set tmp_arr($part) 1
				ic_show_geo_selected $type $name 0
			}
			set parts_list [array names tmp_arr]
			if {$parts_list == ""} return
            if {$what == "hide"} {
                mess "Blanked part(s): $parts_list\n"
            }	
			if {$what == "show"} {
				# hide all and show selected
				aie_part_change_visibility $ims 0 ""
			}
		} elseif {$parts != ""} {
			# create parts_list from part tree names, may be mix of part & ass-s 
			set parts_list [aie_part_names_from_tree $parts]
		}
	# 3. change visibility
			aie_part_change_visibility $ims $n_show $parts_list 
	# 4. change tree icons in accordance with parts visibility 
		if {$parts_list == "" && ($n_show < 2)} {
			aie_part_set_assemblies [lindex "$notVisImg $isVisImg" $n_show]
		} else {
			aie_part_check_assemblies $notVisImg $isVisImg $someVisImg 
		} 
}
#=============================

proc ::AIEnv::GUIManagement::Tree::ToggleGroupVisibility {type name {on ""} {up_a 0}} {
    variable aieTree
    variable VisibilityImages
    global fam_visible aie_bcclass_is_part

#    puts [list ToggleGroupVisibility $type $name $on $up_a]
    
    if {$name == "*"} {
	set nname ${type}Node
    } else {
	set nname $type-$name
	regsub -all {[ \t\n]} $nname _ nname
    }
    if ![$aieTree exists $nname] return
    
    if {$on == ""} {
	set im [$aieTree itemcget $nname -image]
	if {$im == $VisibilityImages(isVisImg) || $im == $VisibilityImages(isVisInactiveImg)} { set on 0 } else { set on 1 }
	set up_a 1
    } elseif {$on == "same"} {
	set im [$aieTree itemcget $nname -image]
	if {$im == $VisibilityImages(isVisImg)} { set on 1 } else { set on 0 }
	set up_a 1
    }
    
    # for prop up_a must be always 0: property does not change part visibility!
    if {[string range $type 0 11] == "element_prop"} {
		set up_a 0
	}
	# change boco images if boco group visibility was changed
	if {$type == "partbc"} {
		set im [lindex "$VisibilityImages(notVisImg) $VisibilityImages(isVisImg)" $on]
		aie_part_set_boco_icons $name $im
	}
	
    if {$type=="connector"} {
	if {$name!="*"} {
	    if $on {
		if {[$aieTree itemcget $nname -image]==$VisibilityImages(notVisImg)} {
		    $aieTree itemconfigure $nname -image $VisibilityImages(isVisImg)
		} elseif {[$aieTree itemcget $nname -image]==$VisibilityImages(notVisInactiveImg)} {
		    $aieTree itemconfigure $nname -image $VisibilityImages(isVisInactiveImg)
		}
	    } else {
		if {[$aieTree itemcget $nname -image]==$VisibilityImages(isVisImg)} {
		    $aieTree itemconfigure $nname -image $VisibilityImages(notVisImg)
		} elseif {[$aieTree itemcget $nname -image]==$VisibilityImages(isVisInactiveImg)} {
		    $aieTree itemconfigure $nname -image $VisibilityImages(notVisInactiveImg)
		}
	    }
	} else {
	    if $on {
		$aieTree itemconfigure $nname -image $VisibilityImages(isVisImg)
	    } else {
		$aieTree itemconfigure $nname -image $VisibilityImages(notVisImg)
	    }
	}
    } else {
	if $on {
	    $aieTree itemconfigure $nname -image $VisibilityImages(isVisImg)
	} else {
	    $aieTree itemconfigure $nname -image $VisibilityImages(notVisImg)
	}
    }
    
    if {$name == "*"} {
	set pa [tdv_active 0]
	
	if {[info exists aie_bcclass_is_part($type)] && [string match element_prop $type]} {
	    aie_set_group_or_part_vis element_prop "" $on 1
	} else {
	    foreach sub [DescendantsWithData $aieTree $nname "* *"] {
		set data [$aieTree itemcget $sub -data]
		# ToggleGroupVisibility [lindex $data 0] [lindex $data 1] $on $sub
		# Rather than calling this function recursively we try and get more
		# efficiency this way ...
		set name [lindex $data 1]
		if {$type=="connector"} {
		    if $on {
			if {[$aieTree itemcget $sub -image]==$VisibilityImages(notVisInactiveImg)} {
			    set img $VisibilityImages(isVisInactiveImg)
			} elseif {[$aieTree itemcget $sub -image]==$VisibilityImages(isVisInactiveImg)} {
			    set img $VisibilityImages(isVisInactiveImg)
			} else {
			    set img $VisibilityImages(isVisImg)
			}
		    } else {
			if {[$aieTree itemcget $sub -image]==$VisibilityImages(isVisInactiveImg)} {
			    set img $VisibilityImages(notVisInactiveImg)
			} elseif {[$aieTree itemcget $sub -image]==$VisibilityImages(notVisInactiveImg)} {
			    set img $VisibilityImages(notVisInactiveImg)
			} else {
			    set img $VisibilityImages(notVisImg)
			}
		    }
		} else {
		    if $on {
			set img $VisibilityImages(isVisImg)
		    } else {
			set img $VisibilityImages(notVisImg)
		    }
		}
		
		if {$name == "VORFN"} {
		    set fam_visible(VORFN) 0
		    if $on {continue}
		}
		$aieTree itemconfigure $sub -image $img 
		switch $type {
		    mesh_subset {
                ic_uns_subset_visible $name $on
                if $on { aie_subset_mesh_shading }
		    }
		    contact {
                aie_show_contact $name $on
		    }
		    geom_subset {
                ic_geo_subset_visible $name $on
		    }
		    default {
                set type1 [lindex $data 0]
                lappend vis_names($type1) $name
		    }
		}
		$aieTree itemconfigure $sub -image $img
	    }
	    foreach type1 [array names vis_names] {
		if {$type1 == "part"} {
		    set names [aie_convert_part_names_to_families $vis_names($type1)]
		} else {
		    set names $vis_names($type1)
		}
		aie_set_group_or_part_vis $type1 $names $on 1
	    }
	    if {$type == "part"}  {
		hex_update_display
	    }
	}
	tdv_active $pa

    } else {
	set pa [tdv_active 0]
	set names ""
	foreach sub [concat $nname [DescendantsWithData $aieTree $nname "* *"]] {
		if {$type=="connector"} {
		    if $on {
			if {[$aieTree itemcget $sub -image]==$VisibilityImages(notVisInactiveImg)} {
			    set img $VisibilityImages(isVisInactiveImg)
			} elseif {[$aieTree itemcget $sub -image]==$VisibilityImages(isVisInactiveImg)} {
			    set img $VisibilityImages(isVisInactiveImg)
			} else {
			    set img $VisibilityImages(isVisImg)
			}
		    } else {
			if {[$aieTree itemcget $sub -image]==$VisibilityImages(isVisInactiveImg)} {
			    set img $VisibilityImages(notVisInactiveImg)
			} elseif {[$aieTree itemcget $sub -image]==$VisibilityImages(notVisInactiveImg)} {
			    set img $VisibilityImages(notVisInactiveImg)
			} else {
			    set img $VisibilityImages(notVisImg)
			}
		    }
		} else {
		if $on {
		    $aieTree itemconfigure $sub -image $VisibilityImages(isVisImg)
	    } else {
		$aieTree itemconfigure $sub -image $VisibilityImages(notVisImg)
	    }
		}
	    set n [lindex [$aieTree itemcget $sub -data] 1]
	    if {$n != "*"} { lappend names $n }
	}
	
	if {$name == "VORFN"} {
	    set fam_visible(VORFN) $on
	}
	
	switch $type {
	    mesh_subset {
		    foreach name $names {
		        ic_uns_subset_visible $name $on
		        if $on { aie_subset_mesh_shading }
		    }
	    }
	    contact {
		    aie_show_contact $name $on
	    }
	    geom_subset {
		    foreach name $names {
		        ic_geo_subset_visible $name $on
		    }
	    }
	    part {
		    aie_set_group_or_part_vis $type $names $on $up_a
		    if $up_a {
		        aie_updateGeoVis all 0
		        aie_updateMeshVis all 0
		    }
	    }
	    default {
            aie_set_group_or_part_vis $type $names $on $up_a
	    }
	}
	if $up_a { UpdateAncestors $nname }
	if {$type == "part"}  {
	    hex_update_display
	}
	tdv_active $pa
    }
}

# this is needed to work around a bug where the new elements disappear
# from the part they were displayed in

proc ::AIEnv::GUIManagement::Tree::RefreshParts {} {
    variable aieTree
    variable VisibilityImages

    foreach name [aie_list_parts 0] {
        set nname part-$name
        regsub -all {[ \t\n]} $nname _ nname
        if ![$aieTree exists $nname] continue
        set im [$aieTree itemcget $nname -image]
        if {$im == $VisibilityImages(isVisImg)} { set on 1 } else { set on 0 }
        set n [lindex [$aieTree itemcget $nname -data] 1]
        set names [list $n]
        aie_set_group_or_part_vis part [list $n] $on 0
    }
    update_geom_visible all v 0
    if [ic_uns_is_loaded] update_uns_visible
    aie_updateGeoVis all 0
    aie_updateMeshVis all 0
    if [ic_hex_blocking_loaded] {
        hex_update_display
    }
}

# This returns 1, -1, or 0 for yes, no, partly, or sets it if the value is given

proc ::AIEnv::GUIManagement::Tree::NodeVisibleStatus {type name {value ""} {defstatus -1}} {
    variable aieTree
    variable VisibilityImages

    if {$name == "*"} {
        set nname ${type}Node
    } else {
        set nname $type-$name
        regsub -all {[ \t\n]} $nname _ nname
    }
    if ![$aieTree exists $nname] { return $defstatus }
    set im [$aieTree itemcget $nname -image]
    if {$im == $VisibilityImages(isVisImg)} {
        set ret 1
    } elseif {$im == $VisibilityImages(notVisImg)} {
        set ret -1
    } else {
        set ret 0
    }
    switch -- $value {
        -1 { $aieTree itemconfigure $nname -image $VisibilityImages(notVisImg) }
        0  { $aieTree itemconfigure $nname -image $VisibilityImages(someVisImg) }
        1  { $aieTree itemconfigure $nname -image $VisibilityImages(isVisImg) }
    }
    return $ret
}

proc ::AIEnv::GUIManagement::Tree::UpdateGeoVisibility {{type all}} {
    variable aieTree
    variable VisibilityImages
    global aie_geoTypeVis aie_ShowDormant

    UpdateGeomNodes

    if {$type == "all"} {
        set types {point curve surface body density}
    } else {
        set types $type
    }

    array set visimg { 0 notVisImg 1 someVisImg 2 isVisImg}
    foreach type $types {
	switch $type {
	    body {
		if {![ic_geo_num_objects material] && ![ic_geo_num_objects body]} continue
	    }
		point -
		curve {
		
			if ![llength [ic_geo_get_objects $type "" 1]] continue
		}
	    default {
		if ![ic_geo_num_objects $type] continue
	    }
	}
	switch $type {
	    point   { set Node geomPointNode }
	    curve   { set Node geomCurveNode }
	    surface { set Node geomSurfNode }
	    body    { set Node geomBodyNode }
	    density { set Node geomDensityNode }
	}
	set vis $aie_geoTypeVis($type)
	doInsertIfNeeded $Node
	$aieTree itemconfigure $Node -image $VisibilityImages($visimg($vis))
	UpdateAncestors [lindex $Node 0]
    }
}

proc ::AIEnv::GUIManagement::Tree::UpdateGeomNodes {} {
    variable aieTree
    variable VisibilityImages
    variable VisibilityContextMenuMap
    global aie_ShowDormant

    doInsertIfNeeded geomNode
    set font [$aieTree itemcget geomNode -font]
    if ![ic_geo_is_loaded] {
	set geo_nodes ""
	foreach node {Point Curve Surf Body Density _subset} {
	    if [$aieTree exists geom${node}Node] {
		lappend geo_nodes geom${node}Node
	    }
	}
	$aieTree delete $geo_nodes
	catch {unset VisibilityContextMenuMap(geomNode)}
    } else {
	foreach node {Point Curve Surf Body Density _subset} \
                name {Points Curves Surfaces Bodies Densities Subsets} {
	    if ![$aieTree exists geom${node}Node] {
		delayedInsert end geomNode geom${node}Node -text $name \
		    -font $font -image $VisibilityImages(notVisImg)
	    }
	}
	set VisibilityContextMenuMap(geomNode) geomContextMenu
    }
    if ![llength [$aieTree nodes geomNode]] {
	$aieTree itemconfigure geomNode -image $VisibilityImages(notVisImg)
    }
    # update the display of dormant points and curves
    foreach "type type2" {point Point curve Curve} {
        if ![::AIEnv::GUIManagement::Tree::NodeVisibility geom${type2}Node] continue
        if {[info exists aie_ShowDormant($type)] && $aie_ShowDormant($type)} {
            ::AIEnv::GUIManagement::Tree::ShowDormant $type
        }
    }
}

proc ::AIEnv::GUIManagement::Tree::UpdateMeshNodes {} {
    variable aieTree
    variable VisibilityImages
    variable VisibilityContextMenuMap
    global doInsertAllDone

    doInsertIfNeeded meshNode
    set font [$aieTree itemcget meshNode -font]
    if ![ic_uns_is_loaded] {
	    set uns_nodes ""
	    foreach node {Point Line Shell Volume} {
	        if [$aieTree exists mesh${node}Node] {
		        lappend uns_nodes mesh${node}Node
	        }
	    }
	    $aieTree delete $uns_nodes
	    catch {unset VisibilityContextMenuMap(meshNode)}
	
	    foreach ss [$aieTree nodes mesh_subsetNode] {
	        $aieTree delete $ss
	    }
        #foreach ss [$aieTree nodes mesh_contactNode] {
        #    $aieTree delete $ss
        #}
    } else {
        if ![info exists doInsertAllDone] {
            set types [ic_uns_list_types]
            foreach node {Tri Quad Hexa Tetra Penta Pyra} {
                if {[$aieTree exists mesh${node}Node] && [lsearch $types [string toupper $node]_*] < 0} {
                    $aieTree delete mesh${node}Node
                }
            }
        }
    }

    if ![ic_str_is_loaded] {
	    set str_nodes ""
	    foreach node {domain subface edge vertex} {
	        if [$aieTree exists mesh_${node}Node] {
		        lappend str_nodes mesh_${node}Node
	        }
	    }
	    $aieTree delete $str_nodes
    }

    if [ic_uns_is_loaded] {
	    foreach node {Point Line Shell Volume} name {Points Lines Shells Volumes} {
	        if ![$aieTree exists mesh${node}Node] {
		        delayedInsert end meshNode mesh${node}Node -text $name \
		            -data "unsmesh $node" -font $font -image $VisibilityImages(notVisImg)
	        }
	    }
	    foreach node {Tri Quad} name {Triangles Quads} {
	        if ![$aieTree exists mesh${node}Node] {
                delayedInsert end meshShellNode mesh${node}Node -text $name \
                    -data "unsmesh $node" -font $font -image $VisibilityImages(notVisImg)
            }
        }
        foreach node {Hexa Tetra Penta Pyra} name {Hexahedra Tetrahedra Prisms Pyramids} {
            if ![$aieTree exists mesh${node}Node] {
                delayedInsert end meshVolumeNode mesh${node}Node -text $name \
                    -data "unsmesh $node" -font $font -image $VisibilityImages(notVisImg)
            }
        }
        set VisibilityContextMenuMap(meshNode) meshUnsContextMenu
    }

    if [ic_str_is_loaded] {
	    foreach node {domain subface edge vertex} name {Domains Subfaces Edges Vertices} {
	        if ![$aieTree exists mesh_${node}Node] {
		        delayedInsert end meshNode mesh_${node}Node -text $name \
		            -data "strmesh $node" -font $font -image $VisibilityImages(notVisImg)
	        }
	    }
    }
    if ![llength [$aieTree nodes meshNode]] {
	    $aieTree itemconfigure meshNode -image $VisibilityImages(notVisImg)
    }
}

proc ::AIEnv::GUIManagement::Tree::UpdateBlockingNodes {} {
    variable aieTree
    variable VisibilityImages
    variable VisibilityContextMenuMap
    global env

    doInsertIfNeeded blockingNode
    set font [$aieTree itemcget blockingNode -font]
    if ![ic_hex_blocking_loaded] {
        set block_nodes ""
        if [$aieTree exists block_subsetNode] {
            lappend block_nodes block_subsetNode
        }
        foreach node {vert edge face block mesh} {
            if [$aieTree exists block_${node}Node] {
                lappend block_nodes block_${node}Node
            }
        }
        if [$aieTree exists topoNode] {
            lappend block_nodes topoNode
        }
        $aieTree delete $block_nodes
        catch {unset VisibilityContextMenuMap(blockingNode)}
    } else {
        if ![$aieTree exists block_subsetNode] {
            doInsert end blockingNode block_subsetNode -text "Subsets" -image  $VisibilityImages(isVisImg) -data "block_subset *"
        }
	
        if ![info exists env(AI_ENV_LSTC)] {
            set hexmesh "Pre-Mesh"	    
        } else {
            set hexmesh "Mesh"
	    }
	    foreach node {vert edge face block mesh} name [list Vertices Edges Faces Blocks $hexmesh] {
	        if ![$aieTree exists block_${node}Node] {
                doInsert end blockingNode block_${node}Node -text $name -data "blocking $node" -font $font -image $VisibilityImages(notVisImg)
	        }
	    }
        if ![$aieTree exists topoNode] {
            doInsert end blockingNode topoNode -text "Topology" -font $font -data "topo *" -image  $VisibilityImages(isVisImg)
        }
        set VisibilityContextMenuMap(blockingNode) blockingContextMenu
    }

    if [$aieTree exists blockingNode] {
        if ![llength [$aieTree nodes blockingNode]] {
            $aieTree itemconfigure blockingNode -image $VisibilityImages(notVisImg)
        }
    }
}

proc ::AIEnv::GUIManagement::Tree::UpdateUnsMeshVisibility {{type all}} {
    global aie_meshTypeVis batch_mode
    variable aieTree
    variable VisibilityImages
    
    if $batch_mode return
    
    UpdateMeshNodes
    if {$type == "all"} {
	    set types {node line shell volume}
    } else {
	    set types $type
    }
    array set visimg { 0 notVisImg 1 someVisImg 2 isVisImg}
    array set dimname { node 0d line 1d shell 2d volume 3d }
    foreach type $types {
	    if [info exists dimname($type)] {
	        if ![ic_count_elements $dimname($type)] continue
	    } else {
	        if ![ic_count_elements $type] continue
	    }
	    switch $type {
	        node   { set nodes Point; set vtypes node }
	        line   { set nodes Line; set vtypes line }
	        shell  {
		        set nodes Shell
		        set vtypes shell
		        foreach i {Tri Quad} {
		            if [ic_count_elements [string tolower $i]] {
			            lappend nodes $i
			            lappend vtypes [string tolower $i]
		            }
		        }
	        }
	        volume {
		        set nodes Volume
		        set vtypes volume
		        foreach i {Tetra Hexa Penta Pyra} {
		            if [ic_count_elements [string tolower $i]] {
			            lappend nodes $i
			            lappend vtypes [string tolower $i]
		            }
		        }
	        }
	        default {
		        set nodes [string totitle $type]
		        set vtypes $type
	        }
	    }
	    foreach node $nodes type $vtypes {
	        set node2 mesh${node}Node
	        doInsertIfNeeded $node2
	        set vis $aie_meshTypeVis($type)
	        $aieTree itemconfigure $node2 -image $VisibilityImages($visimg($vis))
	        UpdateAncestors $node2
	    }
    }
}

proc ::AIEnv::GUIManagement::Tree::UpdateStrMeshVisibility {} {
    variable aieTree
    variable VisibilityImages        
    global str_type_visible batch_mode
 
    if $batch_mode { return }
    UpdateMeshNodes

    foreach type {domain subface edge vertex} {
	    set node mesh_${type}Node
	    doInsertIfNeeded $node
	    if $str_type_visible($type) {
	        $aieTree itemconfigure $node -image $VisibilityImages(isVisImg)
	    } else {
	        $aieTree itemconfigure $node -image $VisibilityImages(notVisImg)
	    }
	    UpdateAncestors $node
    }
}

proc ::AIEnv::GUIManagement::Tree::UpdateBlockingVisibility {} {
    variable aieTree
    variable VisibilityImages        
    global display_flag batch_mode

    if $batch_mode return
    
    UpdateBlockingNodes
    foreach type {vert edge face block mesh} {
	    set node block_${type}Node
	    doInsertIfNeeded $node
	    if $display_flag($type) {
	        $aieTree itemconfigure $node -image $VisibilityImages(isVisImg)
	    } else {
	        $aieTree itemconfigure $node -image $VisibilityImages(notVisImg)
	    }
	    UpdateAncestors $node
    }
}

proc ::AIEnv::GUIManagement::Tree::UpdateElemPropNodes {{on 0}} {
    global aie_bctypes_used current_bc_vis

    set topval [::AIEnv::GUIManagement::Tree::NodeVisibleStatus partbc *]
    
    foreach dimens {0 1 2 3} {
       set dimtype element_prop_${dimens}d
       set dim_bctypes $aie_bctypes_used($dimtype)
       foreach part_name [aie_list_parts 0] {
          set vstat 1
          set subbc ""
          foreach poss $aie_bctypes_used($dimtype) {
	    if {[ic_boco_get $part_name $poss] != ""} {
	       set subbc $poss
	       break
	    }
          }
          if {$subbc != ""} {
             set val [::AIEnv::GUIManagement::Tree::NodeVisibleStatus partbc $subbc]
             set current_bc_vis($subbc) $val
          }
       }
    }

    ::AIEnv::GUIManagement::Tree::clear partbc
    
    foreach dimens {0 1 2 3} {
       set dimtype element_prop_${dimens}d
       set dim_bctypes $aie_bctypes_used($dimtype)
       foreach part_name [aie_list_parts 0] {
          set vstat 1
		switch $on {
			0 - 1 {set vstat $on}
			2 {
			set weird_status [::AIEnv::GUIManagement::Tree::NodeVisibleStatus part $part_name]
			if $weird_status {
				set vstat [expr ($weird_status+1)/2]
			}
			}
		}
	 if {[ic_boco_get $part_name $dim_bctypes] != ""} {
             ::AIEnv::GUIManagement::Tree::AddPartBC $dimtype $part_name $vstat
          }
          set subbc ""
          foreach poss $aie_bctypes_used($dimtype) {
	    if {[ic_boco_get $part_name $poss] != ""} {
	       set subbc $poss
	       break
	    }
          }
          if {[info exists current_bc_vis($subbc)]} {
             set val $current_bc_vis($subbc)
             ::AIEnv::GUIManagement::Tree::NodeVisibleStatus partbc $subbc $val
          }
       }
    }

    ::AIEnv::GUIManagement::Tree::NodeVisibleStatus partbc * $topval
    ::AIEnv::GUIManagement::Tree::treeOpen partbcNode
    
}

proc ::AIEnv::GUIManagement::Tree::ShowGeometry {vis} {
    global aie_geoTypeVis

    if ![ic_geo_is_loaded] {
        mess "Warning: No Geometry Database Available\n" red
        return
    }
    foreach type {point curve surface body density} {
        set aie_geoTypeVis($type) $vis
    }
    aie_updateGeoVis
}

proc ::AIEnv::GUIManagement::Tree::ShowMesh {vis} {
    global aie_meshTypeVis str_type_visible

    if [ic_str_is_loaded] {
        foreach type {domain subface edge vertex} {
            set str_type_visible($type) $vis
        }
    } elseif [ic_uns_is_loaded] {
        foreach type {node line shell volume} {
            set aie_meshTypeVis($type) $vis
        }
    } else {
        mess "Warning: No Mesh Database Available\n" red
        return
    }
    aie_updateMeshVis
}

proc ::AIEnv::GUIManagement::Tree::ShowLCS {image node} {
    variable aieTree
    variable VisibilityImages
    
#	only one lcs is visible and active!!
#	image: 0 - Text selected event (ignore), 
#          1 - image selected event (toggle), 2-show

	if !$image return
	set vis $VisibilityImages(isVisImg)
	set nvis $VisibilityImages(notVisImg)
	if [$aieTree exists $node] {
		set wasimage [$aieTree itemcget $node -image]
		set name     [$aieTree itemcget $node -text]
	}
	# Delete Tree if no such csystem!
	if ![llength [ic_csystem_get $name]] {
		::AIEnv::GUIManagement::Tree::DeleteLCS $name
		return
	}
	foreach lcs [$aieTree nodes lcsNode] {
		$aieTree itemconfigure $lcs -image $nvis
	}
	if {$wasimage == $nvis || $image == 2} {
		$aieTree itemconfigure $node -image $vis
		ic_csystem_display $name 1
		aie_set_lcs_current type $name
	} else {
		ic_csystem_display all 0
		aie_set_lcs_current type global
	}
}
proc ::AIEnv::GUIManagement::Tree::ShowGroup {types treeNode {on ""}} {
    variable aieTree
    variable VisibilityImages
    
    array set visimg { 0 notVisImg 1 someVisImg 2 isVisImg }
    if {$on == ""} {
        set im [$aieTree itemcget $treeNode -image]
        if {$im == $VisibilityImages(notVisImg) } { set on 2 } else { set on 0 }
    }
    set on [expr $on == 2]
    foreach type $types {
		if {$type == "part"} {
			if $on {
				::AIEnv::GUIManagement::Tree::Parts show
			} else {
				::AIEnv::GUIManagement::Tree::Parts hide			
			}
		} else {
			ToggleGroupVisibility $type * $on
		}
    }
}

proc ::AIEnv::GUIManagement::Tree::GetAllChildren {par} {
    variable aieTree
    variable allsubnodes
    
    if ![info exists allsubnodes] {
        set allsubnodes ""
    }
    if [$aieTree exists $par] {
        foreach p [$aieTree nodes $par] {
            lappend allsubnodes $p
            ::AIEnv::GUIManagement::Tree::GetAllChildren $p
        }
    }
}

proc ::AIEnv::GUIManagement::Tree::SaveTreeStatus {} {
    global aie_tree_nodes aie_tree_param_nodes
    global savedTreeVisibility
    variable aieTree
    variable VisibilityImages
    variable allsubnodes

    catch {unset savedTreeVisibility}

    if ![info exists savedTreeVisibility] {
	set savedTreeVisibility ""
	foreach i {geomNode meshNode  blockingNode \
                   lcsNode tblNode partbcNode partNode paramsNode subcaseNode lsdynaParamsNode} {
	    if [$aieTree exists $i] {
	       set im [$aieTree itemcget $i -image]
	       set on 0
	       if {$im == $VisibilityImages(isVisImg)} { set on 2 }
	       if {$im == $VisibilityImages(notVisImg)} { set on 0 }
	       if {$im == $VisibilityImages(someVisImg)} { set on 1 }
	       lappend savedTreeVisibility $i $on
                catch {unset allsubnodes}
                set allsubnodes ""
                ::AIEnv::GUIManagement::Tree::GetAllChildren $i
	       foreach p $allsubnodes {
	          set im [$aieTree itemcget $p -image]
	          set on 0
	          if {$im == $VisibilityImages(isVisImg)} { set on 2 }
	          if {$im == $VisibilityImages(notVisImg)} { set on 0 }
	          if {$im == $VisibilityImages(someVisImg)} { set on 1 }
                   if {$p == "block_meshNode"} {set on 0}
	          lappend savedTreeVisibility $p $on
	       }
	    }
	}
	foreach nn [lsort [array names aie_tree_nodes]] {
	    set i ${nn}Node
	    if [$aieTree exists $i] {
	       set im [$aieTree itemcget $i -image]
	       set on 0
	       if {$im == $VisibilityImages(isVisImg)} { set on 2 }
	       if {$im == $VisibilityImages(notVisImg)} { set on 0 }
	       if {$im == $VisibilityImages(someVisImg)} { set on 1 }
	       lappend savedTreeVisibility $i $on
                catch {unset allsubnodes}
                set allsubnodes ""
                ::AIEnv::GUIManagement::Tree::GetAllChildren $i
	       foreach p $allsubnodes {
	          set im [$aieTree itemcget $p -image]
	          set on 0
	          if {$im == $VisibilityImages(isVisImg)} { set on 2 }
	          if {$im == $VisibilityImages(notVisImg)} { set on 0 }
	          if {$im == $VisibilityImages(someVisImg)} { set on 1 }
	          lappend savedTreeVisibility $p $on
	       }
	    }
	}    
	foreach name [lsort [array names aie_tree_param_nodes]] {
	    set tn $aie_tree_param_nodes($name)
	    set par [lindex $tn 0] 
	    if {$par != ""} {
	       set i ${par}Node
	       if [$aieTree exists $i] {
	          set im [$aieTree itemcget $i -image]
	          set on 0
	          if {$im == $VisibilityImages(isVisImg)} { set on 2 }
	          if {$im == $VisibilityImages(notVisImg)} { set on 0 }
	          if {$im == $VisibilityImages(someVisImg)} { set on 1 }
	          lappend savedTreeVisibility $i $on
                   catch {unset allsubnodes}
                   set allsubnodes ""
                   ::AIEnv::GUIManagement::Tree::GetAllChildren $i
	          foreach p $allsubnodes {
	             set im [$aieTree itemcget $p -image]
	             set on 0
	             if {$im == $VisibilityImages(isVisImg)} { set on 2 }
	             if {$im == $VisibilityImages(notVisImg)} { set on 0 }
	             if {$im == $VisibilityImages(someVisImg)} { set on 1 }
	             lappend savedTreeVisibility $p $on
	          }
	       }
             }
	}
    }
    
}

proc ::AIEnv::GUIManagement::Tree::RestoreTreeStatus {} {
    global savedTreeVisibility
    variable aieTree
    variable VisibilityImages
    variable VisibilityFunctionMap	
    if ![info exists savedTreeVisibility] return
    if {$savedTreeVisibility == ""} return
    set ta [tdv_active 0]
    busy 1
    set list_parts_on ""
    set list_parts_off ""      
    foreach {n v} $savedTreeVisibility {
        if {$v == "1"} continue
        if ![$aieTree exists $n] continue
        if {[string range $n 0 4] == "part-"} {
           if $v {
              lappend list_parts_on [string range $n 5 end]
           } else {
              lappend list_parts_off [string range $n 5 end]
           }
        } else {
           set im [$aieTree itemcget $n -image]
           set on 0
           if {$im == $VisibilityImages(isVisImg)} { set on 2 }
           if {$im == $VisibilityImages(notVisImg)} { set on 0 }
           if {$im == $VisibilityImages(someVisImg)} { set on 1 }
           if {$v != $on} {
              ::AIEnv::GUIManagement::Tree::treeSelect 1 $n
           }
        }
    }
    if {$list_parts_on != ""} {::AIEnv::GUIManagement::Tree::Parts show $list_parts_on}
    if {$list_parts_off != ""} {::AIEnv::GUIManagement::Tree::Parts hide $list_parts_off	}
    busy 0
    tdv_active $ta
    unset savedTreeVisibility
}

proc ::AIEnv::GUIManagement::Tree::DeleteEmptyGroup {type} {
    variable aieTree
    variable allsubnodes

    catch {unset allsubnodes}
    set allsubnodes ""
    set i ${type}Node
    ::AIEnv::GUIManagement::Tree::GetAllChildren $i
    foreach p $allsubnodes {
       if {[string match ${type}-Set_* $p] && ([$aieTree nodes $p] == "")} {
          $aieTree delete $p
       }
    }
}

proc ::AIEnv::GUIManagement::Tree::GetParent {child} {
    variable aieTree

    regsub -all {[ \t\n]} $child _ child
    if [$aieTree exists $child] {
        return [$aieTree parent $child]
    }
}
