#
# gui.tcl: routines to build the GUI
#
# ------------------------------------------------
# Mumit Khan <khan@xraylith.wisc.edu>
# Center for X-ray Lithography
# University of Wisconsin-Madison
# 3731 Schneider Dr., Stoughton, WI, 53589
# ------------------------------------------------
#
# Copyright (c) 1994-1996 Mumit Khan
#
#

#
# build all the GUI components here, but the callbacks do not belong
# in this file. Those are supplied by client routines.
#

#----------------------------------------------------------------------#
# Build various parts of the UI
#----------------------------------------------------------------------#

#----------------------------------------------------------------------#
# Make the top pulldown menu bar
#----------------------------------------------------------------------#

proc GUI:make_topmenu {menu_name} {
    global gvars
    # build widget .topmenu
    frame $menu_name \
	-background {LightGray} \
	-borderwidth {2} \
	-relief {raised} \
	-class TopMenu

    lappend menu_names $menu_name.mFile
    # build widget $menu_name.mFile
    menubutton $menu_name.mFile \
	-background {LightGray} \
	-foreground {black} \
	-menu "$menu_name.mFile.m" \
	-text {File} \
	-underline {0}

    # build widget $menu_name.mFile.m
    menu $menu_name.mFile.m \
	-background {LightGrey} \
	-foreground {black} \
	-tearoff 0

    $menu_name.mFile.m add command \
	-activebackground {SteelBlue2} \
	-background {LightGray} \
	-command {new_state_cmd} \
	-label {New Workspace ...} \
	-underline {-1}

    $menu_name.mFile.m add command \
	-activebackground {SteelBlue2} \
	-background {LightGray} \
	-command {load_state_cmd} \
	-label {Load Workspace ...} \
	-underline {-1}

    $menu_name.mFile.m add command \
	-activebackground {SteelBlue2} \
	-background {LightGray} \
	-command {save_state_cmd} \
	-label {Save Workspace ...} \
	-underline {-1}

    $menu_name.mFile.m add separator

    # ============================================== 

    # build cascade menu for importing/export shadow namelist files
    $menu_name.mFile.m add cascade \
	-menu "$menu_name.mFile.m.mImport" \
	-label {Import} \
	-underline {-1}

    # build widget $menu_name.mFile.m.mImport
    menu $menu_name.mFile.m.mImport \
	-background {LightGrey} \
	-foreground {black} \
	-tearoff 0

    $menu_name.mFile.m.mImport add command \
	-activebackground {SteelBlue2} \
	-background {LightGray} \
	-label {Source ...} \
	-command {load_source_cmd} \
	-underline {-1}

    $menu_name.mFile.m.mImport add command \
	-activebackground {SteelBlue2} \
	-background {LightGray} \
	-label {OE ...} \
	-command {load_oe_cmd} \
	-underline {-1}

    $menu_name.mFile.m.mImport add command \
	-activebackground {SteelBlue2} \
	-background {LightGray} \
	-label {System ...} \
	-command {load_system_cmd} \
	-underline {-1}

    # build cascade menu for importing/export shadow namelist files
    $menu_name.mFile.m add cascade \
	-menu "$menu_name.mFile.m.mExport" \
	-label {Export} \
	-underline {-1}

    # build widget $menu_name.mFile.m.mExport
    menu $menu_name.mFile.m.mExport \
	-background {LightGrey} \
	-foreground {black} \
	-tearoff 0

    $menu_name.mFile.m.mExport add command \
	-activebackground {SteelBlue2} \
	-background {LightGray} \
	-label {Source ...} \
	-command {save_source_cmd} \
	-underline {-1}

    $menu_name.mFile.m.mExport add command \
	-activebackground {SteelBlue2} \
	-background {LightGray} \
	-label {OE ...} \
	-command {save_oe_cmd} \
	-underline {-1}

    $menu_name.mFile.m.mExport add command \
	-activebackground {SteelBlue2} \
	-background {LightGray} \
	-label {System ...} \
	-command {save_system_cmd} \
	-underline {-1}

    $menu_name.mFile.m add separator

    $menu_name.mFile.m add command \
	-activebackground {SteelBlue2} \
	-background {LightGray} \
	-command {exit_cmd} \
	-label {Exit} \
	-underline {1} \
	-accelerator {Ctrl-x}

    lappend menu_names $menu_name.mEdit
    # build widget $menu_name.mEdit
    menubutton $menu_name.mEdit \
	-background {LightGray} \
	-foreground {black} \
	-menu "$menu_name.mEdit.m" \
	-text {Edit} \
	-underline {0}

    # build widget $menu_name.mEdit.m
    menu $menu_name.mEdit.m \
	-background {LightGrey} \
	-foreground {black} \
	-tearoff 0

    $menu_name.mEdit.m add command \
	-activebackground {SteelBlue2} \
	-background {LightGray} \
	-label {Copy Selected} \
	-command {copy_selected_cmd} \
	-underline {-1}

    $menu_name.mEdit.m add command \
	-activebackground {SteelBlue2} \
	-background {LightGray} \
	-label {Delete Selected} \
	-command {delete_selected_cmd} \
	-underline {-1}

    $menu_name.mEdit.m add command \
	-activebackground {SteelBlue2} \
	-background {LightGray} \
	-label {Paste Selected} \
	-command {paste_selected_cmd} \
	-underline {-1}

    $menu_name.mEdit.m add separator

    # build cascade menu for Adding objects
    $menu_name.mEdit.m add cascade \
	-menu "$menu_name.mEdit.m.mAdd" \
	-label {Add} \
	-underline {-1}

    # build widget $menu_name.mEdit.m.mAdd
    menu $menu_name.mEdit.m.mAdd \
	-background {LightGrey} \
	-foreground {black} \
	-tearoff 0

    $menu_name.mEdit.m.mAdd add command \
	-activebackground {SteelBlue2} \
	-background {LightGray} \
	-command {add_src_cmd} \
	-label {Source} \
	-underline {-1}

    $menu_name.mEdit.m.mAdd add command \
	-activebackground {SteelBlue2} \
	-background {LightGray} \
	-command {add_oe_cmd 1} \
	-label {OE...} \
	-underline {-1}

    $menu_name.mEdit.m.mAdd add command \
	-activebackground {SteelBlue2} \
	-background {LightGray} \
	-command {add_scr_cmd 1} \
	-label {Screen...} \
	-underline {-1}

    # build cascade menu for Deleting objects
    $menu_name.mEdit.m add cascade \
	-menu "$menu_name.mEdit.m.mParam" \
	-label {Parameters} \
	-underline {-1}

    # build widget $menu_name.mEdit.m.mParam
    menu $menu_name.mEdit.m.mParam \
	-background {LightGrey} \
	-foreground {black} \
	-tearoff 0

    $menu_name.mEdit.m.mParam add command \
	-activebackground {SteelBlue2} \
	-background {LightGray} \
	-label {Selected} \
	-command {edit_selected_cmd} \
	-underline {-1}

    $menu_name.mEdit.m.mParam add command \
	-activebackground {SteelBlue2} \
	-background {LightGray} \
	-label {Source} \
	-command {edit_src_cmd} \
	-underline {-1}

    $menu_name.mEdit.m.mParam add command \
	-activebackground {SteelBlue2} \
	-background {LightGray} \
	-label {OE...} \
	-command {edit_oe_cmd} \
	-underline {-1}

    $menu_name.mEdit.m.mParam add command \
	-activebackground {SteelBlue2} \
	-background {LightGray} \
	-label {Screen...} \
	-command {edit_scr_cmd} \
	-underline {-1}

    # build cascade menu for Deleting objects
    $menu_name.mEdit.m add cascade \
	-menu "$menu_name.mEdit.m.mDelete" \
	-label {Delete} \
	-underline {-1}

    # build cascaded menu for $menu_name.mDelete
    menu $menu_name.mEdit.m.mDelete \
	-background {LightGrey} \
	-foreground {black} \
	-tearoff 0

    $menu_name.mEdit.m.mDelete add command \
	-activebackground {SteelBlue2} \
	-background {LightGray} \
	-command {undo_deleted_cmd} \
	-label {Undo last} \
	-underline {-1}
    
    set gvars(undo_del_btn_config) "$menu_name.mEdit.m.mDelete entryconfigure 0"

    $menu_name.mEdit.m.mDelete add separator

    $menu_name.mEdit.m.mDelete add command \
	-activebackground {SteelBlue2} \
	-background {LightGray} \
	-command {delete_selected_cmd} \
	-label {Selected} \
	-underline {-1}

    $menu_name.mEdit.m.mDelete add command \
	-activebackground {SteelBlue2} \
	-background {LightGray} \
	-command {delete_src_cmd} \
	-label {Source} \
	-underline {-1}

    $menu_name.mEdit.m.mDelete add command \
	-activebackground {SteelBlue2} \
	-background {LightGray} \
	-command {delete_oe_cmd} \
	-label {OE...} \
	-underline {-1}

    $menu_name.mEdit.m.mDelete add command \
	-activebackground {SteelBlue2} \
	-background {LightGray} \
	-command {delete_all_oe_cmd} \
	-label {All OEs} \
	-underline {-1}

    $menu_name.mEdit.m.mDelete add command \
	-activebackground {SteelBlue2} \
	-background {LightGray} \
	-command {delete_scr_cmd} \
	-label {Screen...} \
	-underline {-1}

    lappend menu_names $menu_name.mRun
    # build widget $menu_name.mRun
    menubutton $menu_name.mRun \
	-background {LightGray} \
	-foreground {black} \
	-menu "$menu_name.mRun.m" \
	-text {Run} \
	-underline {0}

    # build widget $menu_name.mRun.m
    menu $menu_name.mRun.m \
	-background {LightGrey} \
	-foreground {black} \
	-tearoff 0

    $menu_name.mRun.m add command \
	-activebackground {SteelBlue2} \
	-background {LightGray} \
	-label {Selected} \
	-command {run_selected_cmd} \
	-underline {-1}

    $menu_name.mRun.m add command \
	-activebackground {SteelBlue2} \
	-background {LightGray} \
	-label {Source} \
	-command {run_source_cmd} \
	-underline {-1}

    $menu_name.mRun.m add command \
	-activebackground {SteelBlue2} \
	-background {LightGray} \
	-label {System} \
	-command {run_system_cmd} \
	-underline {-1}

    lappend menu_names $menu_name.mWorkspace
    # build widget $menu_name.mWorkspace
    menubutton $menu_name.mWorkspace \
	-background {LightGray} \
	-foreground {black} \
	-menu "$menu_name.mWorkspace.m" \
	-text {Workspace} \
	-underline {0}

    # build widget $menu_name.mWorkspace.m
    menu $menu_name.mWorkspace.m \
	-background {LightGrey} \
	-foreground {black} \
	-tearoff 0

    $menu_name.mWorkspace.m add command \
	-activebackground {SteelBlue2} \
	-background {LightGray} \
	-label {Annotate} \
	-command {annotate_workspace_cmd} \
	-underline {-1}

    $menu_name.mWorkspace.m add command \
	-activebackground {SteelBlue2} \
	-background {LightGray} \
	-label {Show Annotation} \
	-command {show_annotation_cmd} \
	-underline {-1}

    $menu_name.mWorkspace.m add command \
	-activebackground {SteelBlue2} \
	-background {LightGray} \
	-label {Show Info ...} \
	-command {show_workspace_info_cmd} \
	-underline {-1}

    lappend menu_names $menu_name.mTools
    # build widget $menu_name.mTools
    menubutton $menu_name.mTools \
	-background {LightGray} \
	-foreground {black} \
	-menu "$menu_name.mTools.m" \
	-text {Tools} \
	-underline {0}

    # build widget $menu_name.mTools.m
    menu $menu_name.mTools.m \
	-background {LightGrey} \
	-foreground {black} \
	-tearoff 0

    $menu_name.mTools.m add command \
	-activebackground {SteelBlue2} \
	-background {LightGray} \
	-label {Plot} \
	-command {plot_cmd} \
	-underline {-1}

    lappend menu_names $menu_name.mOptions
    # build widget $menu_name.mOptions
    menubutton $menu_name.mOptions \
	-background {LightGray} \
	-foreground {black} \
	-menu "$menu_name.mOptions.m" \
	-text {Options} \
	-underline {0}

    # build widget $menu_name.mOptions.m
    menu $menu_name.mOptions.m \
	-background {LightGrey} \
	-foreground {black} \
	-tearoff 0

    $menu_name.mOptions.m add checkbutton \
	-activebackground {SteelBlue2} \
	-background {LightGray} \
	-label {Verbose Mode} \
	-variable gvars(verbose) \
	-underline {-1}

    $menu_name.mOptions.m add command \
	-activebackground {SteelBlue2} \
	-background {LightGray} \
	-label {Change directory} \
	-command {chdir_cmd} \
	-underline {-1}

    $menu_name.mOptions.m add command \
	-activebackground {SteelBlue2} \
	-background {LightGray} \
	-label {Redraw Parameter Editor} \
	-command {redraw_current_page_cmd} \
	-underline {-1}

    $menu_name.mOptions.m add command \
	-activebackground {SteelBlue2} \
	-background {LightGray} \
	-label {Redraw Beamline Editor} \
	-command {redraw_editbar_cmd} \
	-underline {-1}

    $menu_name.mOptions.m add command \
	-activebackground {SteelBlue2} \
	-background {LightGray} \
	-label {Show Run Window} \
	-command {show_run_window_cmd} \
	-underline {-1}

    $menu_name.mOptions.m add command \
	-activebackground {SteelBlue2} \
	-background {LightGray} \
	-label {Clear clipboard} \
	-command {clear_clipboard_cmd} \
	-underline {-1}

    $menu_name.mOptions.m add command \
	-activebackground {SteelBlue2} \
	-background {LightGray} \
	-label {Clear Param Editor} \
	-command {edit_nothing} \
	-underline {-1}

    $menu_name.mOptions.m add separator

    $menu_name.mOptions.m add command \
	-activebackground {SteelBlue2} \
	-background {LightGray} \
	-label {Remember Current State} \
	-command {save_beamline_state_cmd} \
	-underline {-1}

    $menu_name.mOptions.m add command \
	-activebackground {SteelBlue2} \
	-background {LightGray} \
	-label {Restore Remembered State} \
	-command {restore_beamline_state_cmd} \
	-underline {-1}

    $menu_name.mOptions.m add separator

    # build cascade menu for Preferences
    $menu_name.mOptions.m add cascade \
	-menu "$menu_name.mOptions.m.mPreferences" \
	-label {Preferences} \
	-underline {-1}

    # build cascaded menu for $menu_name.mOptions.m.mPreferences
    menu $menu_name.mOptions.m.mPreferences \
	-background {LightGrey} \
	-foreground {black} \
	-tearoff 0

    $menu_name.mOptions.m.mPreferences add checkbutton \
	-activebackground {SteelBlue2} \
	-background {LightGray} \
	-label {Add SRC at Startup} \
	-variable gprefs(add_src_at_startup) \
	-underline {-1}

    $menu_name.mOptions.m.mPreferences add checkbutton \
	-activebackground {SteelBlue2} \
	-background {LightGray} \
	-label {Edit SRC at Startup} \
	-variable gprefs(edit_src_at_startup) \
	-underline {-1}

    $menu_name.mOptions.m.mPreferences add checkbutton \
	-activebackground {SteelBlue2} \
	-background {LightGray} \
	-label {Edit after adding} \
	-variable gprefs(edit_added_obj) \
	-underline {-1}

    $menu_name.mOptions.m.mPreferences add checkbutton \
	-activebackground {SteelBlue2} \
	-background {LightGray} \
	-label {Balloon Help} \
	-variable gprefs(balloon_help) \
	-command "balloon_help_cmd" \
	-underline {-1}

    $menu_name.mOptions.m.mPreferences add checkbutton \
	-activebackground {SteelBlue2} \
	-background {LightGray} \
	-label {Show Toolbar} \
	-variable gprefs(show_toolbar) \
	-command {show_toolbar_cmd} \
	-underline {-1}

    $menu_name.mOptions.m.mPreferences add checkbutton \
	-activebackground {SteelBlue2} \
	-background {LightGray} \
	-label {Message window at Bottom} \
	-variable gprefs(msg_window_at_bottom) \
	-command {show_msg_window_cmd} \
	-underline {-1}

    $menu_name.mOptions.m.mPreferences add checkbutton \
	-activebackground {SteelBlue2} \
	-background {LightGray} \
	-label {Show Command Window} \
	-variable gprefs(show_cmd_window) \
	-command {show_cmd_window_cmd} \
	-underline {-1}

    $menu_name.mOptions.m.mPreferences add checkbutton \
	-activebackground {SteelBlue2} \
	-background {LightGray} \
	-label {Cache menu pages} \
	-variable gprefs(cache_pages) \
	-state disabled \
	-underline {-1}
    
    $menu_name.mOptions.m.mPreferences add separator

    $menu_name.mOptions.m.mPreferences add command \
	-activebackground {SteelBlue2} \
	-background {LightGray} \
	-label {Reload preferences} \
	-command {load_prefs_cmd} \
	-underline {-1}

    $menu_name.mOptions.m.mPreferences add command \
	-activebackground {SteelBlue2} \
	-background {LightGray} \
	-label {Save preferences} \
	-command {save_prefs_cmd} \
	-underline {-1}

    $menu_name.mOptions.m.mPreferences add command \
	-activebackground {SteelBlue2} \
	-background {LightGray} \
	-label {Reset to defaults} \
	-command {reset_prefs_cmd} \
	-underline {-1}

    lappend menu_names $menu_name.mHelp
    # build widget $menu_name.mHelp
    menubutton $menu_name.mHelp \
	-background {LightGray} \
	-foreground {black} \
	-menu "$menu_name.mHelp.m" \
	-text {Help} \
	-underline {0}

    # build widget $menu_name.mHelp.m
    menu $menu_name.mHelp.m \
	-background {LightGrey} \
	-foreground {black} \
	-tearoff 0

    $menu_name.mHelp.m add command \
	-activebackground {SteelBlue2} \
	-background {LightGray} \
	-command {about_cmd} \
	-label {About} \
	-underline {0}

    $menu_name.mHelp.m add command \
	-activebackground {SteelBlue2} \
	-background {LightGray} \
	-command {about_author_cmd} \
	-label {Author} \
	-underline {0}

    $menu_name.mHelp.m add command \
	-activebackground {SteelBlue2} \
	-background {LightGray} \
	-command {help_on_topmenu_cmd} \
	-label {On Menubar} \
	-underline {0}

    $menu_name.mHelp.m add separator

    # build cascade menu for Preferences
    $menu_name.mHelp.m add cascade \
	-menu "$menu_name.mHelp.m.mDemo" \
	-label {Demos} \
	-underline {-1}

    # build cascaded menu for $menu_name.mHelp.m.mDemo
    menu $menu_name.mHelp.m.mDemo \
	-background {LightGrey} \
	-foreground {black} \
	-tearoff 0

    $menu_name.mHelp.m.mDemo add command \
	-activebackground {SteelBlue2} \
	-background {LightGray} \
	-command {run_demo_cmd toroid.ws} \
	-label {Toroidal Mirror} \
	-underline {7}

    # pack widget $menu_name
    pack append $menu_name \
	$menu_name.mFile {left frame center} \
	$menu_name.mEdit {left frame center} \
	$menu_name.mRun {left frame center} \
	$menu_name.mWorkspace {left frame center} \
	$menu_name.mTools {left frame center} \
	$menu_name.mOptions {left frame center} \
	$menu_name.mHelp {right frame center}

    eval tk_menuBar $menu_name $menu_names
    focus $menu_name

    #
    # install the global bindings (accelerators).
    #
    bind all <Control-x>	"exit_cmd"
    bind Entry <Control-x>	"exit_cmd"
    bind Text <Control-x>	"exit_cmd"

    return $menu_name
}

#
# FIXME/TODO: The following doesn't work for cascaded menu items, so I had 
# to add "catch". Why?
#
proc GUI:set_undo_del_btn_state {state} {
    global gvars
    catch "eval $gvars(undo_del_btn_config) -state $state"
}

#----------------------------------------------------------------------#
# Make the Tcl command window for direct manipulation
#----------------------------------------------------------------------#

proc GUI:make_cmd_window {vname} {
    global gvars
    frame $vname -class XMenuCommand -bd 2 
    label $vname.label -text "Ready:: "
    entry $vname.entry -relief sunken
    bind $vname.entry <Return> {exec_tcl_command %W}
    bind $vname.entry <Any-question> "command_help %W $gvars(cmdhelpfile)"
    pack $vname.label -side left -anchor w -expand 0 
    pack $vname.entry -side left -anchor w -expand 1 -fill x
    return $vname
}

#----------------------------------------------------------------------#
# Make the menu page viewer/editor and return the frame
#----------------------------------------------------------------------#

proc GUI:make_page_viewer {vname} {
    global gvars gprefs
    tixScrolledWindow $vname \
        -width $gvars(page_w_wt) -height $gvars(page_w_ht) \
	-relief sunken -bd 2 \
	-expand 1 ;#-scrollbar both
    bind $vname <Enter> {
        set_msg "Parameter Editor: Enter `?' in any field for help"
    }
    bind $vname <Leave> {reset_msg}
    return $vname
}

#
# make the popup menu for MENU PAGE stuff. Binding is done outside on the
# client side of course.
#
proc GUI:make_page_popup {vname} {
    global gvars
    #
    # make the popup menu. It automatically binds to <3> in the hlist.
    #

    set popup [tixPopupMenu $vname -title "Parameter Editor"]

    # Set the entries inside the PopupMenu widget.
    # [Hint] You have to manipulate the "menu" subwidget.
    #        $popup itself is NOT a menu widget.
    # [Hint] Watch carefully how the sub-menu is created
    #
    set menu [$popup subwidget menu]
    $menu add command -label "Back" -command pop_page_stack2
    $menu add separator
    $menu add command -label "Load ..." -state disabled
    $menu add command -label "Save ..." -state disabled 
    $menu add separator
    $menu add command -label Help -state disabled

    return $vname
}

#----------------------------------------------------------------------#
# Make the startup window (cutesy thing)
#----------------------------------------------------------------------#

set gvars(startup_w) ".startup"

proc GUI:set_startup_msg {{msg ""}} {
    global gvars
    set msg_w $gvars(startup_w).msg
    $msg_w configure -text $msg
    update idletasks
}

proc GUI:make_startup {} {
    global gvars

    set top [toplevel $gvars(startup_w) -class Startup]
    wm transient $top .
    #wm overrideredirect $top 1
    wm withdraw $top

    # load the SHADOW banner if needed.
    if {$gvars(shadow_image) == ""} {
	set image [image create photo]
	global tcl_version
	if {$tcl_version >= 7.5} {
	    set imagefile [file join $gvars(shadow_tcl_library) \
	        bitmaps shadow.gif]
	} else {
	    # NON-PORTABLE-HACK. WILL NOT WORK ON MACs.
	    set imagefile $gvars(shadow_tcl_library)/bitmaps/shadow.gif
	}
	if [catch "$image read $imagefile" msg] {
	    puts stderr "Warning: Cannot find SHADOW image ($msg)"
	} else {
	    set gvars(shadow_image) $image
	}
    }

    set blurb [label $top.blurb \
        -text "Please wait while Loading SHADOW ..."]
    set image [label ${top}.img -anchor center -image $gvars(shadow_image)]
    set msg [label $top.msg -text ""]

    grid $blurb -row 0 -column 0 -sticky news -ipadx 5 -ipady 5
    grid $image -row 1 -column 0 -sticky news -ipadx 20 -ipady 20
    grid $msg -row 2 -column 0 -sticky news -ipadx 5 -ipady 5
    grid columnconfigure $top 0 -weight 1

    update idletasks
    set x [expr [winfo screenwidth $top]/2 - [winfo reqwidth $top]/2 \
            - [winfo vrootx [winfo parent $top]]]
    set y [expr [winfo screenheight $top]/2 - [winfo reqheight $top]/2 \
            - [winfo vrooty [winfo parent $top]]]
    wm geom $top [winfo reqwidth $top]x[winfo reqheight $top]+$x+$y

    wm deiconify $top
    wm title $top "SHADOW GUI v1.1.0"
    update

    return $top
}

#----------------------------------------------------------------------#
# Make the menu page edit tool bar
#----------------------------------------------------------------------#

proc GUI:make_editbar {vname} {
    global gvars
    set initial_toolbox {
	{System header disabled {beamline}}
    }

    frame $vname -class XMenuEditBar
    set editbar [ \
        editbar:make $vname $initial_toolbox editbar_callback \
	editbar_select_callback]
    pack $editbar -side top -fill both -expand yes
    #
    # do not use balloons yet, since there is no way of turning off
    # the balloon and keep only the status message. Use <Enter> and
    # <Leave> instead.
    #
    #	$gvars(balloon) bind $editbar \
    #	    -statusmsg "Editor:: Click on SHADOW element to edit parameters"
    #	    -balloonmsg "Select element to edit" 
    #
    bind $editbar <Enter> {
        set_msg "System: Single click selects, Double Click edit parameters"
    }
    bind $editbar <Leave> {reset_msg}
    return $vname
}

#
# make the popup menu for BEAMLINE stuff. Binding is done outside on the
# client side of course.
#
proc GUI:make_beamline_popup {vname} {
    global gvars
    #
    # make the popup menu. It automatically binds to <3> in the hlist.
    #

    #
    # do we want the spring option turned on or off? Dunno right now.
    #
    set popup [tixPopupMenu $vname -title "Commands" -spring 1]

    # Set the entries inside the PopupMenu widget.
    # [Hint] You have to manipulate the "menu" subwidget.
    #        $popup itself is NOT a menu widget.
    # [Hint] Watch carefully how the sub-menu is created
    #
    set menu [$popup subwidget menu]
    $menu add command -label "Edit Selected" -command edit_selected_cmd
    $menu add command -label "Copy Selected" -command copy_selected_cmd
    $menu add command -label "Cut Selected" -command delete_selected_cmd
    $menu add command -label "Paste Selected" -command paste_selected_cmd
    $menu add separator
    $menu add command -label "Run Selected" -command run_selected_cmd
    $menu add command -label "Annotate Selected" -command rename_selected_cmd \
	-state disabled
    $menu add separator
    $menu add command -label "Load Workspace ..." -command load_state_cmd
    $menu add command -label "Save Workspace ..." -command save_state_cmd
    $menu add separator
    $menu add command -label Help \
        -command {set_msg "No HELP available yet."} \
	-state disabled

    return $vname
}

#----------------------------------------------------------------------#
# Make the message command 
#----------------------------------------------------------------------#

proc GUI:make_msg_window {vname} {
    global gvars
    frame $vname -class XMenuMessage -bd 2
    frame $vname.top

    label $vname.top.label -text "Info:: "
    label $vname.top.msg -width 55 -relief sunken -bd 2 
    set gvars(statusbar) $vname.top.msg
    pack $vname.top.label -side left -anchor w -expand 0 
    pack $vname.top.msg -side left -anchor w -expand 0 -fill x

    label $vname.top.label2 -text "Selection:: "
    label $vname.top.msg2 -width 25 -relief sunken -bd 2 -text "None"
    set gvars(cur_selectbar) $vname.top.msg2
    pack $vname.top.label2 -side left -anchor w -expand 0 
    pack $vname.top.msg2 -side left -anchor w -expand 0 -fill x

    label $vname.top.label3 -text "Edit:: "
    label $vname.top.msg3 -width 25 -relief sunken -bd 3 -text "None"
    set gvars(cur_editbar) $vname.top.msg3
    pack $vname.top.label3 -side left -anchor w -expand 0 
    pack $vname.top.msg3 -side left -anchor w -expand 0 -fill x

    pack $vname.top -side top -expand 1 -fill x

    frame $vname.bottom 

    label $vname.bottom.label1 -text "Current directory:: "
    label $vname.bottom.msg1 -width 55 -relief sunken -bd 2 
    set gvars(cur_directory) $vname.bottom.msg1
    pack $vname.bottom.label1 -side left -anchor w -expand 0 
    pack $vname.bottom.msg1 -side left -anchor w -expand 0 -fill x

    button $vname.bottom.btn1 -text "ChDir" -command chdir_cmd
    pack $vname.bottom.btn1 -side left -anchor w 

    label $vname.bottom.label2 -text "Clipboard:: "
    label $vname.bottom.msg2 -width 20 -relief sunken -bd 2 
    set gvars(clipboard_w) $vname.bottom.msg2
    pack $vname.bottom.label2 -side left -anchor w -expand 0 
    pack $vname.bottom.msg2 -side left -anchor w -expand 0 -fill x

    pack $vname.bottom -side bottom -expand 1 -fill x

    return $vname
}

#----------------------------------------------------------------------#
# Make the toolbox
#----------------------------------------------------------------------#

proc toolbox_callback {args} {
    global gvars
    vputs "toolbox_callback_args: $args"
    set tool_type [lindex $args 0]
    switch -exact $tool_type {
        beamline {
	    if {[llength $args] == 1} {
		show_about_page
	    } else {
	        add_tool [lindex $args 1]
	    }
	}
        inspector {
	    if {[llength $args] == 1} {
		show_about_page
	    } else {
	        add_inspector [lindex $args 1] [lrange $args 2 end]
	    }
	}
	ray_trace {
	    set trace_what [lindex $args 1]
	    switch -exact -- $trace_what {
	        source {
		    run_source_cmd
		}
		system {
		    run_system_cmd
		}
		default {
		    set_msg "Running $trace_what not implemented yet"
		}
	    }
	}
	default {
	    set_msg "ITEM $tool_type not implemented yet"
	}
    }
}

#
# GUI:make_toolbox: Make the SHADOW toolbox, which contains all the models,
# inspection tools and other utilities.
#
proc GUI:make_toolbox {vname} {
    global gvars
    set toolbox_tools {
	{System folder header enabled {beamline}}
	{System.Source file entry enabled {beamline source}}
	{System.OE file entry enabled {beamline oe}}
	{System.OE.Screen file entry enabled {beamline screen}}
	{Ray_Trace folder header disabled {ray_trace}}
	{Ray_Trace.Source file entry enabled {ray_trace source}}
	{Ray_Trace.System file entry enabled {ray_trace system}}
	{Inspector folder header disabled {inspector}}
	{Inspector.General folder header disabled {inspector general}}
	{Inspector.General.Plot file entry enabled {inspector plotxy}}
	{Inspector.General.MinMax file entry enabled {inspector minmax}}
	{Inspector.Source folder header disabled {inspector source}}
	{Inspector.Source.SRCInfo file entry enabled {inspector srcinfo}}
	{Inspector.OE folder header disabled {inspector oe}}
	{Inspector.OE.MirInfo file entry enabled {inspector mirinfo}}
    }

    frame $vname -class XMenuToolBox ;#-relief sunken -bd 2
    set toolbox [toolbox:make $vname $toolbox_tools toolbox_callback]
    pack $toolbox -side top -fill both -expand yes
    #
    # do not use balloons yet, since there is no way of turning off
    # the balloon and keep only the status message. Use <Enter> and
    # <Leave> instead.
    #
    #$gvars(balloon) bind $toolbox \
    #	-statusmsg "Toolbox: Click on element to add to beamline" \
    #	-balloonmsg "Select element to add"
    bind $toolbox <Enter> {
        set_msg "Toolbox: Click on element to add to System"
    }
    bind $toolbox <Leave> {
        reset_msg
    }
    return $vname
}

#----------------------------------------------------------------------#
# misc utils
#----------------------------------------------------------------------#

proc GUI:add_file_to_title {file} {
    global gvars
    if {$file == ""} {
	set filepart "\[No filename\]"
    } else {
	set filepart "\[$file\]"
    }
    wm title . "$gvars(win_title)   $filepart"
}

#----------------------------------------------------------------------#
# Make the top toolbar 
#----------------------------------------------------------------------#


proc GUI:make_toolbar {vname} {
    global gvars
    set toolbar {
	{"" dirleft enabled exit_cmd {
	    "Exit application" "Click to Exit SHADOW"}}
	{Load openfile enabled {load_state_cmd} {
	    "Load Workspace" "Load the entire GUI state from file"}}
	{Save openfile enabled {save_state_cmd} {
	    "Save Workspace" "Save the entire GUI state to file"}}
	{"Edit" "" enabled {edit_selected_cmd} {
	    "Edit selected tool" "Edit currently selected tool in System"}}
	{"Cut" scissors enabled {delete_selected_cmd} {
	    "Cut selected tool" "Cut currently selected tool in System"}}
	{"Source" "" enabled {run_source_cmd} {
	    "Generate Source" "Generate the Source"}}
	{"Trace" "" enabled {run_system_cmd} {
	    "Trace system" "Trace the system"}}
	{"" run2 enabled {run_selected_cmd} {
	    "Run selected" "Run the selected item"}}
	{"Plot" "" enabled {plot_cmd} {
	    "Plot" "Plot SHADOW data"}}
	{"" help4 enabled {set_msg "NOT IMPLEMENTED YET"} {
	    "Help on selected" "Get help on the selected element/tool"}}
    }

    set toolbar [toolbar:make $vname $toolbar $gvars(balloon) 0]
    return $vname
}


#
# initialize the  UI
#
proc GUI:make {} {
    global gvars gprefs env

    global tcl_version
    if {$tcl_version >= 7.5} {
	tix addbitmap [file join $gvars(shadow_tcl_library) bitmaps]
    } else {
	# NON-PORTABLE-HACK. WILL NOT WORK ON MACs.
	tix addbitmap $gvars(shadow_tcl_library)/bitmaps
    }

    #
    # create the TixBalloon widget first.
    #
    set gvars(balloon) [tixBalloon .balloon]

    frame .top -bg lightgrey -relief sunken
    set topmenu [GUI:make_topmenu .top.topmenu]
    set gvars(toolbar_w_stub) .top.toolbar_w_stub
    frame $gvars(toolbar_w_stub)
    set gvars(toolbar) [GUI:make_toolbar .top.toolbar]
    set gvars(cmd_w_stub) .top.tcl_cmd_w_stub
    frame $gvars(cmd_w_stub)
    set gvars(msg_w_top_stub) .top.msg_w_top_stub
    frame $gvars(msg_w_top_stub)
    set gvars(cmd_w) [GUI:make_cmd_window .top.tcl_cmd_w]
    frame .top.body
    set gvars(page_w) [GUI:make_page_viewer .top.body.page]
    set gvars(msg_w_bot_stub) .top.msg_w_bot_stub
    frame $gvars(msg_w_bot_stub)
    set gvars(msg_w) [GUI:make_msg_window .top.msg]

    frame .top.body.toolbox -relief sunken -bd 2
    set gvars(tools_w) [GUI:make_toolbox .top.body.toolbox.tools]
    set downframe [frame .top.body.toolbox.downframe]
    set downimage [label $downframe.img -image [tix getimage down2]]
    pack $downimage -expand 0
    set gvars(editbar) [GUI:make_editbar .top.body.toolbox.editbar]


    # Window manager configurations
    wm positionfrom . user
    wm sizefrom . ""
    # uncomment the following line to make the interface resizable
    # (at your own risk) by the user via the window manager.
    #
    # wm minsize . $gvars(page_w_wt) $gvars(page_w_ht)
    # wm maxsize . [winfo screenwidth .] [winfo screenheight .]
    #
    wm title . $gvars(win_title)
    wm protocol . WM_DELETE_WINDOW exit_cmd
    wm protocol . WM_SAVE_YOURSELF exit_cmd

    $gvars(balloon) configure -statusbar $gvars(statusbar)

    # now pack the whole UI
    pack $topmenu -side top -expand 1 -fill x
    pack $gvars(toolbar_w_stub) -side top -expand 1 -fill x
    pack $gvars(cmd_w_stub) -side top -expand 1 -fill x
    pack $gvars(msg_w_top_stub) -side top -expand 1 -fill x
    pack .top.body -side top -expand 1 -fill both -anchor center 
    pack $gvars(tools_w) -side top -expand 1 -fill both -padx 0 -pady 0 \
        -anchor center 
    pack $downframe -side top -expand 0 -fill y -padx 0 -pady 0 -anchor center
    pack $gvars(editbar) -side bottom -expand 1 -fill both -padx 0 -pady 0 \
        -anchor center 
    pack .top.body.toolbox -side left -expand 1 -fill both -anchor center \
	-padx 4 -pady 4 -ipadx 2 -ipady 2
    pack $gvars(page_w) -side left -expand 1 -fill both -anchor center \
	-padx 4 -pady 4 -ipadx 2 -ipady 2
    pack $gvars(msg_w_bot_stub) -side top -expand 1 -fill x

    # make the various popup menus for various areas in the GUI.

    set gvars(beamline_popup) [GUI:make_beamline_popup .top.bl_popup]

    #
    # I want the Beamline popup to appear in all widgets, and using
    # the TixPopupMenu:bind doesn't allow "all", so hence the horrible
    # hack. Also notice the root correction that TixPopupMenu needs,
    # otherwise the menu is popped up in the wrong place for some reason.
    #
    # Also make sure that the binding does NOT apply to other "foreign"
    # toplevels such as SHADOW Plotting utilities and such.
    #
    bind all <3> {+
	if {[winfo toplevel %W] == "."} {
	$gvars(beamline_popup) post %W \
	    [expr %X - [winfo rootx %W]] \
	    [expr %Y - [winfo rooty %W]]}
    }

    #
    # The parameter editor popup is bound every time a page is created.
    #
    set gvars(page_popup) [GUI:make_page_popup .top.pg_popup]

    #
    # HACK. This should be done better. Also, the following should be
    # set gvars(page_w) [$gvars(page_w) subwidget window].w
    # (Note the trailing .w). This for some reasons works around the
    # weird flicker problem when new pages would be up.
    #
    set gvars(page_w) [$gvars(page_w) subwidget window]
    #
    # END HACK
    #

    #
    # done building. Now pack the sucker.
    #

    pack .top -expand 1 -fill both

    # now pack the configurable windows
    show_toolbar_cmd
    show_cmd_window_cmd
    show_msg_window_cmd

    disable_undo_delete_cmd

    # focus default $topmenu
    focus $topmenu
}

