
#-------------------------------------------------------
# Miscellanous procedures:
#-------------------------------------------------------

proc tkerror err {
    global errorInfo
    puts stdout "$errorInfo\n"
}

# Position a dialog box at a reasonable place on the screen.

proc dpos w {
    wm geometry $w +200+200
#    wm positionfrom $w user
}

# Create a dialog box.  Takes three or more arguments.  The first is
# the name of the window to use for the dialog box.  The second is a set
# of arguments for use in creating the message of the dialog box.  The
# third and following arguments consist of two-element lists, each
# describing one button.  The first element gives the text to be displayed
# in the button, the second gives the command to be invoked when the
# button is invoked.

proc mkDialog {w msgArgs args} {
    catch {destroy $w}
    toplevel $w -class Dialog

    # Create two frames in the main window. The top frame will hold the
    # message and the bottom one will hold the buttons.  Arrange them
    # one above the other, with any extra vertical space split between
    # them.

    frame $w.top -relief raised -border 1
    frame $w.bot -relief raised -border 1
    pack append $w $w.top {top fill expand} $w.bot {top fill expand}

    # Create the message widget and arrange for it to be centered in the
    # top frame.

    eval message $w.top.msg -justify center \
	    -font -*-times-medium-r-normal--*-180* $msgArgs
    pack append $w.top $w.top.msg {top expand padx 5 pady 5}

    # Create as many buttons as needed and arrange them from left to right
    # in the bottom frame.  Embed the left button in an additional sunken
    # frame to indicate that it is the default button, and arrange for that
    # button to be invoked as the default action for clicks and returns in
    # the dialog.

    if {[length $args] > 0} {
	set arg [index $args 0]
	frame $w.bot.0 -relief sunken -border 1
	pack append $w.bot $w.bot.0 {left expand padx 20 pady 20}
	button $w.bot.0.button -text [index $arg 0] \
		-command "[index $arg 1]; destroy $w"
	pack append $w.bot.0 $w.bot.0.button {expand padx 12 pady 12}
	bind $w.top <Enter> "$w.bot.0.button activate"
	bind $w.top.msg <Enter> "$w.bot.0.button activate"
	bind $w.bot <Enter> "$w.bot.0.button activate"
	bind $w.top <Leave> "$w.bot.0.button deactivate"
	bind $w.top.msg <Leave> "$w.bot.0.button deactivate"
	bind $w.bot <Leave> "$w.bot.0.button deactivate"
	bind $w <1> "$w.bot.0.button config -relief sunken"
	bind $w <ButtonRelease-1> \
		"[index $arg 1]; $w.bot.0.button deactivate; destroy $w"
	bind $w <Return> "[index $arg 1]; destroy $w"
	focus $w

	set i 1
	foreach arg [range $args 1 end] {
	    button $w.bot.$i -text [index $arg 0] \
		    -command "[index $arg 1]; destroy $w"
	    pack append $w.bot $w.bot.$i {left expand padx 20}
	    set i [expr $i+1]
	}
    }
}

# Procedure to display the values of one or more variables using a
# dialog box:

proc showVars {w args} {
    set msg "Variable values:\n"
    foreach i $args {
	set msg "$msg\n$i = [uplevel #0 set $i]"
    }
    mkDialog $w "-text {$msg} -justify left" "OK {}"
}

# Procedure to set the width of a frame widget (used by scale demos):

proc setWidth {w width} {
    $w config -geometry ${width}x40
}

# Procedure to set the height of a frame widget (used by scale demos):

proc setHeight {w height} {
    $w config -geometry 40x${height}
}


# parray:
# Print the contents of a global array on stdout.
#

proc parray __a {
    global $__a
    set maxl 0
    foreach name [lsort [array names $__a]] {
	if {[string length $name] > $maxl} {
	    set maxl [string length $name]
	}
    }
    set maxl [expr {$maxl + [string length $__a] + 2}]
    foreach name [lsort [array names $__a]] {
	set nameString [format %s(%s) $__a $name]
	puts stdout [format "%-*s = %s" $maxl $nameString [set ${__a}($name)]]
    }
}



proc selection.get {} {if {[catch {selection get} s]} {return ""} {return $s}}



proc view2cursor { win} {
 set left_extent [$win index @0]
 set right_extent [$win index @[winfo width $win]]
 set cursor_position [$win index cursor]
 set entry_length [expr "$right_extent - $left_extent"]
 if {$cursor_position > $left_extent} {
    if {$cursor_position > $right_extent} {
        #handle cursor too far to the right
        $win view [expr "$cursor_position - $entry_length + 1"]
        }
    } {
        #handle cursor too far to the left
        $win view [expr "$cursor_position - 1"]
    }
}




proc selection.valid {} {expr "! [catch {selection get}]"}



proc bs { win} {
    set x [expr {[$win index cursor] - 1}]
    if {$x != -1} {$win delete $x}
    view2cursor $win
}



proc rpl { win} {
 set x [selection.get]
 $win delete 0 end;
 $win insert cursor $x
}

proc beep { args} {
   puts stderr "\007" nonewline
}


