# Stuff for coordinate systems
#
# Copyright (c) 2000 Pacific Marketing and Consulting, Inc.
#       All rights reserved.
# Author:  Michael E. Hohmeyer, hohmeyer@icemcfd.com

proc coordinate_systems { } {
    coordinate_system_form .coordinate_system
}

proc add_point_select { w suf txtvar var ln base_var def_val active_var } {
    global $active_var
    
    form_label_variable $w.${suf}l $txtvar "$ln 0" \
	$active_var
    
    set m $w.${suf}sel.m
    
    global $var
    set $var $def_val
    
    
    form_entry $w.$suf $var coords "$ln 1 -cols 2" \
	$active_var
    form_menubutton_regular $w.${suf}sel "Select" $m "$ln 5" \
	$active_var
    
    menu $m
    $m add command -label "Graphic location" -command \
	"csystem_select_point graphic $var \"$base_var\""
    $m add command -label "Prescribed point" -command \
	"csystem_select_point pre_point $var \"$base_var\""
}

proc csystem_done {} {
    form_done .coordinate_system
    # JKA: bug 4011: do not delete active csys disp when closing panel
    #csystem_update_display all 0
}

proc csystem_delete {} {
    global csystem_name
    if { $csystem_name == "" } {
	user_error "You must enter a name for the new coordinate system\n"
	return
    }
    delete_coordinate_system $csystem_name
}

proc csystem_create {} {
    global csystem_name axis_active
    if { $csystem_name == "" } {
	user_error "You must enter a name for the new coordinate system\n"
	return
    }
    if { $csystem_name == "global" } {
	user_error "You cannot re-define the global coordinate system\n"
	return
    }
    set nset 0
    global csystem_axis
    foreach i { 0 1 2 } {
	set val $csystem_axis($i)
	if { $val != "" } {
	    incr nset
	}
    }
    if { $nset < 2 } {
	user_error "You must set at least 2 of the axes"
	return
	
    }
    global csystem_center
    if { $csystem_center == "" } {
	user_error "You must enter a center value"
	return
    }
    global csystem_type
    foreach i { 0 1 2 } {
	if { $axis_active($i) } {
	    set axis($i) $csystem_axis($i)
	} else {
# this code was moved to med's create_coordinate_system
#	    set axis($i) [vec_cross $csystem_axis([expr ($i + 1) % 3]) \
#			      $csystem_axis([expr ($i + 2) % 3])]
#	    set csystem_axis($i) $axis($i)
# this is the old code
	    set axis($i) ""
	}
    }
    
    create_coordinate_system $csystem_type $csystem_name  \
	$csystem_center \
	$axis(0) $axis(1) $axis(2)
    csystem_update_display $csystem_name 1
    csystem_set_variables $csystem_name
}

proc get_csys_names { } {
    set names "global "
    append names [ list_coordinate_systems ]
    return $names
}

proc csystem_set {} {
    global csystem_name csystem_center csystem_axis
    global csystem_type csystem_current_name
    set csystem_current_name $csystem_name
    set_coordinate_system $csystem_name
    csystem_set_variables $csystem_name
    axes_update 0 0
}

proc csystem_set_variables {cs} {
    global csystem_name csystem_center csystem_axis
    global csystem_type csystem_current_name
    
    set csystem_name $cs
    if { $csystem_name == "global" } {
	set vals ""
    } else {
	set vals [ get_coordinate_system $csystem_name ]
	if { $vals == "" } {
	    set csystem_name "global"
	}
    }
    if { $csystem_name == "global" } {
	set csystem_type cartesian
	set csystem_center "0 0 0"
	set csystem_axis(0) "1 0 0"
	set csystem_axis(1) "0 1 0"
	set csystem_axis(2) "0 0 1"
    } else {
	
	#	    mess "$vals\n"
	set il 1
	set len [ llength $vals ]
	while { $il < $len } {
	    switch [ lindex $vals $il ] {
		origin {
		    incr il
		    set csystem_center [ lrange $vals $il [ expr $il + 2 ] ]
		    incr il 3
		}
		xaxis {
		    incr il
		    set csystem_axis(0) [ lrange $vals $il [ expr $il + 2 ] ]
		    incr il 3
		}
		yaxis {
		    incr il
		    set csystem_axis(1) [ lrange $vals $il [ expr $il + 2 ] ]
		    incr il 3
		}
		zaxis {
		    incr il
		    set csystem_axis(2) [ lrange $vals $il [ expr $il + 2 ] ]
		    incr il 3
		}
		name {
		    incr il
		    if { [ lindex $vals $il ] != $csystem_name } {
			error "name doesn't match"
		    }
		    incr il
		}
		type {
		    incr il
		    set csystem_type [ lindex $vals $il ]
		    incr il
		}
		default {
		    error "I don't understand [ lindex $vals $il ]"
		}
	    }
	}
    }
    update_csystem_type
}

proc update_csystem_type { } {
    global csystem_type center_name axis_name
    global axis_active
    global csystem_axis
    set center_name "Origin"
    if { $csystem_type == "cartesian" } {
	set axis_name(0) "X Axis"
	set axis_name(1) "Y Axis"
	set axis_name(2) "Z Axis"
	set axis_active(0) 1
	set axis_active(1) 1
	set axis_active(2) 0
    } elseif { $csystem_type == "cylindrical" || \
		   $csystem_type == "spherical" ||
	       $csystem_type == "toroidal" } {
	set axis_name(0) "T=0"
	set axis_name(1) "T=90"
	if { $csystem_type == "spherical" } {
	    set axis_name(2) "P=0"
	} else {
	    set axis_name(2) "Z Axis"
	}
	set axis_active(0) 1
	set axis_active(1) 0
	set axis_active(2) 1
    } else {
	error "unexpected coordinate system type $csystem_type"
    }
}

proc coordinate_system_form { w } {
    global csystem_type csystem_name center_name axis_name csystem_axis
    global csystem_radius center_active axis_active
    global csystem_conv_global csystem_conv_local
    global csystem_current_name
    
    if {[info command ic_csystem_get_current] != ""} {
	set csystem_current_name [ic_csystem_get_current]
    } elseif ![info exists csystem_current_name] {
	set csystem_current_name global
    }
    set buts { create done }
    set d [ form_init $w "Coordinate Systems" "hmm" \
		[ list { Define csystem_create } \
		      { Delete csystem_delete } \
		      { "Change to" csystem_set } \
		      { Done csystem_done } ] ]
    if { $d != "" } {
	form_frame $d.fr sunken 2 {0 0}; set d $d.fr
	
	set ln 0
	form_label $d.namel "Name:" "$ln 0"
	futil_listentry $d.names csystem_name \
	    "get_csys_names" "$ln 1" "" csystem_update_form
	
	#set csystem_name global by JKA for
	set csystem_name [expr {($csystem_current_name != "") \
		? $csystem_current_name : "global"}]
	
	incr ln
	form_label $d.type "Type:" "$ln 0"
	
	set csystem_type cartesian
	form_radiobutton $d.cartesian Cartesian \
	    csystem_type cartesian "$ln 1 -cols -" "" \
	    update_csystem_type
	
	incr ln
	
	form_radiobutton $d.cylindrical Cylindrical \
	    csystem_type cylindrical "$ln 1 -cols -" "" \
	    update_csystem_type
	incr ln
	
	form_radiobutton $d.spherical Spherical \
	    csystem_type spherical "$ln 1 -cols -" "" \
	    update_csystem_type
	incr ln
	
#		form_radiobutton $d.toroidal Toroidal \
#			csystem_type toroidal "$ln 1 -cols -" "" \
#			update_csystem_type
#		incr ln
	
	set center_name ""
	set center_active 1
	add_point_select $d center center_name csystem_center $ln \
	    "" "0 0 0" center_active
	incr ln
	
	foreach i { 0 1 2 } {
	    set axis_name($i) ""
	    set axis_active($i) 1
	    set lname [lindex { x y z } $i]axis
	    add_point_select $d $lname axis_name($i) \
		csystem_axis($i) $ln \
		csystem_center "" axis_active($i)
	    incr ln
	}
	
	
#		form_label $d.rvall "Radius" "$ln 0" \
#			{ { csystem_type toroidal } }
#        	form_entry $d.rval csystem_radius float "$ln 1 -cols 2" \
#			{ { csystem_type toroidal } }
#		incr ln
	
	
	
	form_colwidth $d 0 25 M
	
	if {[info command ic_coords_into_local] != ""} {
	    set act {{csystem_current_name !global}}
	    form_frame $d.conv flat 0 "$ln 0 -cols -"
	    form_label $d.conv.gl Global {0 0} $act
	    form_entry $d.conv.g csystem_conv_global coords {0 1} $act
	    form_button $d.conv.gc ">>" "csystem_convert 1" {0 2} $act
	    form_button $d.conv.lc "<<" "csystem_convert 0" {0 3} $act
	    form_entry $d.conv.l csystem_conv_local coords {0 4} $act
	    form_label $d.conv.ll Local {0 5} $act
	    bind $d.conv.g <Return> "csystem_convert 1" 
	    bind $d.conv.l <Return> "csystem_convert 0" 
	}
	
	form_finish -0-0
    }
    
    if 0 {
	set csystem_name global
	set csystem_type "cartesian"
	
	set csystem_axis(0) "1 0 0"
	set csystem_axis(1) "0 1 0"
	set csystem_axis(2) "0 0 1"
	set csystem_conv_global "0 0 0"
	set csystem_conv_local "0 0 0"
    } else {
	# JKA: so that when returning to form, we get current data
	set csystem_name [expr {($csystem_current_name != "") \
		? $csystem_current_name : "global"}]
	csystem_set
    }
    update_csystem_type
    csystem_update_display $csystem_name 1
}

proc csystem_convert {g_to_l} {
    global csystem_conv_global csystem_conv_local
    if $g_to_l {
	set csystem_conv_local [ic_coords_into_local $csystem_conv_global]
    } else {
	set csystem_conv_global [ic_coords_into_global $csystem_conv_local]
    }
}

proc csystem_update_form {} {
    global csystem_type csystem_name csystem_center csystem_axis
    
    set data [get_coordinate_system $csystem_name]
    if {$data == ""} return
    
    # This is expected to return:
    # system name name type type center x y z axis0 x y z ...
    
    set csystem_type [lindex $data 4]
    set csystem_center [lrange $data 6 8]
    set csystem_axis(0) [lrange $data 10 12]
    set csystem_axis(1) [lrange $data 14 16]
    set csystem_axis(2) [lrange $data 18 20]
    update_csystem_type
    csystem_update_display $csystem_name 1
}

proc csystem_update_display {which on} {
    if {[info command ic_csystem_display] == ""} return
    if {$which == "global"} {
	# JKA: we still need to delete the current csys_disp, so:
	ic_csystem_display all 0
	return
    }
    ic_csystem_display $which $on
}
