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

proc proj_vert {} {
    global move_ogrid_nodes
    if ![check_enabled] return
    
    set cmd "project_to_surface [range_string] [family_activename_string]"
    if { $move_ogrid_nodes } {
	append cmd " move_ogrid_nodes"
    }
    command $cmd
    file_dirty
    update_display edge face block mesh
}

proc proj_nvert { to_what } {
    global button_instructions

    if ![check_enabled] return
    
    switch $to_what {
	surface { set verb "project" }
	none { set verb "unproject" }
	default { set verb $to_what }
    }
    set mess "Please select the nodes to $verb $button_instructions"
    while 1 {
	set node [select_node $mess 100 node_numbers]
	if {$node == ""} break
	foreach n $node {
	    if { $to_what == "none" } {
	    	command "set_node_projection $n to_none"
	    } else {
		command "set_node_projection $n"
	    }
	}
	file_dirty
	update_display edge face block mesh
    }
}


proc proj_vcurve {} {
    global button_instructions

    if ![check_enabled] return
    
    set mess1 "Please select the curve to project to $button_instructions"
    set mess2 "Please select the nodes to project $button_instructions"
    while 1 {
	set curves [select_curve $mess1 ]
        if {[scan $curves "%s" curve_no] != 1} return

	set node [select_node $mess2 100 node_numbers]
	if {$node == ""} break


	foreach n $node {
	    command "set_node_projection $n $curve_no"
	}

	file_dirty
	update_display edge face block mesh
    }
}

proc proj_edge_select { } {
    global display_flag last_line project_flag
    global button_instructions

    while 1 {
        set mess "Please select the edges to project $button_instructions"
        set edges [select_edge $mess 1 "new_format edge_segment"]
	if { $edges == "" } break;
	command "project_to_surface [ lindex $edges 0 ] [ lindex $edges 1 ] "
        file_dirty
        command unhighlight_curves
        update_display edge face block mesh
    }
}
proc proj_edge {} {
    global display_flag last_line project_flag
    
    if ![check_enabled] return
    
    if !$display_flag(curve) {
	set display_flag(curve) 1; update_display curve
    }
    set buts [list "Project proj_edge_to_curve" done]
    set d [form_init .proj_edge "Edge projection" "" $buts]
    if {$d != ""} {
	#form_button $d.pec "Project edge to curve" proj_edge_to_curve {0 0}
	#form_button $d.pes "Project edge to surface" proj_edge_to_surface {1 0}
	#form_button $d.pen "Do not project edge" proj_edge_to_none {2 0}
	form_checkbutton $d.inters "Project associated edges to\nthe two\
		adjacent surfaces" project_flag(intersection) {3 0}
	form_checkbutton $d.cinters "Project end to intersection\nof two\
		curves" project_flag(curve_intersection) {4 0}
	$d.inters configure -anchor c
	$d.cinters configure -anchor c
	form_finish bot
    }
}

proc proj_edge_to_curve {} {
    global display_flag last_line project_flag
    global button_instructions
    
    while 1 {
	set curves [select_curve "Please select the curve \
		$button_instructions" ]
	
	if {[scan $curves "%s" curve_no] != 1} return
	
	set mess "Please select the edges to associate with the curve \
		$button_instructions" 
	set edges [select_edge $mess 1000 "new_format edge_segment"]
	foreach e $edges {
	    set cmd "set_edge_projection $e 1 $curve_no"
	    foreach i {intersection curve_intersection} {
		if $project_flag($i) { append cmd " $i" }
	    }
	    command $cmd
	    file_dirty
	}
	command unhighlight_curves
	update_display edge face block mesh
    }
}

proc proj_edge_to_surface {} {
    global display_flag last_line project_flag
    global button_instructions
    
    set mess "Please select the edges to project to surface \
		$button_instructions"
    set edges [select_edge $mess 1000 "new_format edge_segment"]
    foreach e $edges {
	command "set_edge_projection $e 2 0"
	file_dirty
    }
    update_display edge face block mesh
}

proc proj_update_blocking {} {
	command "update_node_locations"
	update_display edge face block mesh
}
proc proj_edge_to_none {} {
    global display_flag last_line project_flag
    global button_instructions
    
    set mess "Please select the edges to unproject  $button_instructions"
    set edges [select_edge $mess 1000 "new_format edge_segment"]
    foreach e $edges {
	command "set_edge_projection $e 3 0"
	file_dirty
    }
    update_display edge face block mesh
}

proc proj_nedge {} {
    global button_instructions

    if ![check_enabled] return
    
    set mess "Please select the edges to disassociate $button_instructions"
    set edges [select_edge $mess 1000 "new_format edge_segment"]
    foreach e $edges {
	command "set_edge_projection $e 2 0"
	file_dirty
    }
    update_display edge face block mesh
}

proc proj_face { how } {
    global families family_dims family_name proj_face_family topform_geo
    
    if ![check_enabled] return
    
    if ![info exists proj_face_family] { set proj_face_family none }
    
    set surfs ""
    lappend surfs [list any -text "project to closet"]
    lappend surfs [list do_not_project -text "interpolate edges"]
    set appfam [surface_name_string]
    foreach f $appfam {
	lappend surfs $f
    }
    form_kill .project_face
    
    if { $how == "corners" } {
	   set buts {
		{Project {proj_one_face  corners  }}
		{Done    {form_done .project_face}}
	   }
    } elseif { $how == "select" } {
	   set buts {
		{Project {proj_one_face  select  }}
		{Done    {form_done .project_face}}
	   }
    }
    
    set d [form_init .project_face "Project faces" proj $buts]
    form_frame $d.fr sunken 3 {0 0}; set d $d.fr
    form_frame $d.surf flat 0 {0 0}
    #form_checkbutton $d.int "Do not project" proj_interpolate_edge {1 0}
    
    check_box .project_face.main.fr.surf $surfs 6 proj_face_family 0
    
    form_finish $topform_geo
}

proc proj_one_face { how } {
    global proj_face_family  last_line
    global button_instructions

    #global proj_interpolate_edge
    
    if ![check_enabled] return
    
    focus .v
    set fam $proj_face_family
    if {$fam == "project to closet"} { set fam "" }
    if { $how == "corners" } {
	while 1 {
	    set mess "Please select the two vertices of the face to associate\
		$button_instructions"
	    set verts [select_node $mess 3]
	    if {[llength $verts] < 2} return
	
	    command "project_face \{ [lindex $verts 0] \} \{ [lindex $verts 1] \} $fam"
	    update_display edge face block mesh
	}
    } elseif { $how == "select" } {
	    set mess "Please select the icon for the face to associated \
			 $button_instructions"
	    set cmd "select_super_face node_numbers \
			[range_string] [family_activename_string]"
	    command "$cmd"
	    set faces $last_line
	    if { $faces != "" } {
		command "project_face node_numbers $faces $fam"
	    }

	    update_display edge face block mesh
    } else {
	puts "$how"
    }
		
}

proc proj_nface { how } {
    global button_instructions last_line

    if ![check_enabled] return
    
    if { $how == "corners" } {
	while 1 {
	    set mess "Please select the two vertices of the \
			face to disassociate $button_instructions"
	    set verts [select_node $mess 3]
	    if {[llength $verts] < 2} return
	    command "unproject_face \{ [lindex $verts 0] \} \
			\{ [lindex $verts 1] \}"
	    update_display edge face block mesh
	}
    } elseif { $how == "select" } {
	    set mess "Please select the icon for the face to disassociated \
			 $button_instructions"
	    set cmd "select_super_face node_numbers \
			[range_string] [family_activename_string]"
	    command "$cmd"
	    set faces $last_line
	    if { $faces != "" } {
		command "unproject_face node_numbers $faces"
	    }

	    update_display edge face block mesh
    }
}
proc link_face { how } {
    global button_instructions last_line

    if ![check_enabled] return
    
    if { $how == "corners" } {
	while 1 {
	    set mess "Please select the two vertices of the \
			face to link $button_instructions"
	    set verts [select_node $mess 3]
	    if {[llength $verts] < 2} return
	    command "project_face \{ [lindex $verts 0] \} \
			\{ [lindex $verts 1] \} -link"
	    update_display edge face block mesh
	}
    } elseif { $how == "select" } {
	    set mess "Please select the icon for the face to link \
			 $button_instructions"
	    set cmd "select_super_face -volume_faces node_numbers \
			[range_string] [family_activename_string]"
	    command "$cmd"
	    set faces $last_line
	    if { $faces != "" } {
		command "project_face node_numbers $faces -link"
	    }

	    update_display edge face block mesh
    }
}

proc proj_shared_wall {} {
    global all_lines topform_geo form_done_flag shwall_volume_list
    global shwall_surface_list shwall_surface_var botform_geo
    global families family_name family_dims shwall_volume_var
    
    if ![check_enabled] return
    
    command "list_shared_walls" 0
    if {$all_lines == ""} {
	mess "There are no shared walls currently defined.\n"
    } else {
	mess "Currently defined shared walls:\n"
	mess "\tVol 1\tVol 2\tSurface\n"
	set n 1
	foreach l $all_lines {
	    mess "$n.\t[lindex $l 0]\t[lindex $l 1]\t[lindex $l 2]\n"
	    incr n
	}
    }
    
    block_unmark
    command "del marked -solid" 0
    
    set buts {
	{Create {shwall_action create}}
	{Delete {shwall_action delete}}
	{Done {form_done .shwall; command "del erase"}}
    }
    
    set d [form_init .shwall "Shared walls" proj $buts]
    if {$d != ""} {
	form_frame $d.fr sunken 3 {0 0}; set d $d.fr
	
	form_label $d.voll "Volumes:" {1 1}
	form_frame $d.vol flat 0 {2 1 -fill none}
	
	form_label $d.surfl "Surfaces:" {1 2}
	form_frame $d.surf flat 0 {2 2 -fill none}
    }
    
    set vols ""; set surfs ""
    foreach f $families {
	if {$family_dims($f) == 3} {
	    lappend vols [list $f -text $family_name($f) \
		    -command "block_mark_families shwall_volume_var"]
	} else {
	    lappend surfs [list $f -text $family_name($f) \
		    -command "surface_mark_families shwall_surface_var 1"]
	}
    }
    if {![info exists shwall_volume_list] || \
	    ($shwall_volume_list != $vols) || \
	    ![info exists shwall_surface_list] || \
	    ($shwall_surface_list != $surfs)} {
	foreach w [winfo children .shwall.main.fr.vol] { destroy $w }
	foreach w [winfo children .shwall.main.fr.surf] { destroy $w }
	set shwall_volume_list $vols
	set shwall_surface_list $surfs
	check_box .shwall.main.fr.vol $vols 6 shwall_volume_var 1 \
		"block_mark_families shwall_volume_var"
	check_box .shwall.main.fr.surf $surfs 6 shwall_surface_var 0
	
	# This is kind of wierd.
	if {$d != ""} {
	    form_finish $botform_geo
	} else {
	    wm withdraw .shwall
	    update
	    wm geometry .shwall $botform_geo
	    sun_geometry .shwall $botform_geo
	    wm deiconify .shwall
	}
    }
    block_mark_families shwall_volume_var
    surface_mark_families shwall_surface_var 1
}

proc shwall_action {what} {
    global shwall_volume_var shwall_surface_var family_name
    
    set vols ""
    foreach v [array names shwall_volume_var] {
	if $shwall_volume_var($v) { lappend vols $family_name($v) }
    }
    if {[llength $vols] != 2} {
	mess "Error: exactly two volume families must be selected\n" red
	return
    }
    if { $shwall_surface_var == "" } {
	tk_dialog .err "Error" "You must select a surface family" "" 0 Ok
	return
    }

    set surf $family_name($shwall_surface_var)
    switch $what {
	create { command "define_shared_wall $vols $surf" }
	delete { command "remove_shared_wall $vols" }
    }
    file_dirty
    update_display edge face block mesh
}

proc proj_active_surfs {} {
    global all_lines topform_geo form_done_flag
    global active_surface_list active_surface_var botform_geo
    global families family_name family_dims
    
    if ![check_enabled] return
    
    catch {unset active_surface_var}
    command "list_family_projection" 0
    foreach l $all_lines {
	set active_surface_var([lindex $l 0]) [lindex $l 1]
    }
    set surfs ""
    set form_families ""

# sort the families
    if [ info exists family_number ] {
	unset family_number
    }
    foreach f $families {
	set fname $family_name($f)
	lappend fams $fname
	set family_number($fname) $f
    }
    set fams [ lsort $fams ]

    mess "sorted families\n"
    foreach f $fams {
	mess "$f\n"
    }

	
    foreach n $fams {
	set f $family_number($n)
	if {$f && ($family_dims($f) != 3)} {
	    lappend surfs [list $n -text $n ]
	    lappend form_families $n
	}
    }
    
    
    if [ check_box_form .act_surfs "Active surfaces families" $surfs 8 \
	active_surface_var ] {
	command "undo_major_start active_families -no_save"
	foreach f $form_families {
    		command "set_family_projection $f $active_surface_var($f)"
	}
	command "undo_major_end active_families"
    }
}


proc proj_query {} {
    global display_flag last_line
    
    set pb $display_flag(edge); set pbp $display_flag(edge_proj)
    set display_flag(edge) 1
    set display_flag(edge_proj) 1
    update_display edge mesh
    
    while { 1 } {
    	banner "Pick the end of one of the projection arrows."
    	command graphics_loc
    	set pt $last_line
    
    	if {$pt == ""} {
		banner ""
		break;
    	}
    
    	banner "Select a surface."
    	if ![command "select_surface $pt"] {
		set last_line ""
    	}
    
    	banner ""
    	if {$last_line == ""} {
		mess "No surface was selected.\n"
    	} else {
		mess "Surface is $last_line\n"
		command "display_surfaces simple color white $last_line" 0
    	}
    }
    set display_flag(edge) $pb
    set display_flag(edge_proj) $pbp
    update_display edge mesh
}

proc proj_limit {} {
    set lim [question_box .proj_limit "Projection limit" \
		 " Enter the distance to use\
		   for the projection limit." ""]
    if {$lim == ""} return
    command "projection_limit $lim"
}

proc proj_update {how what} {    
    set top [top_get_current]
    command "${how}_association $top $what"
    update_display edge face block mesh
}
proc proj_vpoint {} {
    global display_flag
    global button_instructions

    if ![check_enabled] return

    while 1 {
        set node [select_node "Please select the vertex to modify \
                $button_instructions" 1 "edge_nodes node_numbers" ]
        if {$node == ""} break

        set point [select_point "Please select the prescribed point \
                $button_instructions"]
# no point means closest
#        if {$point == ""} break

        set cmd "move_node $node $point"
        command $cmd 1 1
        update_display edge face block mesh
    }

    file_dirty

    return
}

