
proc aie_do_mesh_contacts {how onegroup dist paramname paramvals contlist targlist \
                            {contactpartlist ""} } {
    if {$how != "update"} {
	# First get rid of all the old contact data
	if {$paramname == "ALL"} {
	    set delpat "CONTACT * *"
	} else {
	    set delpat "CONTACT $paramname *"
	}
	foreach omap [ic_uns_map_list 0 $delpat] {
	    ic_uns_subset_delete $omap
	    ::AIEnv::GUIManagement::Tree::DeleteGroup contact [lindex $omap 1] 0
	}
    }
    
    # Get back the new sets - this is going to be grouped by family and not part,
    # so we need to create new subsets for parts.
    switch $how {
	auto {
	    set stuff [ic_uns_contact_sets $dist $contactpartlist]
	}
	manual {
	    # First off, if the user has picked surfaces, convert to elements.
	    if ![string match uns_* $contlist] {
		set sub [ic_uns_subset_create]
		foreach sn $contlist {
		    set sub1 [ic_uns_get_attached_elements surface $sn]
		    ic_uns_subset_add_from $sub $sub1
		    ic_uns_subset_delete $sub1
		}
		set contlist $sub
	    }
	    
	    if ![string match uns_* $targlist] {
		set sub [ic_uns_subset_create]
		foreach sn $targlist {
		    set sub1 [ic_uns_get_attached_elements surface $sn]
		    ic_uns_subset_add_from $sub $sub1
		    ic_uns_subset_delete $sub1
		}
		set targlist $sub
	    }
	    
	    mess "Found [ic_uns_subset_count_elements $contlist] in contact, [ic_uns_subset_count_elements $targlist] in target\n"
	    
	    # Segment the maps by part
	    set contmaps ""
	    foreach p [ic_uns_subset_families_used $contlist 1] {
		set m2 [ic_uns_subset_copy_only_families $contlist $p 1]
		lappend contmaps $p $m2
	    }
	    set targmaps ""
	    foreach p [ic_uns_subset_families_used $targlist 1] {
		set m2 [ic_uns_subset_copy_only_families $targlist $p 1]
		lappend targmaps $p $m2
	    }
	    # Now do all pairs
	    set stuff ""
	    foreach {cp cm} $contmaps {
		foreach {tp tm} $targmaps {
		    # Allow only lines and shells here
		    lappend stuff $cp [ic_uns_subset_copy "" $cm "1 2"] \
			$tp [ic_uns_subset_copy "" $tm "1 2"]
		}
	    }
	    foreach m $contmaps { ic_uns_subset_delete $m }
	    foreach m $targmaps { ic_uns_subset_delete $m }
	    ic_uns_subset_delete $contlist
	    ic_uns_subset_delete $targlist
	    
	    set onegroup 0
	}
	update {
	}
    }

    foreach {f1 m1 f2 m2} $stuff {
	set p1 [lindex [split $f1 :] 0]
	set p2 [lindex [split $f2 :] 0]
	lappend part_maps([list $p1 $p2]) $m1 $m2
    }
    
    # The mesh_contactNode is unused now
    set vis [::AIEnv::GUIManagement::Tree::NodeVisibility contactNode]
    
    tdv_active 0
    foreach pair [array names part_maps] {
	# Disallow self-contacts for auto
	if {$how == "auto"} {
	    if {[lindex $pair 0] == [lindex $pair 1]} {
		foreach map $part_maps($pair) {
		    ic_uns_subset_delete $map
		}
		continue
	    }
	}
	
	if {($how == "auto") && !$onegroup} {
	    set group ${paramname}_[join [lsort $pair] _]
	} else {
	    set group $paramname
	}
	# Otherwise the contact groups get really wierd looking
	regsub -all / $group _ group
	
	set ssname1 "CONTACT $group [lindex $pair 0] [lindex $pair 1] CONTACT"
	set ssname2 "CONTACT $group [lindex $pair 1] [lindex $pair 0] TARGET"

	set groupnames($group) 1
	
	if ![ic_uns_subset_exists $ssname1] {
	    ic_uns_subset_create $ssname1 $vis
	    ic_uns_subset_configure $ssname1 -width 3
	    ic_uns_subset_color $ssname1 white
	}
	if ![ic_uns_subset_exists $ssname2] {
	    ic_uns_subset_create $ssname2 $vis
	    ic_uns_subset_configure $ssname2 -width 3
	    ic_uns_subset_color $ssname2 red
	}
	foreach {map1 map2} $part_maps($pair) {
	    ic_uns_subset_add_from $ssname1 $map1
	    ic_uns_subset_add_from $ssname2 $map2
	    ic_uns_subset_delete $map1
	    ic_uns_subset_delete $map2
	    mess "Contact between [lindex $pair 0] ([ic_uns_subset_count_elements $ssname1]) and [lindex $pair 1] ([ic_uns_subset_count_elements $ssname2])\n"
	}
    }
    foreach group [array names groupnames] {
	::AIEnv::GUIManagement::Tree::AddGroup contact $group $vis
	ic_param_set_values :contact/$group $paramvals
    }
    tdv_active 1
}

proc aie_create_mesh_contact {} {
}

proc aie_edit_contact {name} {
    global current_contact_to_load
    catch {unset current_contact_to_load}
    if {$name == "*"} {
	#array set current_contact_to_load { name CONTACT dist 0.05 }
        createContactDEZ show
    } else {
        array set current_contact_to_load [ic_param_get_values :contact/$name]
        set current_contact_to_load(name) $name
        createExistingContactDEZ show
    }
#    createContactDEZ show
}

proc onContactMeshDEZLoad {} {
    global aie_mesh_contact
    
    set onegroup 1
    foreach {n v} [array get aie_mesh_contact] { set $n $v }
}

proc onContactMeshDEZApply {} {
    global aie_mesh_contact
    
    foreach {n ov} [array get aie_mesh_contact] {
        if [info exists $n] { set aie_mesh_contact($n) [set $n] }
    }
    aie_do_mesh_contacts $aie_mesh_contact(dist) $aie_mesh_contact(name)
    ic_param_set_values :contact/$aie_mesh_contact(name) [array get aie_mesh_contact]
}

proc aie_switch_contact {name} {
    global contact_switch
    foreach omap [ic_uns_map_list 0 "CONTACT $name *"] {
        set vis 1
	    set p1 [lindex $omap 2]
	    set p2 [lindex $omap 3]
	    set tt [lindex $omap 4]
	    if {$tt == "CONTACT"} {
	        set omap2 "CONTACT $name $p2 $p1 TARGET"
	        ic_uns_subset_rename $omap __temp_contact__
	        ic_uns_subset_rename $omap2 $omap
	        ic_uns_subset_rename __temp_contact__ $omap2
	        ic_uns_subset_color $omap white
	        ic_uns_subset_color $omap2 red
            if ![info exists contact_switch($name)] {
                 set contact_switch($name) 1
            } else {
                 unset contact_switch($name)
            }
	    }
    }
}

proc aie_delete_contact {name} {
    global contact_switch
    ::AIEnv::GUIManagement::Tree::DeleteGroup contact $name 0
    foreach omap [ic_uns_map_list 0 "CONTACT $name *"] {
        ic_uns_subset_delete $omap
    }
    ic_param_delete_node :contact/$name
    catch { unset contact_switch($name) }
}

proc aie_rename_contact {name} {
    global contact_switch
    set newname [question_box .newname "New name" "New name for contact set $name" $name]
    if {$newname == ""} return
    if {$newname == $name} return
    foreach omap [ic_uns_map_list 0 "CONTACT $name *"] {
        ic_uns_subset_rename $omap [list CONTACT $newname [lindex $omap 2] [lindex $omap 3] [lindex $omap 4]]
    }
    ic_param_rename :contact/$name :contact/$newname 0
    if [info exists contact_switch($name)] {
        unset contact_switch($name)
        set contact_switch($newname) 1
    }    
    ::AIEnv::GUIManagement::Tree::RenameGroup contact $name $newname
}

proc aie_show_contact {name on} {
    global aie_show_contact_message_printed contact_switch

    if ![info exists aie_show_contact_message_printed] {
        mess "WHITE is contact, RED is target\n"
        set aie_show_contact_message_printed 1
    }

    foreach map [ic_uns_map_list 0 "CONTACT $name *"] {
        set n [lindex $map 1]
        lappend contact_show($n) [lindex $map 4]
        switch [lindex $map 4] {
            CONTACT { set contact_map($n) $map }
            TARGET { set target_map($n) $map }
        }
        if ![info exists contact_switch($n)] {
            if {[lindex $contact_show($n) 0] == "TARGET"} {
                if [info exists target_map($n)] { ic_uns_subset_visible $target_map($n) $on }
                if [info exists contact_map($n)] { ic_uns_subset_visible $contact_map($n) $on }
            } else {
                if [info exists contact_map($n)] { ic_uns_subset_visible $contact_map($n) $on }
                if [info exists target_map($n)] { ic_uns_subset_visible $target_map($n) $on }
            }
        } else {
            if [info exists contact_map($n)] { ic_uns_subset_visible $contact_map($n) 0 }
            if [info exists target_map($n)] { ic_uns_subset_visible $target_map($n) 0 }
            if $on {
                if {[lindex $contact_show($n) 0] == "TARGET"} {
                    if [info exists contact_map($n)] { ic_uns_subset_visible $contact_map($n) 1 }
                    if [info exists target_map($n)] { ic_uns_subset_visible $target_map($n) 1 }
                } else {
                    if [info exists target_map($n)] { ic_uns_subset_visible $target_map($n) $on }
                    if [info exists contact_map($n)] { ic_uns_subset_visible $contact_map($n) $on }
                }
            }
        }
        unset contact_show($n)
    }
}

proc aie_init_contact {} {
    if ![ic_uns_is_loaded] return
    set vis [::AIEnv::GUIManagement::Tree::NodeVisibility mesh_contactNode]
    foreach map [ic_uns_map_list 0 "CONTACT *"] {
	    set want([lindex $map 1]) 1
	    ic_uns_subset_configure $map -width 3
	    switch [lindex $map 4] {
	        CONTACT {
                ic_uns_subset_color $map white
	        }
	        TARGET {
                ic_uns_subset_color $map red
	        }
	    }
	    ic_uns_subset_visible $map $vis
    }
    if [catch {
	# if this is icemcfd and we are loading an ai*env mesh this could fail
	    foreach name [lsort [array names want]] {
	        ::AIEnv::GUIManagement::Tree::AddGroup contact $name $vis
	    }
    } res] { puts $res }
}
