# $Revision$ on $Date$
# The above revision line needs to be the first line for all techtk files
# Copyright (c) 2006 Ansys Inc
#----------------------------------------------------------------------------
#
# PADT---------------------------------------------------- Phoenix Analysis &
#                                                         Design Technologies
#
#----------------------------------------------------------------------------
#
#       Package: AI-Environment GUI Management
#
#
#          File: dez_environment.tcl
#
#
#     Developer: Matt Sutton
#
#
#   Description: The procedures in this file are responsible for creating and
#                maintaining the execution environment for the DEZs.  This 
#                includes setting up the namespaces that wrap each DEZ as well
#                as transparently executing client procedures within these
#                namespaces.  Furthermore, all variables referenced by the 
#                widgets within a DEZ are wrapped within the DEZ's namespace
#                and are managed by the procedures within this file.
#   
#
#      05/03/02: File Creation (MGS)
#
#           
#
#-----------------------------------------------------------------------------
# For support: 1-480-813-4884 ext. 125 -or- matt.sutton@padtinc.com
#-----------------------------------------------------------------------------

# NOTE: Make sure you maintain consistency between the DEZNamespacePrefix
# variable in both the ::AIEnv::GUIManagement and ::AIEnv::GUIManagement::DEZ
# namespaces
namespace eval ::AIEnv::GUIManagement {

}

namespace eval ::AIEnv::GUIManagement::DEZ {
	variable DEZData
	variable DEZCommands
	variable LoadProcCallPoints [list "BEFORE_ON_LOAD" "AFTER_ON_LOAD"]
	set DEZCommands [list "create" "build" "set" "get" "proc" "apply" "accept" "cancel" "load" "unload" "show" "hide" "enabletrace" "addtracebutton" "setdirty" "setclean" "gettree" "init" "addloadproc" "deleteloadproc" "isbuilt"]
}


proc ::AIEnv::GUIManagement::WriteDEZData {fp} {
    global dontSaveDEZ

    puts $fp "\n\#------------- DEZ Data ------------------\n"
    puts $fp  "namespace eval ::AIEnv::GUIManagement::DEZ {"
    foreach dez_tree $::AIEnv::GUIManagement::DEZ::DEZData(Trees) {
	set dez [string trimright $dez_tree _Tree]
	if [info exists dontSaveDEZ($dez)] {
	    #puts "Not saving data for $dez"
	    continue
	}
	if [$dez exist] {
	    puts $fp "    array set ${dez}_data {"
            foreach n [GetLocalVariables $dez] {
		if ![catch {$dez get $n} v] {
		    # Special case work-a-round ...
		    if [string match uns_sel_* $v] continue
		    puts $fp "        [list $n $v]"
		}
            }
            puts $fp "    }"
	}
    }
    puts $fp "}"
}


proc ::AIEnv::GUIManagement::InNamespaceResetGUI {ResourceFilePath} {
   variable ObjectList

   foreach name $ObjectList {
      ::AIEnv::GUIManagement::DEZ::_remove $name

      interp alias {} ::$name {}
      #namespace delete [GetNamespace DEZ $name]
   }

   set ObjectList ""
   set ::AIEnv::GUIManagement::DEZ::DEZData(Trees) ""

   ::AIEnv::GUIManagement::ExclusiveGroup::Clean ""

   ParseResourceFile $ResourceFilePath
   #BuildGUI
}

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

proc ::AIEnv::GUIManagement::DEZ::RouterProc {DEZ {Cmd "proc"} args} {
# This seems as a best place to cancel pick and clear temporary highlights
	global select_action
	set select_action cancel
	ic_highlight
#------------
	if { [string equal [info commands ::AIEnv::GUIManagement::DEZ::_$Cmd] ""] } {
		if { [string equal [info commands $Cmd] ""] } {
			variable DEZCommands
			set OptList [join $DEZCommands ", "]
			set OptList [linsert $OptList "end-1" "or"]
			error "Bad option \"$Cmd\": must be $OptList"
		} else {
			# Assume the user left off the proc, and just called
			# DEZName Function Arguments.  So, reorg things so that
			# they match the calling convention for the _proc command.
			# This means that the first item in args should be the function
			# name and Cmd should be "proc"
			set UserSuppliedFunctionName $Cmd
			set Cmd "proc"
			set args [linsert $args 0 $UserSuppliedFunctionName]
		}
	}
	return [eval [list ::AIEnv::GUIManagement::DEZ::_$Cmd $DEZ] $args]
}

proc ::AIEnv::GUIManagement::DEZ::_enabletrace {Name args} {
	set LocalVariables [::AIEnv::GUIManagement::GetLocalVariables $Name]
	set Namespace [::AIEnv::GUIManagement::GetNamespace DEZ $Name]
	
	foreach Var $LocalVariables {
		set FullyQualifiedVariable ${Namespace}::${Var}
		trace variable $FullyQualifiedVariable w "::AIEnv::GUIManagement::DEZ::TraceFunc $Name"
	}
}

proc ::AIEnv::GUIManagement::DEZ::TraceFunc {Name Name1 Name2 op} {
	SetDirty $Name
}

proc ::AIEnv::GUIManagement::DEZ::SetClean {Name} {
	variable DEZData
	set DEZData($Name-DirtyFlag) 0
	if { [array names DEZData $Name-buttons] != "" } {
		foreach Button $DEZData($Name-buttons) {
			$Button configure -state disabled
		}
	}
}

proc ::AIEnv::GUIManagement::DEZ::SetDirty {Name} {
	variable DEZData
	set DEZData($Name-DirtyFlag) 1
	if { [array names DEZData $Name-buttons] != "" } {
		foreach Button $DEZData($Name-buttons) {
			$Button configure -state active
		}
	}
}

proc ::AIEnv::GUIManagement::DEZ::SetCleanOthers {Name} {
	variable DEZData
	set DEZData($Name-DirtyFlag) 0
	if { [array names DEZData $Name-buttons] != "" } {
		foreach Button $DEZData($Name-buttons-others) {
			$Button configure -state disabled
		}
	}
}

proc ::AIEnv::GUIManagement::DEZ::SetDirtyOthers {Name} {
	variable DEZData
	set DEZData($Name-DirtyFlag) 1
	if { [array names DEZData $Name-buttons] != "" } {
		foreach Button $DEZData($Name-buttons-others) {
			$Button configure -state active
		}
	}
}

proc ::AIEnv::GUIManagement::DEZ::_init {Name args} {
	variable DEZData
	# Initially mark this dez as not being built
	set DEZData($Name-IsBuilt) 0
	# Create the tree that will store the widgets for this dez.
	set DEZData($Name-Tree) [struct::tree ${Name}_Tree]
	lappend DEZData(Trees) $DEZData($Name-Tree)
}

proc ::AIEnv::GUIManagement::DEZ::_isbuilt {Name} {
        variable DEZData
        # Initially mark this dez as not being built
        return $DEZData($Name-IsBuilt)
}

proc ::AIEnv::GUIManagement::DEZ::_gettree {Name args} {
	variable DEZData
	return $DEZData($Name-Tree)
}

proc ::AIEnv::GUIManagement::DEZ::_setclean {Name args} {
	SetClean $Name	
}

proc ::AIEnv::GUIManagement::DEZ::_setdirty {Name args} {
	SetDirty $Name	
}

proc ::AIEnv::GUIManagement::DEZ::_setclean_others {Name args} {
	SetCleanOthers $Name	
}

proc ::AIEnv::GUIManagement::DEZ::_setdirty_others {Name args} {
	SetDirtyOthers $Name	
}

proc ::AIEnv::GUIManagement::DEZ::_addtracebutton {Name args} {
	variable DEZData
	if { [llength $args] == 1} {
		lappend DEZData($Name-buttons) $args
	}
}

proc ::AIEnv::GUIManagement::DEZ::_addtracebutton_others {Name args} {
	variable DEZData
	if { [llength $args] == 1} {
		lappend DEZData($Name-buttons-others) $args
	}
}

proc ::AIEnv::GUIManagement::DEZ::_addloadproc {Name args} {
	variable DEZData
	variable LoadProcCallPoints
	if { [llength $args] == 2} {
		set ProcName [lindex $args 0]
		set CallPoint [string toupper [lindex $args 1]]
		if {[lsearch $LoadProcCallPoints $CallPoint] != -1} {
			if {[info exists DEZData($Name,loadprocs,$CallPoint)]} {
				if {[lsearch $DEZData($Name,loadprocs,$CallPoint) $ProcName] == -1 } {
					lappend DEZData($Name,loadprocs,$CallPoint) $ProcName
				}
			} else {
				lappend DEZData($Name,loadprocs,$CallPoint) $ProcName
			}
		} else {
			error "The call point \"$CallPoint\" is not recognized as a valid load procedure call point."
		}
	} else {
		error "The wrong number of arguments were supplied to \"$Name addloadproc\""
	}
}

proc ::AIEnv::GUIManagement::DEZ::_deleteloadproc {Name args} {
	variable DEZData
	variable LoadProcCallPoints
	if { [llength $args] == 2} {
		set ProcName [lindex $args 0]
		set CallPoint [string toupper [lindex $args 1]]
		if {[lsearch $LoadProcCallPoints $CallPoint] != -1} {
			
		}
	}
}

proc ::AIEnv::GUIManagement::DEZ::DestroyAll {} {
	variable DEZData
	foreach Tree $DEZData($Trees) {
		$Tree destroy
	}
}

#----------------------------------------------------------------------------------
# This procedure is responsible for setting the values of a variable within
# the given DEZ
#----------------------------------------------------------------------------------
proc ::AIEnv::GUIManagement::DEZ::_set {Name args} {
    # Evaluate things in the namespace of this dez
    set Namespace [::AIEnv::GUIManagement::GetNamespace DEZ $Name]

    # Move the name passed into this function into the global variable
    # _DEZName so that we can reference it from within the namespace
    # command below
    global _DEZName
    global _DEZArgs
    set _DEZName $Name
    set _DEZArgs $args

    namespace eval $Namespace {
	    global _DEZName
	    global _DEZArgs
	    global select_opts
	    set LocalVariables [::AIEnv::GUIManagement::GetLocalVariables $_DEZName]
	    set FullVariableName [lindex $_DEZArgs 0]
	    set Value [lindex $_DEZArgs 1]
        # if long list of entities it's necessary to fix aie_ command (see deletePoint/Curve/Surface)
        # Currently fixed functions must have option "allow_long_list" 
    
        if {([info exists select_opts] && [lsearch $select_opts "allow_long_list"] >= 0) && \
            ($_DEZName == "transformSurfsToolsDEZ" || $_DEZName == "repairGeomDEZ" || $_DEZName == "createPartDEZ" || $_DEZName == "modifyPartDEZ" ||  $_DEZName == "createBlockDEZ")} {
            if {[llength $Value] != 0} {
                if {$_DEZName == "createBlockDEZ" && [lindex [split $FullVariableName ::] end] == "blockSurfs"} {
                    set N_args [llength $Value]
                } else {
                    set N_args [expr [llength $Value] / 2]
                }
            } else {
                set N_args 0
            }
        } else {
	        set N_args [llength $Value]
	    }
	    if {[info exists LongList] && [string match ::* $FullVariableName] && ([info exists select_opts] && [lsearch $select_opts "allow_long_list"] >= 0)} {
            unset LongList
        }
	    if {$N_args > 20} {
	        if {[info exists select_opts] && [lsearch $select_opts "allow_long_list"] >= 0} {
		        set LongList $Value
		        set Value "$N_args entities"
	        }
	    }
        if [string match ::* $FullVariableName] {
            # Special case - just set the global variable
            upvar \#0 $FullVariableName lvar
            set lvar $Value
        } else {
           set VariableName [namespace tail $FullVariableName]
           set VariableNamespace [namespace qualifiers $FullVariableName]
           set CurrentNamespace [namespace current]
           if {$VariableNamespace != ""} {
               if { $CurrentNamespace != $VariableNamespace } {
                   error "Proc: ::AIEnv::GUIManagement::DEZ::_set \nThe variable named: \$VariableName\" resides in namespace: \"$VariableNamespace\" which is different from the current namespace scope: \"$CurrentNamespace\""
               }
           }
           if {[lsearch -exact $LocalVariables $VariableName] != -1} {
               variable $VariableName
               set $VariableName $Value
           } else {
               error "Proc: ::AIEnv::GUIManagement::DEZ::_set \nThe variable named: \"$VariableName\" was not found within the scope of the DEZ named: \"$_DEZName\""
           }
        }
    }
}

proc ::AIEnv::GUIManagement::DEZ::_get {Name args} {
	# Evaluate things in the namespace of this dez
	set Namespace [::AIEnv::GUIManagement::GetNamespace DEZ $Name]
	
	# Move the name passed into this function into the global variable
	# _DEZName so that we can reference it from within the namespace
	# command below
	global _DEZName
	global _DEZArgs
	set _DEZName $Name
	set _DEZArgs $args
	
	namespace eval $Namespace {
		global _DEZName
		global _DEZArgs
		set LocalVariables [::AIEnv::GUIManagement::GetLocalVariables $_DEZName]
		
		set VariableName [namespace tail [lindex $_DEZArgs 0]]
		set VariableNamespace [namespace qualifiers [lindex $_DEZArgs 0]]
		set CurrentNamespace [namespace current]

		if { $VariableNamespace != "" } {
			if { $CurrentNamespace != $VariableNamespace } {
				error "Proc: ::AIEnv::GUIManagement::DEZ::_get \nThe variable named: \$VariableName\" resides in namespace: \"$VariableNamespace\" which is different from the current namespace scope: \"$CurrentNamespace\""
			}
		}
		if { [lsearch -exact $LocalVariables $VariableName] != -1 } {
			variable $VariableName
			return [subst [set [subst $VariableName]]]
		}
	}
}

proc ::AIEnv::GUIManagement::DEZ::_proc {Name args} {
	variable DidExecuteUserProc
	set Namespace [::AIEnv::GUIManagement::GetNamespace DEZ $Name]
	global _DEZName
	global _DEZArgs
	global _UserProc
	
	set _DEZName $Name
	set _DEZArgs $args
	
	# Look for the function to see if it exists before we move into the
	# namespace
	set FuncName [lindex $args 0]
	set NullFunc [string toupper $FuncName]
	if { $NullFunc == "NULL" || $NullFunc == "" } {
		return
	}
	# Don't inforce a case convention on the user proc
	regexp -nocase "$FuncName" [join [info commands]] UserProc
	
	if { [info exists UserProc] } {
		if { $UserProc != "" } {
			set _UserProc $UserProc
			set DidExecuteUserProc 1
			namespace eval $Namespace {
				global _DEZName
				global _DEZArgs
				global _UserProc
				
				set GlobalVariables [::AIEnv::GUIManagement::DEZ::ExtractGlobalVariablesFromUserProc $_UserProc]
				set LocalVariables [::AIEnv::GUIManagement::GetLocalVariables $_DEZName]

				# Bring these variables into this scope
				foreach Var $LocalVariables {
					variable $Var
				}
				
				foreach Var $GlobalVariables {
					global $Var
				}
				
				# Get the names of the arguements for this procedure
				set ActualFuncArgs [info args $_UserProc]
				# Pull the arguments for the function into the local scope
				set ArgListIndex 1
				set SuppliedArgCount [expr [llength $_DEZArgs] - 1]
				foreach ActualArg $ActualFuncArgs {
					# Bring the argument into local scope
					variable $ActualArg
					if { $ArgListIndex <= $SuppliedArgCount } {
						set $ActualArg [lindex $_DEZArgs $ArgListIndex]
					} elseif { [info default $_UserProc $ActualArg Value] == 1} {
						set $ActualArg $Value
					} else {
						mess "Error: Could not match a value for arg: \"$ActualArg\" while executing: \"$_DEZName proc $FuncName ...\"\n" red
					}
					incr ArgListIndex
				}

				# Now get the guts of the procedure and execute in this namespace
				set ProcBody [info body $_UserProc]
				eval $ProcBody
			}
		}
	}
}

proc ::AIEnv::GUIManagement::DEZ::ExtractGlobalVariablesFromUserProc {UserProc} {
	set Globals ""
	set ProcBody [info body $UserProc]
	set Lines [split $ProcBody "\n"]
	
 	foreach L $Lines {
		set L [string trim $L]
		set i [string first "global" $L]
		if { $i != -1 } {
			# Offset over the global keyword to the remaining string
			incr i [expr [string length "global"] + 1]
			
			set VarString [string range $L $i end]
			set Vars [split $VarString]
			foreach V $Vars {
				if {$V != ""} {
					lappend Globals $V
				}
			}
		}
	}
	return $Globals
}

proc ::AIEnv::GUIManagement::DEZ::_apply {Name args} {
        global select_action
	variable DEZData
    
        set select_action done
# making busy consistent:
      if {[::AIEnv::GUIManagement::TabbedIconPageRaise] != "Post-processing"} {busy 1}
        set stat 0
	# This is the list of function suffixes that will be searched
	# by the _apply proc in order until one is found or the list
	# is empty.  This list must be maintained in sorted order where
	# order is defined as the most applicable (no pun intended) function
	# first.
	set CandidateFunctionSuffixes [list "Apply" "OK"]
	if { $DEZData($Name-DirtyFlag) == 1 } {
	        #unhiglight geometry if any selected
		global aie_guiOpt
		if {$aie_guiOpt(withMedGWin)} {
	           ic_reset_geo_selected
	           ic_undo_group_begin
		}
		SetClean $Name
		set stat [ExecuteUserProc $Name $CandidateFunctionSuffixes DefaultApply]
		ExecuteUserProc $Name [list "AfterApply" "AfterOK"]
	        if {$aie_guiOpt(withMedGWin)} {
		   ic_undo_group_end
		}
	}
	busy reset
        return $stat
}

proc ::AIEnv::GUIManagement::DEZ::_accept {Name args} {
	global select_action
	variable DEZData
    
        set select_action done
        set stat 0
	# This is the list of function suffixes that will be searched
	# by the _apply proc in order until one is found or the list
	# is empty.  This list must be maintained in sorted order where
	# order is defined as the most applicable (no pun intended) function
	# first.
	set CandidateFunctionSuffixes [list "OK" "Apply"]
	
	if { $DEZData($Name-DirtyFlag) == 1 } {
	    	global aie_guiOpt
		if {$aie_guiOpt(withMedGWin)} {
	           ic_reset_geo_selected
	           ic_undo_group_begin
		}
	    set stat [ExecuteUserProc $Name $CandidateFunctionSuffixes DefaultAccept]
		SetClean $Name
	        if {$aie_guiOpt(withMedGWin)} {
		   ic_undo_group_end
		}
	}
	
	_hide $Name $args
       
        return $stat
}

proc ::AIEnv::GUIManagement::DEZ::_cancel {Name args} {
	global select_action

	# This is the list of function suffixes that will be searched
	# by the _apply proc in order until one is found or the list
	# is empty.  This list must be maintained in sorted order where
	# order is defined as the most applicable (no pun intended) function
	# first.
	set CandidateFunctionSuffixes [list "Cancel"]

        set select_action cancel
	ExecuteUserProc $Name $CandidateFunctionSuffixes DefaultCancel
	
	_hide $Name $args
}

proc ::AIEnv::GUIManagement::DEZ::ExecuteUserProc {Name CandidateFunctionSuffixes {DefaultProc ""}} {
	# Iterate over all of the possible candidate functions
	variable DidExecuteUserProc
	set DidExecuteUserProc 0
	set stat 0
	foreach Candidate $CandidateFunctionSuffixes {
		# Build up the default proc Name
		set ProcName "on${Name}${Candidate}"
		set args $ProcName
		set stat [_proc $Name $args]
		if { $DidExecuteUserProc == 1 } {
			break
		}
	}
	if { $DidExecuteUserProc == 0 } {
		if {$DefaultProc != ""} {
		    set stat [$DefaultProc $Name]
		}
	}
	return $stat
}

proc ::AIEnv::GUIManagement::DEZ::_create { DEZName args} {
	# This procedure builds the DEZ within the frame allowed for the dez
	variable DEZData
	set GUITree $DEZData($DEZName-Tree)
	variable ::AIEnv::GUIManagement::GUIZones
	variable ::AIEnv::GUIManagement::GUIDisplayData
	variable ::AIEnv::GUIManagement::CATRootDir
	
	set RootDir $::AIEnv::GUIManagement::CATRootDir
	
	set NodeID [lindex $args 0]
	set Parent $::AIEnv::GUIManagement::GUIZones("DataEntryZone")
	set ThisDEZ [frame $Parent.$DEZName]
	set TitleFrame [frame $ThisDEZ.titleFrame]
	
	set DEZData($DEZName-Win) $ThisDEZ

	set Title [label $TitleFrame.title -text [$GUITree get $NodeID -key "Title"] \
	                                   -font $::AIEnv::GUIManagement::GUIDisplayData("DEZTitleFont") \
	                                   -wraplength $::AIEnv::GUIManagement::GUIDisplayData("DEZTitleWrapLength") \
	                                   -justify left]
	set HelpButtonBar [ButtonBox $TitleFrame.bbox  \
	                   -spacing [expr $::AIEnv::GUIManagement::GUIDisplayData("ImageSize") / 4] \
	                   -padx 1 \
	                   -pady 1]
	
	set FileName [::AIEnv::GUIManagement::GetFileName [file join $RootDir icons help.gif]]
	set im [image create photo -file $FileName]
	
	$HelpButtonBar add -image $im -highlightthickness 0 -takefocus 0 -relief link \
	                   -borderwidth 1 -padx 1 -pady 1 -helptext "help" -command "$DEZName help"
	
	grid columnconfigure $TitleFrame 0 -weight 0
	grid columnconfigure $TitleFrame 1 -weight 1
	grid columnconfigure $TitleFrame 0 -weight 0
	
	grid $Title -row 0 -column 0 -sticky w
	grid $HelpButtonBar -row 0 -column 2 -sticky e
	
	set TopSep [Separator $ThisDEZ.topSep -orient horizontal]
	set ScrlWindow [ScrolledWindow $ThisDEZ.sw -auto both]
	set ScrlFrame [ScrollableFrame $ScrlWindow.sf -constrainedwidth true]
	$ScrlWindow setwidget $ScrlFrame
	set InternalWidgetFrame [$ScrlFrame getframe]
	set BotSep [Separator $ThisDEZ.botSep -orient horizontal]
	
    set DEZData($DEZName-ScrlFrame) $ScrlFrame
	set ButtonFrame [frame $ThisDEZ.buttonFrame]
	
	set apply_text "Apply"
	if {$DEZName == "meshAutoDEZ"} {
	    set apply_text "Compute"
	}

	set ApplyButton [button $ButtonFrame.apply -text $apply_text -font $::AIEnv::GUIManagement::GUIDisplayData("ButtonFont") \
											   -default normal \
											   -command "$DEZName apply"]

	set OKButton [button $ButtonFrame.accept -text "OK" -font $::AIEnv::GUIManagement::GUIDisplayData("ButtonFont") \
									       	 -default active \
										     -command "$DEZName accept"]

	set CancelButton [button $ButtonFrame.cancel -text "Dismiss" -font $::AIEnv::GUIManagement::GUIDisplayData("ButtonFont") \
												 -default normal \
												 -command "$DEZName cancel"]
# Anshul: Does not work on any of the UNIX platforms
#	set maxWidth 0
#	foreach b [list $ApplyButton $OKButton $CancelButton] {
#		set w [winfo reqwidth $b]
#		if { $maxWidth < $w } {
#			set maxWidth $w
#		}
#	}
#	set cw1 [font measure $::AIEnv::GUIManagement::GUIDisplayData("ButtonFont") "A"]
#	set cw2 [font measure $::AIEnv::GUIManagement::GUIDisplayData("ButtonFont") "W"]
#	set cw3 [font measure $::AIEnv::GUIManagement::GUIDisplayData("ButtonFont") "G"]
#	
#	set cw_avg [expr ($cw1 + $cw2 + $cw3) / 3]
#	
#	set Width  [expr (int(floor($maxWidth / $cw_avg)+1))]
	set Width $GUIDisplayData("ButtonWidth")
	foreach b [list $ApplyButton $OKButton $CancelButton] {
		$b configure -width $Width
	}

	# Enable the dynamic greying out of dezs
	
	_addtracebutton $DEZName $OKButton
	_addtracebutton $DEZName $ApplyButton
	_addtracebutton_others $DEZName $CancelButton

# Anshul: I moved the Cancel button from column 4 to column 3
	grid columnconfigure $ButtonFrame 0 -weight 1
	grid columnconfigure $ButtonFrame 1 -weight 0 -pad $::AIEnv::GUIManagement::GUIDisplayData("ButtonPad")
	grid columnconfigure $ButtonFrame 2 -weight 0 -pad $::AIEnv::GUIManagement::GUIDisplayData("ButtonPad")
	grid columnconfigure $ButtonFrame 3 -weight 0 -pad $::AIEnv::GUIManagement::GUIDisplayData("ButtonPad")
	grid columnconfigure $ButtonFrame 4 -weight 0 -minsize 10
	
	grid $ApplyButton -column 1 -row 0 
	grid $OKButton -column 2 -row 0
	grid $CancelButton -column 3 -row 0
	
	grid rowconfigure $ThisDEZ 0 -weight 0 -minsize 0
	grid rowconfigure $ThisDEZ 1 -weight 0 -minsize 0
	grid rowconfigure $ThisDEZ 2 -weight 1 
	grid rowconfigure $ThisDEZ 3 -weight 0 -minsize 0
	grid rowconfigure $ThisDEZ 4 -weight 0 -minsize 0
	
	grid columnconfigure $ThisDEZ 0 -weight 1
	
	grid $TitleFrame  -row 0 -column 0 -sticky ew
	grid $TopSep      -row 1 -column 0 -sticky ew -pady 3 -padx 2
	grid $ScrlWindow  -row 2 -column 0 -sticky nsew -pady 2
	grid $BotSep      -row 3 -column 0 -sticky ew -pady 3 -padx 2
	grid $ButtonFrame -row 4 -column 0 
	
	grid columnconfigure $InternalWidgetFrame 0 -weight 0
	grid columnconfigure $InternalWidgetFrame 1 -weight 1
	grid columnconfigure $InternalWidgetFrame 2 -weight 0
	
	WindowPathStack push $InternalWidgetFrame
	DEZRowCountStack push 0
	$GUITree set $NodeID -key "WindowPath" $ThisDEZ
	set DEZData($DEZName-IsBuilt) 1
}

proc ::AIEnv::GUIManagement::DEZ::_exist {Name args} {
    variable DEZData

    return $DEZData($Name-IsBuilt)
}

proc ::AIEnv::GUIManagement::DEZ::_build {Name args} {
    variable DEZData
    global auto_pick_mode

    set first_build 0
    variable ::AIEnv::GUIManagement::ItemNameMap
    TreeStack push $DEZData($Name-Tree)
	
    if { $DEZData($Name-IsBuilt) == 0 } {
	::AIEnv::GUIManagement::BuildSubcomponent
	_enabletrace $Name
	set first_build 1
    } 

    # Turn-off auto pick mode during first build
    set cur_auto_pick_mode $auto_pick_mode
    if $cur_auto_pick_mode {
	set auto_pick_mode 0
    }
    set CandidateFunctionSuffixes [list "Load"]
    SetClean $Name	
    ExecuteAdditionalLoadProcs $Name "BEFORE_ON_LOAD"
    ExecuteUserProc $Name $CandidateFunctionSuffixes DefaultLoad
    TreeStack pop
    set auto_pick_mode $cur_auto_pick_mode	
}
#====================
proc ::AIEnv::GUIManagement::DEZ::CheckInitializeEG {name {node node1}} {
# This proc will be called once for each DEZ
# set EG variable may initiate "pick" if auto_pick_mode: 
# turn temporary off:
global auto_pick_mode
	if {$node == "node1"} {
		set was_auto_pick_mode $auto_pick_mode
		set auto_pick_mode 0		
	}
#
	set GUITree [TreeStack peek]	
	foreach i [$GUITree children $node] {
		set t [$GUITree get $i -key "Type"]
#
		if {$t == "ExclusiveGroup"}  {	
#                  ^^^^^^^^^^^^^^
			if {[$GUITree get $i -key "Proc"] != "NULL"} continue
			set Var [$GUITree get $i -key "Variable"]
			set v ::AIEnv::DEZ::${name}::$Var
			if {![info exists $v] || ![llength [set $v]]} {
			set $v 0
		}
		}
#
		if {$t == "RadioGroup"}  {
#                  ^^^^^^^^^^
			if {[$GUITree get $i -key "Proc"] != "NULL"} continue
			set Var [$GUITree get $i -key "Variable"]
			set v ::AIEnv::DEZ::${name}::$Var
			set ch0 [lindex [$GUITree children $i] 0]
			set val0 [$GUITree get $ch0 -key "Value"]
			if {![info exists $v] || ![llength [set $v]]} {
			set $v $val0			
		}
		}
#
# any other groups?
#
		CheckInitializeEG $name $i
	}
# restore pick mode
	if {$node == "node1"} {set auto_pick_mode $was_auto_pick_mode}
}
#=================
proc ::AIEnv::GUIManagement::DEZ::_load {Name args} {
	global toolBarInfo select_action ExecuteUserProcAfterLoad IgnoreActiveReload
	variable DEZData
	variable ::AIEnv::GUIManagement::ActiveDEZ
	variable ::AIEnv::GUIManagement::ItemNameMap

	# Fixing problems with slow computer or fast clicking before function completed:
	global busy_loading_DEZ
	if [info exists busy_loading_DEZ] return
	busy 1
	set busy_loading_DEZ 1
	
	set ExecuteUserProcAfterLoad 0
    # Ensure that if a selection mode is active it will go away when you
    # switch dez's
    set select_action cancel
    set ::status_message "" 
	# Make sure any previous DEZ is unloaded
	if { $::AIEnv::GUIManagement::ActiveDEZ != "NULL" } {
		set AllowReload [$Name get AllowActiveReload]
		if { $AllowReload == 0 } {
			if { $::AIEnv::GUIManagement::ActiveDEZ == $Name } {
				# Don't do anything.
				busy reset
				unset busy_loading_DEZ
				return
			} else {
				# Unload the previous DEZ
				$::AIEnv::GUIManagement::ActiveDEZ unload
			}
		} else {
			# Unload the previous DEZ
			$::AIEnv::GUIManagement::ActiveDEZ unload
		}
	}
        # Record this dez as active here to avoid DEZ's getting stacked
	set ::AIEnv::GUIManagement::ActiveDEZ $Name
	TreeStack push $DEZData($Name-Tree)
	
	if { $DEZData($Name-IsBuilt) == 0 } {
		::AIEnv::GUIManagement::BuildSubcomponent
		_enabletrace $Name
		set load_first_time 1
	} else {
		set load_first_time 0
	} 
          
	# This is the list of function suffixes that will be searched
	# by the _apply proc in order until one is found or the list
	# is empty.  This list must be maintained in sorted order where
	# order is defined as the most applicable (no pun intended) function
	# first.

	set CandidateFunctionSuffixes [list "Load"]

	SetClean $Name
	
	ExecuteAdditionalLoadProcs $Name "BEFORE_ON_LOAD"
	
	ExecuteUserProc $Name $CandidateFunctionSuffixes DefaultLoad
	set NodeID $::AIEnv::GUIManagement::ItemNameMap($Name)
	set Path [[TreeStack peek_one] get $NodeID -key "WindowPath"]
	pack $Path -fill both -expand yes
	
	ExecuteAdditionalLoadProcs $Name "AFTER_ON_LOAD"
	
    update idletasks
    if {!$load_first_time && [info exist DEZData($Name-ScrlFrame)]} {
       $DEZData($Name-ScrlFrame) yview moveto 0
    }

	set CandidateFunctionSuffixes [list "AfterLoad"]
	ExecuteUserProc $Name $CandidateFunctionSuffixes DefaultAfterLoad
    set toolBarInfo(activeDEZ) $toolBarInfo(activeWin)

    # restore the saved data if available - only once
    if [info exists ::AIEnv::GUIManagement::DEZ::${Name}_data] {
	    set ddlist_vars [getTypeKeyVars $Name "DropDownEntry" "List"]
	    foreach {n v} [array get ::AIEnv::GUIManagement::DEZ::${Name}_data] {		
		    # never restore list menu data, the menu could be modified/enlarged in the meantime
		    if {[lsearch $ddlist_vars $n] < 0} {
		        if [info exists ::IgnoreActiveReload($Name,$n)] continue
		        catch {$Name set $n $v}
		    }
	    }
	    unset ::AIEnv::GUIManagement::DEZ::${Name}_data
	}
	if $load_first_time {CheckInitializeEG $Name}
	if $ExecuteUserProcAfterLoad {
	    ExecuteUserProc $Name $CandidateFunctionSuffixes DefaultAfterLoad
	    set ExecuteUserProcAfterLoad 0
	}
	busy reset
    # scroll bar is missing sometimes, reset the height of the scroll bar solves the problem
    if {[info exists DEZData($Name-ScrlFrame)] && [winfo exists $DEZData($Name-ScrlFrame)]} {
	    $DEZData($Name-ScrlFrame) configure -height [$DEZData($Name-ScrlFrame) cget -height]
    }
	unset busy_loading_DEZ
}

proc ::AIEnv::GUIManagement::DEZ::_unload {Name args} {
        global toolBarInfo
	variable ::AIEnv::GUIManagement::ActiveDEZ
	# This is the list of function suffixes that will be searched
	# by the _apply proc in order until one is found or the list
	# is empty.  This list must be maintained in sorted order where
	# order is defined as the most applicable (no pun intended) function
	# first.

        if {$::AIEnv::GUIManagement::ActiveDEZ != $Name} {
	    return
	}
	set CandidateFunctionSuffixes [list "UnLoad"]
	
	ExecuteUserProc $Name $CandidateFunctionSuffixes DefaultUnLoad

	# Unselect geom entities if any
	global aie_guiOpt
	if {$aie_guiOpt(withMedGWin)} {
	   aie_reset_geo_selected
	}
	
	# Unload the DEZ
	set NodeID $::AIEnv::GUIManagement::ItemNameMap($Name)
	set Path [[TreeStack peek_one] get $NodeID -key "WindowPath"]
	pack forget $Path
	set ::AIEnv::GUIManagement::ActiveDEZ "NULL"
	::AIEnv::GUIManagement::toolBarSelect $toolBarInfo(activeDEZ) "" 1
        set toolBarInfo(activeDEZ) ""

	TreeStack pop
}

proc ::AIEnv::GUIManagement::DEZ::_show {Name args} {
	_load $Name $args
}


proc ::AIEnv::GUIManagement::DEZ::_hide {Name args} {
	_unload $Name $args 
}

proc ::AIEnv::GUIManagement::DEZ::_help {Name args} {
	set CandidateFunctionSuffixes "Help"
	ExecuteUserProc $Name $CandidateFunctionSuffixes DefaultHelp
}


proc ::AIEnv::GUIManagement::DEZ::_path {DEZName Name {node ""}} {
   variable DEZData
   set GUITree $DEZData($DEZName-Tree)
   if {$node == ""} {set node root}

   foreach i [$GUITree children $node] {
      if {[$GUITree get $i -key "Name"] == $Name} {
         if [$GUITree keyexists $i -key "WindowPath"] {
            return [$GUITree get $i -key "WindowPath"]
         } else {
            return ""
         }
      } else {
         set rr [_path $DEZName $Name $i]
         if {$rr != ""} {return $rr}
      }
   }
   return ""  
}

proc ::AIEnv::GUIManagement::DEZ::_pathIgnoreErrors {DEZName Name {node ""}} {
   variable DEZData

   set GUITree $DEZData($DEZName-Tree)
   if {$node == ""} {set node root}
   
   foreach i [$GUITree children $node] {
       catch { set FoundName [$GUITree get $i -key Name] }
       if {[info exists FoundName] && $FoundName == $Name} {
           return [$GUITree get $i -key WindowPath]
       } else {
          set rr [_pathIgnoreErrors $DEZName $Name $i]
          if {$rr != ""} { return $rr }
       }
   }
   return ""
}

# Caution: This is not very efficient - Ganesan
proc ::AIEnv::GUIManagement::DEZ::_getGuiType {DEZName Name key {node ""}} {
   variable DEZData

   set GUITree $DEZData($DEZName-Tree)
   if {$node == ""} {set node root}
   
   foreach i [$GUITree children $node] {
       catch { set FoundName [$GUITree get $i -key $key] }
       if {[info exists FoundName] && $FoundName == $Name} {
           return [$GUITree get $i -key Type]
       } else {
          set rr [_getGuiType $DEZName $Name $key $i]
          if {$rr != ""} { return $rr }
       }
   }
   return ""
}

proc ::AIEnv::GUIManagement::DEZ::getTypeKeyVars {DEZName type key} {
    variable DEZTypeKeyVars
    
    set DEZTypeKeyVars ""
    set GUITree [$DEZName gettree]
    $GUITree walk "root" -order both -type dfs -command "addTypeKeyVars $GUITree %n $type $key"

    return $DEZTypeKeyVars
}

proc ::AIEnv::GUIManagement::DEZ::addTypeKeyVars {GUITree Node type key} {
    variable DEZTypeKeyVars

    if { [$GUITree get $Node -key "Type"] == "$type" } {
	if [catch {set vname [$GUITree get $Node -key "$key"]} ret] {
	    puts $res
	} else {
	    lappend DEZTypeKeyVars $vname
	}
    }
}

proc ::AIEnv::GUIManagement::DEZ::ChangeLabel {DEZName Label} {
    variable DEZData
    if ![info exists DEZData($DEZName-Tree)] {
        error "The specific GUI entity named \"$DEZName\" does not exist."
    }
    set GUITree $DEZData($DEZName-Tree)
    if {[$GUITree get [$GUITree children root] -key "Type"] != "DataEntryDialog"} {
        error "The specific GUI entity named \"$DEZName\" must be type \"DataEntryDialog\"."
    }
    variable ::AIEnv::GUIManagement::GUIZones
    set Parent $::AIEnv::GUIManagement::GUIZones("DataEntryZone")
    set ThisDEZ $Parent.$DEZName.titleFrame.title
    if [winfo exists $ThisDEZ] {
        $ThisDEZ configure -text "$Label"
    }
}

proc ::AIEnv::GUIManagement::DEZ::DefaultApply { DEZName } {
	
}

proc ::AIEnv::GUIManagement::DEZ::DefaultAccept { DEZName } {
	
}

proc ::AIEnv::GUIManagement::DEZ::DefaultHelp { DEZName } {
	mess "Currently there is no help available for: $DEZName\n" red
}

proc ::AIEnv::GUIManagement::DEZ::DefaultCancel { DEZName } {
	
}

proc ::AIEnv::GUIManagement::DEZ::DefaultLoad { DEZName } {
	
}

proc ::AIEnv::GUIManagement::DEZ::DefaultUnLoad { DEZName } {
	
}

proc ::AIEnv::GUIManagement::DEZ::DefaultAfterLoad { DEZName } {
	
}

proc ::AIEnv::GUIManagement::DEZ::ExecuteAdditionalLoadProcs { Name LoadPoint } {
	variable DEZData
	if {[info exists DEZData($Name,loadprocs,$LoadPoint)]} {
		foreach f $DEZData($Name,loadprocs,$LoadPoint) {
			eval $f
		}
	}
}

proc ::AIEnv::GUIManagement::DEZShow { DEZName } {
    variable ActiveDEZ
    if { $ActiveDEZ != "NULL" } {
        $ActiveDEZ hide
    }
    $ActiveDEZ show
}

proc ::AIEnv::GUIManagement::DEZHide {} {
    variable ActiveDEZ
    if { $ActiveDEZ != "NULL" } {
        $ActiveDEZ hide
    }
}


proc ::AIEnv::GUIManagement::DEZ::_remove {Name args} {
   variable DEZData

   if ![info exist DEZData($Name-Tree)] {return ""}
   set DezTree $DEZData($Name-Tree)

   if {[info command $DezTree] == ""} {return ""}

   set NodeID [$DezTree children root]

   if {$Name != [$DezTree get $NodeID -key  "Name"]} {
      error "DEZ $Name inconsistent with data in $DezTree"
      return ""
   }

    _unload $Name

   set ThisDEZ [$DezTree get $NodeID -key "WindowPath"]

   if {($ThisDEZ != "NULL") && [winfo exist $ThisDEZ]} {
      destroy $ThisDEZ
   }

   $DezTree destroy

   foreach n [array names DEZData $Name-*] {
      unset DEZData($n)
   }

   if [info exists ::AIEnv::GUIManagement::DEZ::${Name}_data] {
      unset ::AIEnv::GUIManagement::DEZ::${Name}_data
   }

   if [info exist ::AIEnv::GUIManagement::LocalVariables($Name)] {
      foreach n $::AIEnv::GUIManagement::LocalVariables($Name) {
         variable $n
         if [info exist $n] {unset $n}
      }
   }
}
