# window-manager.tcl --
#
#

namespace eval NSWindowManager {

variable Priv

# NSWindowManager::RegisterWindow --
#
#	Introduce a toplevel to the NSWindowManager.
#
# Arguments:
#	arg1					about arg1
#
# Results:
#	What happened.

proc RegisterWindow {winName window geomCmd setupCmd displayCmd} {

	variable Priv

#	if {[info exists Priv($winName,window)]} return
	set Priv($winName,win) $window
	set Priv($winName,geomCmd) $geomCmd
	set Priv($winName,displayCmd) $displayCmd
	set Priv($winName,setupCmd) $setupCmd
	if {![info exists Priv($winName,geomRequest)]} {
		set Priv($winName,geomRequest) ""
	}
	set Priv($winName,first) 1
	set Priv($winName,setup) 0
}

# NSWindowManager::UnregisterWindow --
#
#	Forget about a toplevel registered with the NSWindowManager.
#
# Arguments:
#	arg1					about arg1
#
# Results:
#	What happened.

proc UnregisterWindow {winName} {

	variable Priv
	
	foreach name [array names Priv "*,win"] {
		unset Priv($name)
	}
}

# NSWindowManager::RequestGeometry --
#
#	Request geometry for a toplevel. The toplevel might not even exist
#	yet, and in any case nothing interesting happens. Only when
#	Setup() is called for the first time will the geometry passed to
#	this command be used.
#
# Arguments:
#	arg1					about arg1
#
# Results:
#	What happened.

proc RequestGeometry {winName geometry} {

	variable Priv

	set Priv($winName,geomRequest) $geometry
}

# NSWindowManager::Setup --
#
#	Display the toplevel offscreen. Then set the toplevel geometry
#	and withdraw the window.
#
# Arguments:
#	arg1					about arg1
#
# Results:
#	What happened.

proc Setup winName {

	variable Priv

	if $Priv($winName,setup) return

	NSToplevel::NaturalSize $Priv($winName,win) $Priv($winName,setupCmd)

	set geometry $Priv($winName,geomRequest)
	if {[string length $geometry]} {
	} else {
		set geometry [uplevel #0 $Priv($winName,geomCmd)]
	}
	scan $geometry "%dx%d+%d+%d" width height x y
	wm geometry $Priv($winName,win) ${width}x$height
	update

	wm geometry $Priv($winName,win) +$x+$y
	wm withdraw $Priv($winName,win)
	update

	set Priv($winName,setup) 1
}

# NSWindowManager::Arrange --
#
#	Set the desired geometry for the toplevel.
#
# Arguments:
#	arg1					about arg1
#
# Results:
#	What happened.

proc Arrange winName {

	variable Priv

	# Check for exists, because I want to clear any scheduled
	# geometry request below.
	if {[info exists Priv($winName,win)]} {
		set geometry [uplevel #0 $Priv($winName,geomCmd)]
		wm geometry $Priv($winName,win) $geometry
		update idletasks
	}
	
	# Hack -- Clear any geometry request
	set Priv($winName,geomRequest) ""
}

# NSWindowManager::Display --
#
#	Call Setup() to update the toplevel geometry if needed. Call
#	the displayCmd if provided, show the toplevel, then call the
#	displayCmd again.
#
# Arguments:
#	arg1					about arg1
#
# Results:
#	What happened.

proc Display {winName args} {

	variable Priv

	Setup $winName

	set displayCmd $Priv($winName,displayCmd)

	if {[wm state $Priv($winName,win)] == "normal"} {

		if {[string length $displayCmd]} {
			uplevel #0 $displayCmd reDisplay 0 $args
		}
		
	} else {
	
		if {[string length $displayCmd]} {
			uplevel #0 $displayCmd preDisplay $Priv($winName,first) $args
		}
	
		WindowBringToFront $Priv($winName,win)
		update
	
		if {[string length $displayCmd]} {
			uplevel #0 $displayCmd postDisplay $Priv($winName,first) $args
		}
		
		set Priv($winName,first) 0
	}
}

# NSWindowManager::Undisplay --
#
#	Remove a window from the screen.
#
# Arguments:
#	arg1					about arg1
#
# Results:
#	What happened.

proc Undisplay {winName args} {

	variable Priv

	set displayCmd $Priv($winName,displayCmd)
	if {[string length $displayCmd]} {
		uplevel #0 $displayCmd preWithdraw 0 $args
	}

	wm withdraw $Priv($winName,win)
	update
	
	if {[string length $displayCmd]} {
		uplevel #0 $displayCmd postWithdraw 0 $args
	}
}

# NSWindowManager::GetWindowList --
#
#	Set the desired geometry for the toplevel.
#
# Arguments:
#	arg1					about arg1
#
# Results:
#	What happened.

proc GetWindowList {} {

	variable Priv

	set result {}
	foreach name [array names Priv "*,win"] {
		regexp "(.*),win" $name ignore window
		lappend result $window
	}
	return $result
}

# namespace eval NSWindowManager
}
