# $Revision$ on $Date$
# The above revision line needs to be the first line for all techtk files
# Copyright (c) 2006 Ansys Inc
namespace eval ::AIEnv::GUIManagement {}

# --------------------------------------------------------------------------------------------------
# Procedures to compute the layout of the toolbars
#

set ::AIEnv::GUIManagement::CurrentVisibleTab ""

proc ::AIEnv::GUIManagement::ComputeIconButtonDimensions {} {
	# Create a test button with an icon and a test button with a text label
	variable IconButtonTextLength
	variable GUIDisplayData
	variable CATRootDir
	variable IconDir
	variable GUIZones
	variable DummyIcon
	
	set top [toplevel .dummy]
	wm overrideredirect $top 1
	wm geometry $top +10000+10000
	
	if {![info exists IconButtonTextLength]} {
		set IconButtonTextLength 5
	}
	set TestToolbar [ButtonBox $top.tbar -spacing $GUIDisplayData("ButtonBoxSpacing") \
						-padx $GUIDisplayData("ButtonBoxPadx") -pady $GUIDisplayData("ButtonBoxPady")]
	
	# Check the file name to see if it is a valid file (Nocase compare)
	set FileName [GetFileName [file join $CATRootDir $IconDir dummy1.gif]]
	
	set im [image create photo -format GIF -file $FileName]
	set DummyIcon $im
	
	set TestIconButton [$TestToolbar add -image $im \
				-highlightthickness 0 -takefocus 0 \
				-relief $GUIDisplayData("IconButtonRelief") \
				-borderwidth $GUIDisplayData("IconButtonBorderWidth") \
				-padx $GUIDisplayData("IconButtonPadx") \
				-pady $GUIDisplayData("IconButtonPady") ]
	
    set TestTextButton [button $top.tbut -text "Hi" -font $GUIDisplayData("BubbleFont") \
                        -width $IconButtonTextLength]
    
    pack $TestToolbar 
    pack $TestTextButton
    
    update
    
    set IconButtonWidth [winfo width $TestToolbar]
    set TextButtonWidth [winfo width $TestTextButton]
    
    set GUIDisplayData("TextButtonCharacterWidth") $IconButtonTextLength
    set GUIDisplayData("IconButtonWidth") $IconButtonWidth
    set GUIDisplayData("TextButtonWidth") $TextButtonWidth
    
    destroy $top
    
}

proc ::AIEnv::GUIManagement::GetIconToolbarLayout {NumButtons MaxWidth} {
    variable LastSeparator
    variable RightMostCorner
    variable GUIDisplayData
    variable CurrentRowFrame
    variable CurrentRowNumber
    
    if { ![info exists RightMostCorner] } {
	set RightMostCorner 0
    }
    if ![info exists CurrentRowNumber] {
	set CurrentRowNumber 0
    }
    
    set ThisToolbarWidth [expr $NumButtons * $GUIDisplayData("IconButtonWidth")]
    set NewRightCorner [expr $RightMostCorner + $ThisToolbarWidth]
    
    if { $NewRightCorner > $MaxWidth } {
	set RightMostCorner 0
	incr CurrentRowNumber
	if {[info exists LastSeparator]} {
	    pack forget $LastSeparator
	}
	set Parent [WindowPathStack peek]
	set CurrentRowFrame [frame $Parent.f$CurrentRowNumber]
	grid configure $CurrentRowFrame -row $CurrentRowNumber -column 0 -sticky nw
	grid rowconfigure $Parent $CurrentRowNumber -weight 0
	grid rowconfigure $Parent [expr $CurrentRowNumber + 1] -weight 1
	
    } else {
	# Record for next time
	set RightMostCorner $NewRightCorner
	# The very first row might not exist
	if {[info exists CurrentRowFrame ]} {
	    return $CurrentRowFrame
	} else {
	    set CurrentRowNumber 0
	    set Parent [WindowPathStack peek]
	    set CurrentRowFrame [frame $Parent.f$CurrentRowNumber]
	    grid configure $CurrentRowFrame -row $CurrentRowNumber -column 0 -sticky nw
	    grid rowconfigure $Parent $CurrentRowNumber -weight 0
	    grid rowconfigure $Parent [expr $CurrentRowNumber + 1] -weight 1
	}
    }
    return $CurrentRowFrame
}

proc ::AIEnv::GUIManagement::ComputeNumberOfTextButtonColumns {MaxWidth} {
	variable TextButtonColumns
	variable GUIDisplayData
	variable CurrentColumn
	variable CurrentRow
	
	set TextButtonColumns [expr int($MaxWidth / $GUIDisplayData("TextButtonWidth")) - 1]
	
	set CurrentColumn 0
	set CurrentRow 0
	
	return $TextButtonColumns
}

proc ::AIEnv::GUIManagement::GetTextButtonRowAndColumn {} {
	variable TextButtonColumns
	variable GUIDisplayData
	variable CurrentColumn
	variable CurrentRow
	
	
	# See if we need to move to the next column
	if { ![info exists CurrentColumn] } {
		set CurrentColumn 0
	}
	
	if { ![info exists CurrentRow] } {
		set CurrentRow 0
	}
	
	if { $CurrentColumn > $TextButtonColumns} {
		set Parent [WindowPathStack peek]
		set CurrentColumn 0
		grid rowconfigure $Parent $CurrentRow -weight 0
		incr CurrentRow
		grid rowconfigure $Parent $CurrentRow -weight 1 
	}
	
	# Package up the data
	set Data [list $CurrentRow $CurrentColumn]
	# Prepare for the next time
	incr CurrentColumn
	return $Data
}
#---------------------------------------------------------------------------------------------------

proc ::AIEnv::GUIManagement::enterTabbedIconZoneBuild {NodeID} {
    variable GUIZones
    variable ItemNameMap
    variable GUIDisplayData

    set TabbedIconZone $GUIZones("TabbedIconZone")
    # We need a unique name for the notebook, so append the node id of the
    # tabbed icon node to the frame defining the Tabbed Icon GUI Zone

    variable TabbedIconZoneStyle
    variable TabbedIconBar
    if {$TabbedIconZoneStyle == "default"} {
       if { $GUIDisplayData("UseTabIcons") == 1 } {
           set TabbedIconBar [NoteBook $TabbedIconZone.$ItemNameMap("TabbedIcon") -borderwidth 1]
       } else {
           set TabbedIconBar [ NoteBook $TabbedIconZone.$ItemNameMap("TabbedIcon") \
              -font $GUIDisplayData("TabFont") -borderwidth 1 -arcradius 3 ]
       }

       $TabbedIconBar configure -internalborderwidth $GUIDisplayData("TabbedIconBarInternalBorderwidth") 
      # -height $GUIDisplayData("TabbedIconBarHeight")
   } else {
      set TabbedIconBar [frame $TabbedIconZone.$ItemNameMap("TabbedIcon")]
   }
       
    pack $TabbedIconBar -fill both -expand yes -side left
    WindowPathStack push $TabbedIconBar

}

proc ::AIEnv::GUIManagement::leaveTabbedIconZoneBuild {NodeID} {
    
    set TabbedIconBar [WindowPathStack pop]

    variable TabbedIconZoneStyle
    if {$TabbedIconZoneStyle == "default"} {
       foreach page [eval "$TabbedIconBar pages"] {
           eval $TabbedIconBar raise $page
       }

       $TabbedIconBar raise [$TabbedIconBar page 0]
    }
}

proc ::AIEnv::GUIManagement::enterIconZoneBuild {NodeID} {
    variable GUIZones
    variable UseIcons
    variable GUIDisplayData
    variable MaxWidth
    variable CurrentRowNumber
    set CurrentRowNumber 0
    set MaxWidth $GUIDisplayData("IconZoneWidth")
    set UseIcons $GUIDisplayData("UseIconsInCommonZone")
    WindowPathStack push $GUIZones("IconZone")
    
    # Set up the gridding based on whether we are using icons or text buttons
	if { $GUIDisplayData("UseIconsInCommonZone") == 1 } {
		grid columnconfigure $GUIZones("IconZone") 0 -weight 0
		grid columnconfigure $GUIZones("IconZone") 1 -weight 1
	} else {
		# Retrieve the number of text buttons that will fit
		set NumCols [ComputeNumberOfTextButtonColumns $GUIDisplayData("IconZoneWidth")]
		for {set i 0} {$i < $NumCols} {incr i} {
			grid columnconfigure $GUIZones("IconZone") $i -weight 0
		}
		# Push everything to the left
		grid columnconfigure $GUIZones("IconZone") $NumCols -weight 1
	}
}

proc ::AIEnv::GUIManagement::leaveIconZoneBuild {NodeID} {
    variable GUIDisplayData
    variable CurrentRowFrame
	variable CurrentRowNumber
	variable CurrentColumn
	variable CurrentRow
	variable LastSeparator
	variable RightMostCorner
	
	if { [info exists CurrentRow] } {
		unset CurrentRow
	} 
	
	if { [info exists CurrentColumn] } {
		unset CurrentColumn
	}
	
	if { [info exists CurrentRowFrame] } {
		unset CurrentRowFrame
	}
	
	if { [info exists CurrentRowNumber] } {
		unset CurrentRowNumber
	}
	
	if { [info exists RightMostCorner] } {
		unset RightMostCorner
	}
	
	if { [info exists LastSeparator] } {
		pack forget $LastSeparator
		unset LastSeparator
	}
    WindowPathStack pop
}

proc ::AIEnv::GUIManagement::enterTabbedIconBuild {NodeID} {
    variable CATRootDir
    variable IconDir
    variable GUIDisplayData
    variable IconBarNumber
    variable UseIcons
    variable MaxWidth
    variable TabbedIconWidget
    variable DummyIcon
    variable BuildContext

    set GUITree [TreeStack peek]
    
    set theNotebook [WindowPathStack peek]
    
    # We need to use this elsewhere
    set TabbedIconWidget $theNotebook
    
    if { $GUIDisplayData("UseTabIcons") == 1 } {
        set imName [$GUITree get $NodeID -key "ImageName"]
        set FileName [GetFileName [file join $CATRootDir "$IconDir" "$imName"]]
        if [catch {
	    set im [image create photo -format GIF -file $FileName]
	}] { set im $DummyIcon }
	
        set Tooltip [$GUITree get $NodeID -key "ToolTip"]
        set NewTab [$theNotebook insert end $NodeID -image $im]
    } else {
        set Label [$GUITree get $NodeID -key "Label"]
        set NewTab [$theNotebook insert end $NodeID -text $Label]
    }
    
    # Set up the gridding based on whether we are using icons or text buttons
    if { $GUIDisplayData("UseIconsInTabZone") == 1 } {
    	grid columnconfigure $NewTab 0 -weight 0
    	grid columnconfigure $NewTab 1 -weight 1
	} else {
		# Retrieve the number of text buttons that will fit
		set NumCols [ComputeNumberOfTextButtonColumns $GUIDisplayData("TabbedIconZoneWidth")]
		for {set i 0} {$i < $NumCols} {incr i} {
			grid columnconfigure $NewTab $i -weight 0
		}
		# Push everything to the left
		grid columnconfigure $NewTab $NumCols -weight 1
	}
    WindowPathStack push $NewTab
    set UseIcons $GUIDisplayData("UseIconsInTabZone")
    set MaxWidth $GUIDisplayData("TabbedIconZoneWidth")
    grid rowconfigure $NewTab 0 -weight 0
    grid rowconfigure $NewTab 1 -weight 1
    
    set name [$GUITree get $NodeID -key "Name"]
    bind $NewTab <Expose> "set ::AIEnv::GUIManagement::CurrentVisibleTab $name; aie_update_tabs"

    $theNotebook itemconfigure $NodeID -raisecmd "aie_sync_tabs_viewer $name"
    set BuildContext "TabbedIcon"
}

proc ::AIEnv::GUIManagement::leaveTabbedIconBuild {NodeID} {
    variable GUIDisplayData
    variable CurrentRowFrame
	variable CurrentRowNumber
	variable CurrentColumn
	variable CurrentRow
	variable LastSeparator
	variable RightMostCorner
	variable BuildContext
	
	if { [info exists CurrentRow] } {
		unset CurrentRow
	} 

	if { [info exists CurrentColumn] } {
		unset CurrentColumn
	}

	if { [info exists CurrentRowFrame] } {
		unset CurrentRowFrame
	}

	if { [info exists CurrentRowNumber] } {
		unset CurrentRowNumber
	}

	if { [info exists LastSeparator] } {
		pack forget $LastSeparator
		unset LastSeparator
	}

	if { [info exists RightMostCorner] } {
		unset RightMostCorner
	}    
    
    set NewTab [WindowPathStack pop]
    pack $NewTab -side left -anchor w -fill both
    set BuildContext ""
}

proc ::AIEnv::GUIManagement::enterIconBarBuild {NodeID} {
    variable BuildContext
    variable GUIDisplayData
    variable IconBarNumber
    variable IconBarData
    variable UseIcons
    variable MaxWidth
    global toolBarInfo
    
    set GUITree [TreeStack peek]

    if { $BuildContext == "" || $BuildContext == "TabbedIcon"} {
        variable GUIDisplayData
	
	if { $UseIcons == 1 } {
	    # The number of children of this iconbar is the number of
	    # actual buttons.  Use this info to determine if the
	    # iconbar will fit
	    set NumButtons [llength [$GUITree children $NodeID]]
	    set WindowPath [GetIconToolbarLayout $NumButtons $MaxWidth]
	    set homo 1
	    if {$BuildContext == "TabbedIcon"} {set homo 0}
	    set NewToolbar [ButtonBox $WindowPath.$NodeID -spacing $GUIDisplayData("ButtonBoxSpacing") \
				-padx $GUIDisplayData("ButtonBoxPadx") -pady $GUIDisplayData("ButtonBoxPady") \
				-homogeneous $homo]
	    set toolBarInfo($NewToolbar-current) ""
	    WindowPathStack push $NewToolbar
	} else {
	    # Do nothing if we are using text buttons.  They will be
	    # placed directly into the notebook frame. However, to
	    # make the stack work properly, we need to push the zone
	    # frame (Common or Tabbed) on the stack again
	    set Top [WindowPathStack peek]
	    WindowPathStack push $Top
	}
    } elseif { $BuildContext == "IconDrop" } {
        # Do nothing for now
    }
    
}

proc ::AIEnv::GUIManagement::leaveIconBarBuild {NodeID} {
    variable BuildContext
    variable UseIcons
    variable SeparatorID
    variable LastSeparator
    variable GUIDisplayData
           
    # This is just used to generate a unique name for a toolbar
    # separator. However, it has to exist before we can reference
    # it. So make sure that it exists
    if { ![info exists SeparatorID] } {
	set SeparatorID 0	
    }
    if { $BuildContext == "" || $BuildContext == "TabbedIcon"} {
        # Pack the button box
        set Toolbar [WindowPathStack pop]
    	pack $Toolbar -side left -anchor nw
    	set RowFrame [winfo parent $Toolbar]
    	if { $UseIcons == 1 } {
	    set Sep [Separator $RowFrame.sep$SeparatorID -orient vertical]
            pack $Sep -side left -fill y \
		-padx $GUIDisplayData("ToolbarSeparatorPadding") -anchor w
            incr SeparatorID
            set LastSeparator $Sep
	}
    } elseif { $BuildContext == "IconDrop" } {
        # Do nothing for now
    }
}

proc ::AIEnv::GUIManagement::toolBarSelect {win tool {done 0}} {
    variable GUIDisplayData
    variable BGColor
    global toolBarInfo

    if ![info exists toolBarInfo($win-current)] { return }
    if $done {
	if {(([set ::AIEnv::GUIManagement::ActiveDEZ] == "NULL") ||  \
		 $win != $toolBarInfo(activeDEZ)) && $toolBarInfo($win-current) != ""} {
	    set prevtool $toolBarInfo($win-current)
	    $prevtool configure -relief $GUIDisplayData("IconButtonRelief") \
		-background $BGColor
	    if {$tool != ""} {
	        ::AIEnv::GUIManagement::toolBarIconInvoke $tool
	    }
	    set toolBarInfo($win-current) ""
	    return
	}
    }
    
    if {$toolBarInfo($win-current) != "" && (![info exists toolBarInfo(external_select)])} {
	set prevtool $toolBarInfo($win-current)
	$prevtool configure -relief  $GUIDisplayData("IconButtonRelief") \
	    -background $BGColor
    }

    if {$tool != ""} {
	$tool configure -relief sunken -background $GUIDisplayData("SunkenBackground")
	set toolBarInfo($win-current) $tool
	if ![info exists toolBarInfo(external_select)] {
	    set toolBarInfo(activeWin) $win
	}
        # added this to make sure that buttons get updated and to avoid conflict with the values
        # read from the project file causing 2 buttons to be pressed in the same moment
        ::AIEnv::GUIManagement::toolBarIconInvoke $tool
    }
    catch {unset toolBarInfo(external_select)}
}

proc ::AIEnv::GUIManagement::toolBarIconInvoke {tool} {
    variable GUIDisplayData
    set parent [winfo parent $tool]
    set all_parents [winfo parent $parent]
    if {([winfo class $all_parents] == "Frame")} {
        foreach child [winfo children $all_parents] {
            if {[string match *f.bbox? $child] && ([winfo class $child] == "Frame")} {
                foreach child2 [winfo children $child] {
                    if {$child2 != $tool && ([winfo class $child2] == "Button")} {
                        $child2 configure -relief $GUIDisplayData("IconButtonRelief")
                    }
                }
            }
        }
    }
}

proc ::AIEnv::GUIManagement::enterIconButtonBuild {NodeID} {
    variable CATRootDir
    variable BuildContext
    variable GUIDisplayData
    variable IconDir
    variable UseIcons
    variable DummyIcon
    global toolBarInfo

    set GUITree [TreeStack peek]
    
    if { $UseIcons == 1 } {
        set imName [$GUITree get $NodeID -key "ImageName"]
        set Name [$GUITree get $NodeID -key "Name"]
        set Proc [$GUITree get $NodeID -key "Proc"]
        set ToolTip [$GUITree get $NodeID -key "ToolTip"]
        set icon_file [file join $CATRootDir "$IconDir" "$imName"]
        if ![file exists $icon_file] {
           tk_messageBox -message "Icon $icon_file not found!" -type ok -icon warning
        } else {
             set FileName [GetFileName $icon_file]
        }
        if [catch {
	    set im [image create photo -format GIF -file $FileName]
        }] {
	    set im $DummyIcon
        }
        if {$BuildContext == "" || $BuildContext == "TabbedIcon"} {
            set ToolBar [WindowPathStack peek]
            set tb [$ToolBar add -image $im -highlightthickness 0 -takefocus 0 \
                         -relief $GUIDisplayData("IconButtonRelief") \
                         -borderwidth $GUIDisplayData("IconButtonBorderWidth") \
                         -padx $GUIDisplayData("IconButtonPadx") \
                         -pady $GUIDisplayData("IconButtonPady") \
			 -font $GUIDisplayData("BubbleFont") \
		         -helptext $ToolTip]
	    $tb configure -command "::AIEnv::GUIManagement::toolBarSelect $ToolBar $tb; eval $Proc; ::AIEnv::GUIManagement::toolBarSelect $ToolBar $tb 1"
	    set toolBarInfo(widget,$Name) $tb
        } elseif { $BuildContext == "IconDrop" } {
            [WindowPathStack peek] add $im $ToolTip $Proc
        }
    } else {
        set Proc [$GUITree get $NodeID -key "Proc"]
        set Label [$GUITree get $NodeID -key "Label"]
        if { $BuildContext == "" || $BuildContext == "TabbedIcon"} {
            set ParentFrame [WindowPathStack peek]
            set Button [button $ParentFrame.$NodeID -text $Label -relief $GUIDisplayData("TextIconButtonRelief") \
                        -borderwidth $GUIDisplayData("IconButtonBorderWidth") \
						 -padx $GUIDisplayData("IconButtonPadx") \
						 -pady $GUIDisplayData("IconButtonPady") \
						 -font $GUIDisplayData("BubbleFont") \
                         -command "eval $Proc" -width $GUIDisplayData("TextButtonCharacterWidth")]
            set RowCol [GetTextButtonRowAndColumn]
            set Row [lindex $RowCol 0]
            set Col [lindex $RowCol 1]
            grid configure $Button -row $Row -column $Col -sticky nw
        } elseif { $BuildContext == "IconDrop" } {
            # TO DO: Shore up the icon drop stuff
        }
    }
}

proc ::AIEnv::GUIManagement::leaveIconButtonBuild {NodeID} {
    # Do nothing
}

proc ::AIEnv::GUIManagement::enterIconToggleBuild {NodeID} {
    # Not Supported
}

proc ::AIEnv::GUIManagement::leaveIconToggleBuild {NodeID} {
    # Not Supported
}

proc ::AIEnv::GUIManagement::enterIconDropBuild {NodeID} {
    variable BuildContext
       
    set dropButton [::AIEnv::GUIManagement::Widgets::DropdownButton::DropdownButton "dB-$NodeID"]
    # The parent window better be a toolbar
    set Parent [WindowPathStack peek]
    $dropButton create $Parent
    WindowPathStack push $dropButton
    set BuildContext "IconDrop"
}

proc ::AIEnv::GUIManagement::leaveIconDropBuild {NodeID} {
    variable BuildContext
    WindowPathStack pop
    set BuildContext ""
}


