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

proc domain_load_struct {domain_prefix topofile famtopofile \
	subfaceprojfile only_dom \
	{auto_topo 0}} {
    global str_cur str_option batch_mode
    
    if ![check_mesh_functions_enabled] {
	license_unavailable_warning
	return ""
    }
    
    # This is needed because pcube might name the domains using arbitrary
    # filenames that are unrelated to the actual domain numbers
    set pcube_nums ""
    set doms [glob -nocomplain $domain_prefix.*]
    foreach d $doms {
	set ns [string range [file extension $d] 1 end]
	if {[scan $ns %d ns1] == 1} {
	    lappend pcube_nums $ns1
	}
    }
    set pcube_nums [lsort -integer $pcube_nums]
    
    busy 1
    if {$str_cur == ""} {
	set str_cur [str_mesh -update_undo_cmd undo_redo_update]
	$str_cur initialize_mesh
	undo_redo_update 0 0
	set merging 0
    } else {
	set merging 1
    }
    
    if {$only_dom != ""} {
	if ![string match */* $only_dom] {
	    set only_dom [file dirname $domain_prefix]/$only_dom
	}
	set cmd "$str_cur load_domain_single $only_dom"
    } else {
	set cmd [list $str_cur load_domain [file dirname $domain_prefix] \
		     [file tail $domain_prefix]. \
		     $topofile $famtopofile $subfaceprojfile $pcube_nums]
    }

    if [catch $cmd res] {
	mess $res\n red
	set str_cur ""
	busy 0
	return ""
    }
    
    if {$merging && !$batch_mode} {
	set mess "You can merge the common subfaces, edges, and vertices now,\
		or keep them separate.  You can merge them later\
 		using the Copy/move form."
	if {$auto_topo || ![tk_dialog .comptopo "Recompute topology" \
		$mess "" -1 "Merge" "Keep separate"]} {
	    ic_str_recompute_topo
	}
    }
    
    if ![$str_cur num_topo_objects domain] {
	mess "No domains were found\n" red
	$str_cur delete
	set str_cur ""
	busy 0
	return ""
    }
    if ![$str_cur num_topo_objects subface] {
	if {[$str_cur num_topo_objects domain] == 1} {
	    mess "Creating basic subfaces for one domain\n"
	    $str_cur set_basic_topo
	    
	} else {
	    if {$auto_topo || \
		    (!$batch_mode && ![tk_dialog .comptopo "Recompute topology" \
		    "There is no topology for this mesh.  You can either recompute the full topology, which may take some time, or set up a basic topology which has every domain unattached to the others." "" -1 "Recompute" "Basic topo"])} {
		mess "Please wait: computing topology\n"
		$str_cur assign_subface_families
		$str_cur recompute_topo "" ""
	    } else {
		mess "Creating basic subfaces for domains\n"
		$str_cur set_basic_topo
	    }
	}
    }
    
    if {[$str_cur num_topo_objects domain] > 100} {
	set str_option(domain,names) 0
    } else {
	set str_option(domain,names) 1
    }
    $str_cur check
    str_topo_surfs $str_cur
    
    busy 0
    struct_summary $str_cur
    $str_cur configure -modified 0
    return $str_cur
}

proc str_topo_surfs {str} {
    global str_type_visible
    
    str_topo_clear_surfs $str
    
    # Leave the rest for on-the-fly.  We need the domains for other reasons.
    foreach i [array names str_type_visible] {
	if {($i == "domain") || $str_type_visible($i)} {
	    str_topo_make_surfs $str $i 1
	}
    }
}

proc list_families_for_type {str type} {
    foreach inf [$str get_topo_info $type 0 0] {
	set found([lindex $inf 2]) 1
    }
    catch {unset found()}
    return [lsort [array names found]]
}

proc str_topo_make_surfs {str stype force} {
    global str_cur str_was_visible
    
    if {!$force && ([$str_cur get_surf $stype 1] != "")} return
    
    busy 1
    foreach inf [$str get_topo_info $stype 0 0] {
	set fam [lindex $inf 2]
	set num [lindex $inf 3]
	if [info exists str_was_visible($stype,$num)] {
	    set vis $str_was_visible($stype,$num)
	} else {
	    set vis [expr {$fam != ""}]
	}
	str_topo_make_surf $stype $num $inf $vis
    }
    
    foreach inf [$str get_periodic_info $stype] {
	set s1 [$str_cur get_surf $stype [lindex $inf 0]]
	set s2 [$str_cur get_surf $stype [lindex $inf 1]]
	$s1 configure -twin_surf $s2
	$s2 configure -twin_surf $s1
    }
    
    busy 0
}

proc str_topo_make_one_surf {str stype num} {
    global str_cur
    
    set inf [lindex [$str_cur get_topo_info $stype $num 1] 0]
    set im [str_topo_make_surf $stype $num $inf 1]
    
    disp_set_option_one $stype $num
    disp_update_number_list $stype
}

proc str_topo_make_surf {stype num inf vis} {
    global str_cur batch_mode
    global tdv_default
    
    set im [str_surf -mesh $str_cur -visible 0 \
		-name [lindex $inf 0] -surftype $stype \
		-family [lindex $inf 2] -number $num]
    $im add_ijk [lindex $inf 4] [lindex $inf 5] [lindex $inf 6]
    if !$batch_mode {
    	$tdv_default add_image $im
    	$tdv_default add_tag $im str_$stype
    }
    
    $im configure -visible $vis \
	-color_fam [family_color_for_name [lindex $inf 2]]
    
    foreach inf2 [$str_cur get_topo_info $stype $num 1] {
	set dom [lindex $inf2 4]
	set str_domain_visible($stype,$dom) 0
    }
    return $im
}

proc str_recolor_objects {} {
    global str_cur
    
    foreach s [$str_cur list_surfs all] {
	set fam [$s get -family]
	$s configure -color_fam [family_color_for_name $fam]
    }
}


proc str_topo_delete_surf {str surf} {
    set stype [$surf get -surftype]
    set num [$surf get -number]
    set fam [$surf get -family]
    
    $surf delete
    disp_update_number_list $stype
}

proc str_topo_clear_surfs {str} {
    global str_cur str_was_visible
    
    catch {unset str_was_visible}
    
    foreach im [$str_cur list_surfs all] {
	set str_was_visible([$im get -surftype],[$im get -number]) \
	    [$im get -visible]
	$im delete
    }
}

proc struct_summary {{str ""}} {
    global str_cur
    
    if {$str == ""} {
	set str $str_cur
    }
    mess "[$str num_topo_objects domain] domains\n"
    mess "[$str num_topo_objects subface] subfaces\n"
    mess "[$str num_topo_objects edge] edges\n"
    mess "[$str num_topo_objects vertex] vertices\n"

    mess "Total cells : [$str count cells]\n"
    mess "Total nodes : [$str count nodes]\n"
    mess "Min : [lindex [$str domain_bbox 0] 0]\n"
    mess "Max : [lindex [$str domain_bbox 0] 1]\n"
    set nd [$str num_topo_objects domain]
    for {set i 1} {$i <= $nd} {incr i} {
	set inf [$str_cur get_topo_info domain $i 1]
	mess "Domain $i: [lindex [lindex $inf 0] 6]\n"
    }
    mess \n
}

proc str_topo_visible_surfs {str} {
    global str_surf str_cur
    
    set ret ""
    foreach im [$str_cur list_surfs all] {
	if [$im get -visible] {
	    lappend ret $im
	}
    }
    return $ret
}

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

proc domain_copy {odom do_build} {
    global struct_domain
    
    set ns [nodeset]
    $ns copy_nodes_from [$odom get -nodes]
    
    set opts ""
    foreach i {imin imax nodes_imin nodes_imax skip some_dead} {
	lappend opts -$i [$odom get -$i]
    }

    set num [expr [llength [array names struct_domain]] + 1]
    set dfile [file rootname [$odom get -filename]].$num
    
    set str [eval struct_mesh -nodes $ns -filename $dfile $opts \
	    -came_from [$odom get -number] -modified 1]
    set struct_domain($num) $str
    
    if $do_build {
	domain_build_one domain DOM $num [$str get -imin] [$str get -imax]
    }
    
    return $str
}
