# toplevel.tcl --
#
#	Commands for manipulating toplevel windows. There is so much 
#	tomfoolery with positioning and resizing toplevels.
#

namespace eval NSToplevel {

variable ToplevelPriv

# NSToplevel::MoveOffscreen --
#
#	Move a window offscreen.
#
# Arguments:
#	arg1					about arg1
#
# Results:
#	What happened.

proc MoveOffscreen toplevel {

	variable ToplevelPriv

	set ToplevelPriv(save,focus) [focus]
	set ToplevelPriv(save,state) [wm state $toplevel]
	set ToplevelPriv(save,x) [winfo x $toplevel]
	set ToplevelPriv(save,y) [winfo y $toplevel]

	wm withdraw $toplevel
	update idletasks

	wm geometry $toplevel +[winfo screenwidth $toplevel]+0
	update idletasks

	wm deiconify $toplevel
	update idletasks
}

# NSToplevel::Restore --
#
#	Put a toplevel back to how it was before it was moved offscreen.
#
# Arguments:
#	arg1					about arg1
#
# Results:
#	What happened.

proc Restore toplevel {

	variable ToplevelPriv

	set state $ToplevelPriv(save,state)

	if {$state == "withdrawn"} {
		wm withdraw $toplevel

	} elseif {$state == "iconic"} {
		wm iconify $toplevel
	}
	update idletasks

#	wm geometry $toplevel +$ToplevelPriv(save,x)+$ToplevelPriv(save,y)
#	update idletasks

	focus $ToplevelPriv(save,focus)
}

# NSToplevel::WidthLeft --
#
#	Return width of frame at left of a window. It is assumed that this is
#	also the width at the right and bottom of the frame.
#
# Arguments:
#	arg1					about arg1
#
# Results:
#	What happened.

proc WidthLeft toplevel {
	return [expr [winfo rootx $toplevel] - [winfo x $toplevel]]
}

# NSToplevel::WidthTop --
#
#	Return the width of frame (and menubar) at the top of a window.
#
# Arguments:
#	arg1					about arg1
#
# Results:
#	What happened.

proc WidthTop toplevel {
	return [expr [winfo rooty $toplevel] - [winfo y $toplevel]]
}

# NSToplevel::EdgeRight --
#
#	Return the pixel-coordinate of pixel to the right of the right edge of a
#	window's frame.
#
# Arguments:
#	arg1					about arg1
#
# Results:
#	What happened.

proc EdgeRight toplevel {
	return [expr [winfo rootx $toplevel] + [winfo width $toplevel] + [WidthLeft $toplevel]]
}

# NSToplevel::EdgeBottom --
#
#	Return the pixel-coordinate of pixel below the bottom edge of a
#	window's frame.
#
# Arguments:
#	arg1					about arg1
#
# Results:
#	What happened.

proc EdgeBottom toplevel {
	return [expr [winfo rooty $toplevel] + [winfo height $toplevel] + [WidthLeft $toplevel]]
}

# NSToplevel::ContentWidth --
#
#	Return the content width required so that a toplevel will be
#	exactly as wide as the given width, from left edge to right
#	edge.
#
# Arguments:
#	arg1					about arg1
#
# Results:
#	What happened.

proc ContentWidth {toplevel width} {

	set frameLeft [WidthLeft $toplevel]
	return [expr $width - $frameLeft * 2]
}

# NSToplevel::ContentHeight --
#
#	Return the content height required so that a toplevel will be
#	exactly as tall as the given height, from top edge to bottom
#	edge.
#
# Arguments:
#	arg1					about arg1
#
# Results:
#	What happened.

proc ContentHeight {toplevel height} {

	set frameTop [WidthTop $toplevel]
	set frameBottom [WidthLeft $toplevel]
	return [expr $height - $frameTop - $frameBottom]
}

# NSToplevel::NaturalSize --
#
#	Withdraws the given toplevel, moves it offscreen, then shows it
#	again. At this point the geometry info is all correct, and the
#	caller can then confidently use the geometry info to set lists
#	etc.
#
# Arguments:
#	arg1					about arg1
#
# Results:
#	What happened.

proc NaturalSize {toplevel command} {

	# Withdraw the toplevel
	wm withdraw $toplevel
	update idletasks

	# Move the toplevel offscreen
	wm geometry $toplevel +[winfo screenwidth $toplevel]+0
	update idletasks

	# Show the toplevel
	wm deiconify $toplevel
	update idletasks

	# Now that the window is displayed, the geometry information
	# is all correct. Call the client command to fiddle with the
	# geometry of any widgets.
	if {[string length $command]} {
		uplevel #0 eval $command
	}

	# Just to club it over the head...
	update
}

# namespace eval NSToplevel
}
