
# 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 pick_struct_entity {what} {
    global ai_environment
    while 1 {
	set ss [select_struct_surf $what 0]
	if {$ss == ""} return
	foreach s $ss {
	    if { ([info exists ai_environment] && $ai_environment) } {
	        mess "name [ic_str_get_name $what $s] type $what part [ic_str_get_family $what $s] number $s\n"
	    } else {
	        mess "name [ic_str_get_name $what $s] type $what family [ic_str_get_family $what $s] number $s\n"
	    }
	    foreach ii [ic_str_get_ijk $what $s] {
		mess "    dom [lindex $ii 0] : [lindex $ii 1] -> [lindex $ii 2]\n"
	    }
	}
    }
}

proc struct_diag {} {
    global struct_diag
    
    set buts {{Compute struct_do_diag} {Histogram struct_do_histo} done}
    set d [form_init .struct_diag "Diagnostics" "" $buts]
    if {$d != ""} {
	form_frame $d.fr sunken 2 {0 0}; set d $d.fr
	
	form_label $d.doml "Domains:" {0 0}
	form_frame $d.doms ridge 2 {1 0}
	
	form_label $d.whichl "Diagnostic:" {0 1}
	form_frame $d.which ridge 2 {1 1}
	
	form_label $d.minl "  Min value" {10 0}
	form_label $d.maxl "  Max value" {11 0}
	form_label $d.numl "  Num bars" {12 0}
	form_label $d.hgtl "  Max height" {13 0}
	form_entry $d.min struct_diag(min) string {10 1}
	form_entry $d.max struct_diag(max) string {11 1}
	form_entry $d.num struct_diag(num) string {12 1}
	form_entry $d.hgt struct_diag(hgt) string {13 1}
	
	form_finish -0-0
	
	trace variable struct_diag(which) w "ic_str_clear_diagnostics; list"
    }
    set doms [ic_str_list_entities domain]
    foreach d $doms {
	if ![info exists struct_diag($d)] { set struct_diag($d) 1 }
    }
    check_box .struct_diag.main.fr.doms $doms 6 struct_diag 1
    
    set diags ""
    foreach d [diagnostic_info] {
	lappend diags [list [lindex $d 0]]
    }
    check_box .struct_diag.main.fr.which $diags 6 struct_diag(which) 0
    
    form_wait .struct_diag
    
    ic_str_clear_diagnostics
    catch {unset struct_diag(is_done)}
}

proc struct_do_diag {} {
    global struct_diag
    
    ic_str_clear_diagnostics
    
    set doms ""
    foreach d [ic_str_list_entities domain] {
	if $struct_diag($d) {
	    lappend doms $d
	}
    }
    set struct_diag(domlist) $doms
    
    busy 1
    set st [ic_str_metric $struct_diag(which) $struct_diag(domlist)]
    busy 0
    
    set nok [lindex $st 0]
    set nundef [lindex $st 1]
    set nbad [lindex $st 2]
    set min [lindex $st 3]
    set max [lindex $st 4]
    set totval [lindex $st 5]
    
    ic_str_create_diagnostic_subset
    
    if $nok {
	mess "Min = $min, max = $max, mean = [expr $totval / ($nok + 0.0)]\n"
	mess "Num = $nok, undefined = $nundef, bad = $nbad\n"
    } else {
	mess "Warning: $struct_diag(which) is not defined for any elements\n" red
	set min ""; set max ""
    }
    set struct_diag(minv) $min
    set struct_diag(maxv) $max
    set struct_diag(is_done) 1
}

proc struct_do_histo {{title ""} {nbars ""} {min ""} {max ""}
		      {ylim 100} {arguments ""}} {
    global struct_diag
    
    if ![info exists struct_diag(is_done)] { struct_do_diag }
    
    if {$struct_diag(minv) == ""} {
	mess "Not plotting histogram\n" red
	return
    }
    if {$min == ""} { set min $struct_diag(minv) }
    if {$max == ""} { set max $struct_diag(maxv) }
    if {$title != ""} { set title $struct_diag(which) }
    if {$nbars == ""} { set nbars 50 }
    
    for {set i 0} {$i < $nbars} {incr i} {set histo($i) 0}
    
    set numt 0
    set hist [ic_str_histogram $min $max $nbars \
		  $struct_diag(domlist)]
    for {set i 0} {$i < $nbars} {incr i} {
	set n [lindex $hist [expr $i + 1]]
	incr histo($i) $n
	incr numt $n
    }
    
    # This is sort of wrong but it's what people want (Bugzilla #4770)
    incr histo(0) [lindex $hist 0]
    incr histo([expr $nbars - 1]) [lindex $hist [expr $nbars + 1]]
    
    set diff [expr {$max - $min}]
    set vstep [expr {$diff / ($nbars + 0.0)}]

    set xvalues {}
    set yvalues {}
    set total 0
    for {set i 0} {$i < $nbars} {incr i} {
	set x [expr {$min + $i * $vstep}]
	set y $histo($i)
	
	lappend xvalues $x
	lappend yvalues $y
	incr total $y
    }
    lappend xvalues $max
    
    if !$total {
	warningmsg "No values fell within the specified range ($min - $max)"
	return
    }
    
    make_histogram .histo $title $xvalues $yvalues $ylim \
	[list "Num = $total" "Min = $min" "Max = $max"] \
	struct_do_histo struct_plot_histo "" "" 1
}

proc struct_plot_histo {w intervals args solid} {
    global struct_diag
    
    if ![info exists struct_diag(is_done)] { struct_do_diag }
    
    if $solid {
	ic_str_configure_diagnostic_subset -shade flat_wire
    } else {
	ic_str_configure_diagnostic_subset -shade wire
    }
    set tot [ic_str_set_with_diagnostic $intervals $struct_diag(domlist)]
    mess "$tot elements\n"
}

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

proc struct_copymove {} {
    global struct_move needs_topo_recompute
    
    set buts {{Apply struct_do_copymove} done}
    set d [form_init .struct_copymove "Move/copy domains" edit $buts]
    if {$d != ""} {
	form_frame $d.fr sunken 2 {0 0}; set d $d.fr
	
	form_frame $d.whatf flat 0 {0 0 -cols -}
	form_label $d.whatf.l Operation {0 0}
	form_radiobutton $d.whatf.m Move struct_move(what) move {0 1}
	form_radiobutton $d.whatf.c Copy struct_move(what) copy {0 2}
	form_label $d.ncopiesl "Num copies:" {2 1}
	form_entry $d.ncopys struct_move(numcopies) int {2 2 -cols 2} \
		{{struct_move(what) copy}}
	form_label $d.domsl "Domains:" {3 1}
	form_entry $d.doms struct_move(domains) string {3 2 -cols 2}
	form_frame $d.allnonesel flat 0 {4 2 -cols 2}
	form_button $d.allnonesel.s Select struct_select_domains {0 0}
	form_button $d.allnonesel.a All "struct_copymove_all 1" {0 1}
	form_button $d.allnonesel.n None "struct_copymove_all 0" {0 2}
	
	form_colwidth $d 0 4 M
	
	form_checkbutton $d.translate Translate struct_move(do_translate) \
		{10 0 -cols 2}
	form_checkbutton $d.rotate "Rotate (degrees)" struct_move(do_rotate) \
		{20 0 -cols 2}
	form_checkbutton $d.scale Scale struct_move(do_scale) \
		{30 0 -cols 2}
	form_checkbutton $d.mirror Mirror struct_move(do_mirror) \
		{40 0 -cols 2}
	form_checkbutton $d.flipijk "Flip index" struct_move(do_flipijk) \
		{50 0 -cols 2}
	
	form_label $d.about "Transform about" {60 0 -cols 2}
	form_radiobutton $d.origin Origin struct_move(about) origin \
		{60 2 -cols 2}
	form_radiobutton $d.centr Centroid struct_move(about) centroid \
		{61 2 -cols 2}
	form_radiobutton $d.point Point struct_move(about) point \
		{62 2}
	
	form_entry $d.transamount struct_move(translate) coords \
		{10 2 -cols 2} struct_move(do_translate)
	
	form_entry $d.rotamount struct_move(rotate) string {20 2 -cols 2} \
		struct_move(do_rotate)
	form_frame $d.rotf flat 0 {21 2 -cols 2}
	form_radiobutton $d.rotf.x X struct_move(rotaxis) "1 0 0" {0 0} \
		struct_move(do_rotate)
	form_radiobutton $d.rotf.y Y struct_move(rotaxis) "0 1 0" {0 1} \
		struct_move(do_rotate)
	form_radiobutton $d.rotf.z Z struct_move(rotaxis) "0 0 1" {0 2} \
		struct_move(do_rotate)
	form_radiobutton $d.rotf.o Other struct_move(rotaxis) other \
	    {1 0 -cols 2} struct_move(do_rotate)
	form_entry $d.rotf.oe struct_move(rotaxis_other) float \
	    {1 2 -cols 2} \
	    {struct_move(do_rotate) {struct_move(rotaxis) other}}
	form_button $d.rotf.os "Select line" "med_get_line_2pts \
		struct_move(about_point) struct_move(rotaxis_other) \
		struct_move(about) point" {2 0 -cols 4} \
	    {struct_move(do_rotate) {struct_move(rotaxis) other}}
	
	form_entry $d.scaleamount struct_move(scale) coords_float \
		{30 2 -cols 2} struct_move(do_scale)
	
	form_label $d.mirrnml "Norm" {41 1}
	form_entry $d.mirnmt struct_move(mirrornorm) coords \
		{41 2 -cols 2} struct_move(do_mirror)
	
	form_frame $d.fl flat 0 {50 2 -cols 2}
	form_radiobutton $d.fl.i I struct_move(flipijk) 0 {0 0} \
		struct_move(do_flipijk)
	form_radiobutton $d.fl.j J struct_move(flipijk) 1 {0 1} \
		struct_move(do_flipijk)
	form_radiobutton $d.fl.k K struct_move(flipijk) 2 {0 2} \
		struct_move(do_flipijk)
	
	form_entry $d.centpoint struct_move(about_point) coords \
		{62 3} {{struct_move(about) point}}
	form_button $d.centp_set "Select" \
	    "disp_get_location struct_move(about_point)" \
	    {63 3} {{struct_move(about) point}}
	
	#form_label $d.syml "Symmetry families" {70 0 -cols 2}
	#form_entry $d.sym struct_move(symfams) string {70 2 -cols 2}
	
	form_finish bot
    }
    
    form_wait .struct_copymove
    
    if [info exists needs_topo_recompute] {
	struct_comptopo 0 $struct_move(symfams)
	unset needs_topo_recompute
    }
}

proc struct_copymove_all {all} {
    global struct_move
    
    if $all {
	set struct_move(domains) [ic_str_list_entities domain]
    } else {
	set struct_move(domains) ""
    }
}

proc struct_select_domains {} {
    global struct_move
    
    set struct_move(domains) [select_struct_surf domain 0]
}

proc struct_do_copymove {} {
    global struct_move needs_topo_recompute
    
    if {!$struct_move(do_translate) && \
	    !$struct_move(do_rotate) && \
	    !$struct_move(do_mirror) && \
	    !$struct_move(do_scale) && \
	    !$struct_move(do_flipijk)} {
	mess "No operations were selected.\n" red
	return
    }
    
    if {$struct_move(do_mirror) && !$struct_move(do_flipijk)} {
	set mess "You have selected a mirror and not an IJK flip - this may\
		result in left-handed domains.  Continue?"
	if [tk_dialog .copymove_check "Mirror without IJK flip" \
		$mess "" -1 Continue Cancel] return
    }
    
    with_view_inactive {
        set numdoms [llength $struct_move(domains)]
	
	# Don't do this unless we have to ...
	if {($struct_move(what) != "move") || \
		($numdoms != [ic_str_num_entities domain])} {
	    ic_str_assign_subface_families
	    set needs_topo_recompute 1
	}
	
	if {$struct_move(what) == "move"} {
	    mess "Moving $numdoms domains: "
	    foreach dnum $struct_move(domains) {
		struct_move_apply_params $dnum
		mess .
	    }
	    mess " done\n"
	} else {
	    set ndoms ""
	    set otr $struct_move(translate)
	    set orot $struct_move(rotate)
	    mess "Copying [expr $struct_move(numcopies) * $numdoms] domains: "
	    for {set i 0} {$i < $struct_move(numcopies)} {incr i} {
		foreach dnum $struct_move(domains) {
		    set n [ic_str_copy_domain $dnum]
		    lappend ndoms $n
		    struct_move_apply_params $n
		    mess .
		}
		
		if $struct_move(do_translate) {
		    set tt ""
		    set tr $struct_move(translate)
		    foreach j {0 1 2} {
			lappend tt [expr {[lindex $tr $j] + [lindex $otr $j]}]
		    }
		    set struct_move(translate) $tt
		}
		if $struct_move(do_rotate) {
		    set struct_move(rotate) \
			[expr {$struct_move(rotate) + $orot}]
		}
	    }
	    set struct_move(translate) $otr
	    set struct_move(rotate) $orot
	    mess " done\n"
	    
	    mess "Updating domain lists...\n"
	    ic_str_update_surfs
	    initialize_struct_visibility
	    mess "Done.\n"
	}
    }
}

proc struct_move_apply_params {num} {
    global struct_move
    
    switch $struct_move(about) {
	origin   { set cent "0 0 0" }
	centroid { set cent [ic_str_domain_centroid $num] }
	point    { set cent $struct_move(about_point) }
    }
    
    set cmd [list ic_str_move_domain $num cent $cent]
    if $struct_move(do_translate) {
	lappend cmd translate $struct_move(translate)
    }
    if $struct_move(do_rotate) {
	set axis $struct_move(rotaxis)
	if {$axis == "other"} { set axis $struct_move(rotaxis_other) }
	lappend cmd rotate_axis $axis rotate $struct_move(rotate)
    }
    if $struct_move(do_scale) {
	set ms $struct_move(scale)
	if {[llength $ms] == 1} { set ms "$ms $ms $ms" }
	lappend cmd scale $ms
    }
    if $struct_move(do_mirror) {
	lappend cmd mirror $struct_move(mirrornorm)
    }
    if $struct_move(do_flipijk) {
	set rev ""
	foreach i {0 1 2} { lappend rev [expr {$i == $struct_move(flipijk)}] }
	lappend cmd flip_ijk "0 1 2"
    }
    eval $cmd
}

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

proc struct_move_node_exact {} {
    global struct_move_node
    
    set struct_move_node(surfs) ""
    set struct_move_node(subfsel) "Subfaces selected: 0"
    set struct_move_node(nodesel) "Nodes selected: 0"
    
    #struct_move_node_exact_select 0
    
    set buts {{Apply struct_move_node_exact_doit} dismiss nl
	{"Select subface" "struct_move_node_exact_select 1"}
	{"Select nodes" "struct_move_node_exact_select 0"}}
    set d [form_init .struct_move_node "Move nodes" "" $buts]
    if {$d != ""} {
	form_label $d.subfsel "" {0 0 -cols 2}
	form_label $d.nodesel "" {1 0 -cols 2}
	$d.subfsel configure -textvariable struct_move_node(subfsel)
	$d.nodesel configure -textvariable struct_move_node(nodesel)
	form_radiobutton $d.setp "Set position" \
	    struct_move_node(set_pos) 1 {10 0 -cols 2}
	form_radiobutton $d.incr "Increment position" \
	    struct_move_node(set_pos) 0 {11 0 -cols 2}
	form_checkbutton $d.sx "X value" struct_move_node(dox) {12 0}
	form_checkbutton $d.sy "Y value" struct_move_node(doy) {13 0}
	form_checkbutton $d.sz "Z value" struct_move_node(doz) {14 0}
	form_entry $d.vx struct_move_node(xv) float {12 1} \
	    struct_move_node(dox)
	form_entry $d.vy struct_move_node(yv) float {13 1} \
	    struct_move_node(doy)
	form_entry $d.vz struct_move_node(zv) float {14 1} \
	    struct_move_node(doz)
	
	form_finish bot
    }
    form_wait .struct_move_node
    
    ic_str_clear_selection_subset
}
  
proc struct_move_node_exact_clear {} {
    ic_str_clear_selection_subset
    
    global struct_move_node
    
    foreach surf $struct_move_node(surfs) {
	if {[$surf get -surftype] == ""} {
	    $surf delete
	}
    }
    set struct_move_node(surfs) ""
}

proc struct_move_node_exact_select {subf} {
    global struct_move_node
    
    ic_str_clear_selection_subset
    
    set struct_move_node(is_subf) $subf
    set struct_move_node(subfsel) "Subfaces selected: 0"
    set struct_move_node(nodesel) "Nodes selected: 0"
    
    if $subf {
	set subs [select_struct_surf subface 0]
    } else {
	set subs [select_struct_node]
    }
    if {$subs == ""} return
    
    set totn 0
    foreach s $subs {
	if {$s == "selected"} {
	    incr totn [ic_str_selection_numnodes]
	    set bb [ic_str_selection_get_bbox]
	} else {
	    incr totn [ic_str_get_num_nodes subface $s]
	    set bb [ic_str_get_bbox subface $s]
	}
	foreach i {0 1 2} {
	    set min [lindex [lindex $bb 0] $i]
	    set max [lindex [lindex $bb 1] $i]
	    if {![info exists bmin($i)] || ($bmin($i) > $min)} {
		set bmin($i) $min
	    }
	    if {![info exists bmax($i)] || ($bmax($i) < $max)} {
		set bmax($i) $max
	    }
	}
    }
    if $subf {
	mess "Bounding box for [llength $subs] subfaces:\
	($bmin(0) $bmin(1) $bmin(2)) -> ($bmax(0) $bmax(1) $bmax(2))\n"
    }
    if $struct_move_node(set_pos) {
	foreach i {0 1 2} {
	    set x [lindex {x y z} $i]
	    if {$bmin($i) == $bmax($i)} {
		set struct_move_node(do$x) 1
	    } else {
		set struct_move_node(do$x) 0
	    }
	    set struct_move_node(${x}v) \
		[expr ($bmin($i) + $bmax($i)) / 2.0]
	}
    }
    
    set struct_move_node(surfs) $subs
    if $subf {
	set struct_move_node(subfsel) "Subfaces selected: [llength $subs]"
    } else {
	set struct_move_node(subfsel) "Subfaces selected: 0"
    }
    set struct_move_node(nodesel) "Nodes selected: $totn"
}

proc struct_move_node_exact_doit {} {
    global struct_move_node

    foreach s $struct_move_node(surfs) {
	set amt [ic_str_move_nodes_exact subface $s $struct_move_node(set_pos) \
	$struct_move_node(dox) $struct_move_node(doy) $struct_move_node(doz) \
	$struct_move_node(xv) $struct_move_node(yv) $struct_move_node(zv)]
	if [info exists val] {
	    if {[lindex $amt 0] < $val(min)} { set val(min) [lindex $amt 0] }
	    if {[lindex $amt 1] > $val(max)} { set val(max) [lindex $amt 1] }
	    set val(tot) [expr $val(tot) + [lindex $amt 2]]
	    incr val(num) [lindex $amt 3]
	} else {
	    set val(min) [lindex $amt 0]
	    set val(max) [lindex $amt 1]
	    set val(tot) [lindex $amt 2]
	    set val(num) [lindex $amt 3]
	}
    }
    if $val(num) {
	mess "$val(num) nodes moved, min $val(min), max $val(max),\
		mean [expr {$val(tot) / ($val(num) + 0.0)}]\n"
    } else {
	mess "0 nodes moved\n"
    }
}

proc struct_move_node_screen {} {
    global options struct_move_node
    
    while 1 {
	ic_newop
	if $options(edit_wait) {
	    set sel_surf [select_struct_node 0 "" 0]
	    set xypos ""
	} else {
	    set ss [select_struct_node 0 "" 0 "" 1 1]
	    set sel_surf [lindex $ss 0]
	    set xypos [lindex $ss 1]
	}
	if {$sel_surf == ""} return
	
	select_move_str_surf 1 $xypos $struct_move_node(on_geom)
	ic_str_clear_selection_subset
    }
}

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

proc struct_check_orient {} {
    set doms [ic_str_list_entities domain]
    
    set ok 0; set flat 0
    foreach d $doms {
	switch -- [ic_str_domain_orient $d] {
	    -1 { mess "Warning: domain $d is left-handed\n" red }
	    0  { incr flat }
	    1  { incr ok }
	}
    }
    if $flat { mess "$flat domains were flat\n" }
    mess "$ok domains were right-handed\n"
}

proc struct_reorient {} {
    global display_option
    
    set display_option(domain,ijk) 1
    disp_set_option domain
    
    set buts {{Apply struct_do_reorient} dismiss}
    set d [form_init .struct_orient "Reorient blocks" "" $buts]
    if {$d != ""} {
	form_radiobutton $d.sel "Reorient selected" \
	    struct_reorient(how) sel {0 0 -cols -}
	form_frame $d.f ridge 2 {2 1 -cols -}
	form_colwidth $d 0 2 M
	set act {{struct_reorient(how) sel}}
	form_label $d.f.ll "The labels on the left represent the\ncurrent axis labels.  The checkbuttons\nrepresent what they will be after the operation." {0 0 -cols -}
	$d.f.ll configure -justify left
	form_label $d.f.new0l "I -> " {1 0} $act
	form_label $d.f.new1l "J -> " {2 0} $act
	form_label $d.f.new2l "K -> " {3 0} $act
	form_radiobutton $d.f.new00 I struct_reorient(new0) 0 {1 1} $act
	form_radiobutton $d.f.new01 J struct_reorient(new0) 1 {1 2} $act
	form_radiobutton $d.f.new02 K struct_reorient(new0) 2 {1 3} $act
	form_radiobutton $d.f.new10 I struct_reorient(new1) 0 {2 1} $act
	form_radiobutton $d.f.new11 J struct_reorient(new1) 1 {2 2} $act
	form_radiobutton $d.f.new12 K struct_reorient(new1) 2 {2 3} $act
	form_radiobutton $d.f.new20 I struct_reorient(new2) 0 {3 1} $act
	form_radiobutton $d.f.new21 J struct_reorient(new2) 1 {3 2} $act
	form_radiobutton $d.f.new22 K struct_reorient(new2) 2 {3 3} $act
	form_checkbutton $d.f.flip0 Flip struct_reorient(flip0) {1 4} $act
	form_checkbutton $d.f.flip1 Flip struct_reorient(flip1) {2 4} $act
	form_checkbutton $d.f.flip2 Flip struct_reorient(flip2) {3 4} $act
	form_radiobutton $d.all "Reorient all" \
	    struct_reorient(how) all {10 0 -cols -}
	
	form_finish bot
    }
}

proc struct_do_reorient {} {
    global struct_reorient
    
    switch $struct_reorient(how) {
	all {
	    set mess "the reference domain"
	    set dom [lindex [select_struct_surf domain 0 item default $mess] 0]
	    if {$dom == ""} return
	    busy 1
	    set err [catch {ic_str_align_all_ijks $dom $struct_reorient(stop_num)} nn]
	    ic_str_update_surfs
	    busy 0
	    if $err {
		error $nn
	    } else {
		set nmod [lindex $nn 0]
		if {$nmod < 0} {
		    set nmod "Only [expr -$nmod]"
		}
		mess "$nmod domain orientations out of [lindex $nn 1] modified\n"
	    }
	}
	sel {
	    foreach i {0 1 2} { set ok($struct_reorient(new$i)) 1 }
	    foreach i {0 1 2} {
		if ![info exists ok($i)] {
		    error "You must specify a correct permutation of IJK"
		}
	    }
	    
	    set struct_reorient(domains) [select_struct_surf domain 0 item default]
	    busy 1
	    foreach dom $struct_reorient(domains) {
		ic_str_move_domain $dom \
		    flip_ijk [list $struct_reorient(flip0) \
				  $struct_reorient(flip1) \
				  $struct_reorient(flip2)] \
		    permute_ijk [list $struct_reorient(new0) \
				     $struct_reorient(new1) \
				     $struct_reorient(new2)]
	    }
	    ic_str_update_surfs
	    busy 0
	}
    }
}

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

proc struct_renumber {} {
}

proc struct_split {} {
}

proc struct_merge {} {
    set sub1 [select_struct_surf subface 1]
    if {$sub1 == ""} return
    set sub2 [select_struct_surf subface 1]
    if {$sub2 == ""} return
    
    if ![ic_str_merge_subfaces $sub1 $sub2] {
	mess "Could not merge subfaces\n" red
    } else {
	mess "Merged subfaces $sub1 and $sub2\n"
	update_struct_visibility
    }
}

proc struct_movenode {} {
}

proc struct_interp {} {
}

proc struct_nspack {} {
}

proc struct_refine {} {
}

proc struct_dump {} {
    set file [file_select "Select a file to dump the topo info to." [pwd] \
		  "File select" 0 1]
    if {$file == ""} return
    ic_str_dump_topo_info $file
}

proc struct_split_subface {} {
    set surfs [select_struct_surf subface 0 item default "subfaces to split"]
    if {$surfs == "*cancel*"} return
    busy 1
    foreach surf $surfs {
	set new [ic_str_split_subface $surf]
	if {$new != ""} {
	    mess "Split subface $surf -> $new\n"
	}
    }
    update_struct_visibility
    busy 0
}

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

proc struct_setfam {what} {
    global change_family fam_visible
    
    set nums [select_struct_surf $what 0 item default "entities to change"]
    
    if 0 {
	set nums [get_struct_list $what \
		      "Select the ${what}s to change; middle = done,\
			right = back up / cancel."]
    }
    if {$nums == ""} return
    set change_family(${what}_list) $nums
    
    set fam [select_family "Select the family for the ${what}s."]
    if {$fam == ""} return
    
    ic_str_change_family $what $nums $fam
    
    disp_set_option $what
}

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

proc struct_comptopo {{do_assign 1} {symfams ""}} {
    global struct_comptopo_cache
    
    busy 1
    mess "Recomputing topology ...\n"
    catch {unset struct_comptopo_cache}
    ic_str_recompute_topo $do_assign $symfams
    disp_new_stuff
    mess "Done recomputing topology.\n"
    busy 0
}

proc struct_comptopo_callback {fam is_2_to_1 dom1 ijk11 ijk12 dom2 ijk21 ijk22} {
    global struct_comptopo_cache
    
    if [info exists struct_comptopo_cache($fam,$is_2_to_1)] {
	return $struct_comptopo_cache($fam,$is_2_to_1)
    }
    if $is_2_to_1 { set n1 2; set n2 1 } else { set n1 1; set n2 2 }
    
    set mess "The family \"$fam\" was $n1-sided before but some faces are\
	now $n2-sided.  Take them out of the family or keep them?"
    
    append mess "\n\nFirst changed face encountered:\n\tFirst domain: [expr $dom1 + 1], range: ($ijk11 -> $ijk12)"
    if {$dom2 >= 0} {
	append mess "\n\tSecond domain: [expr $dom2 + 1], range: ($ijk21 -> $ijk22)"
    }
    set n [tk_dialog .comptopo "Recompute topology" \
	       $mess "" -1 Remove Keep]
    set struct_comptopo_cache($fam,$is_2_to_1) $n
    return $n
}

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

proc struct_periodic {} {
}

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

proc struct_extrude {} {
    global struct_extrude
    
    
}

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

proc struct_to_unstruct {} {
    ic_struct_to_unstruct "" 3 1
}

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

proc struct_close_all_open_windows {} {
    global batch_mode
    if $batch_mode { return }
    if [winfo exists .histo] { form_kill .histo }
    if [winfo exists .struct_diag] { form_kill .struct_diag }
    if [winfo exists .struct_orient] { form_kill .struct_orient }
    if [winfo exists .struct_copymove] { form_kill .struct_copymove }
    if [winfo exists .struct_move_node] { form_kill .struct_move_node }
}
