/////////////////////////////////////////////////////////////////////////////
//
// Gladiator Components
//
// http://www.gladiatorweb.com
//
// (c) 2006 by Edward H. Trager .  All Rights Reserved
//
// NAME: gladiatorWindows.js
//
// DESCRIPTION: Implements window components.
//
// AUTHOR: Edward H. Trager
//
// LAST UPDATE: 2006.03.08
//
// NOTE: SEE "LICENSE" FILE FOR LICENSING TERMS
//
//////////////////////////////////////////////////////////////////////////////

//
// DEPENDENCY CHECKING:
//
if(typeof GLADIATOR_CORE_INCLUDED == 'undefined') alert('NOTE BENE: "gladiatorWindows.js" REQUIRES "gladiatorCore.js"!');

var GLADIATOR_WINDOWS_INCLUDED=true;


//
// User Interface Manager:
//
function gUIM(){
	
	var _windowCount = 0;
	var _zIndexMultiplier=100;
	
	//var _windowArray = new Array;
	var _windowArray = new Object;
	
	var mySelf = this;
	
	var _iconifiedStackCount = -1;
	var _iconifiedStackPosition=POSITION.bottom;
	var _iconifiedStackPadding=12;
	var _iconifiedHeight=35;
	var _iconifiedWidth =250;
	
	DIMENSIONS.init();
	//////////////////////////////
	//
	// PUBLIC METHODS:
	//
	//////////////////////////////
	
	/////////////////////////////////////////////////////////////////
	//
	// addWindow: Add a window to the UIM's list of managed windows
	//
	/////////////////////////////////////////////////////////////////
	this.addWindow = function (windowDivObject,id){
		_windowCount++;
		// Set the window's zIndex so it is on top:
		windowDivObject.style.zIndex = (_windowCount)*_zIndexMultiplier;
		// Add window to the list:
		_windowArray[id]=windowDivObject;
		
	}
	
	/////////////////////////////////////////////////////////////////
	//
	// deleteWindow: Delete a window in the UIM's list of managed windows
	//
	/////////////////////////////////////////////////////////////////
	this.deleteWindow = function ( id ){
		
		delete _windowArray[id];
		_windowCount--;
		
	}
	
	//////////////////////////////////////////////////////////////////
	//
	// bringToTop() : Manages the zIndex of all the windows to put id
	//                on top:
	//////////////////////////////////////////////////////////////////
	this.bringToTop = function (id){
		// Push all down by one ...
		for(var i in _windowArray){
			if( _windowArray[i].style.zIndex > _zIndexMultiplier){
				_windowArray[i].style.zIndex -= _zIndexMultiplier;
			}
		}
		// ... and finally put this window on top:
		_windowArray[id].style.zIndex = _windowCount*_zIndexMultiplier;
		
	}
	
	/////////////////////////////////////////////////////////////
	//
	// convertTagToWindow():
	// Converts an XML or DIV "window" element into a gWindow.
	//
	/////////////////////////////////////////////////////////////
	this.convertTagToWindow = function( node ){
		
		var parent    = node.parentNode;
		var id        = node.id;
		var contents  = node.innerHTML;
		var title     = node.getAttribute("title");
		// ROUGH SPOT : NEED TO PARSE STYLE attribute ...
		var left="";
		var top ="";
		var width="";
		var height="";
		var style     = node.getAttribute("style");
		if(typeof style == "object"){
			// This is the case for IE:
			if(style.left  ) left   = parseInt(style.left  );
			if(style.top   ) top    = parseInt(style.top   );
			if(style.width ) width  = parseInt(style.width );
			if(style.height) height = parseInt(style.height);
		}else{
			var attributes= style.split(";");
			var t;
			for(var i=0;i<attributes.length;i++){
				t = attributes[i].split(":");
				if(t[0].match("left")) left=parseInt(t[1]);
				if(t[0].match("top")) top=parseInt(t[1]);
				if(t[0].match("width")) width=parseInt(t[1]);
				if(t[0].match("height")) height=parseInt(t[1]);
			}
		}
		// remove the original XML node ...
		
		parent.removeChild(node);
		// ... and replace with the window:
		var newWindow = new gWindow(title,id,left,top,width,height,contents);
	}
	
	///////////////////////////////////////////////////////
	//
	// convertWindowTagsToWindows()
	//
	///////////////////////////////////////////////////////
	this.convertWindowTagsToWindows = function (){
		
		var divs = document.getElementsByTagName("div");
		var windowNodes = new Array();
		var i,j=0;
		for(i=0;i<divs.length;i++){
			if(divs[i].className=="window"){
				// Save these specific nodes in an
				// array for processing:
				windowNodes[j]=divs[i];
				j++;
			}
		}
		// Now convert these nodes to Windows:
		// This step removes the original nodes, replacing
		// them with our new nodes:
		for(i=0;i<windowNodes.length;i++){
			this.convertTagToWindow(windowNodes[i]);
		}
	}
	
	//
	// setIconifiedStackPosition()
	//
	// => Valid values are bottom (default), top, left, and right:
	//
	this.setIconifiedStackPosition = function(position){
		if(position<POSITION.bottom || position>=POSITION.center) return;
		_iconifiedStackPosition=position;
	}
	
	//
	// setIconifiedStackPadding()
	//
	this.setIconifiedStackPadding = function(padding){
		_iconifiedStackPadding = padding;
	}
	
	//
	// setIconifiedWidthAndHeight:
	//
	this.setIconifiedWidthAndHeight = function(width,height){
		
		_iconifiedWidth = width;
		_iconifiedHeight= height;
		
	}
	
	//
	// getIconifiedWidthAndHeight:
	//
	this.getIconifiedWidthAndHeight = function(){
		return [ _iconifiedWidth , _iconifiedHeight ];
	}
	
	//
	// getNextIconifiedPosition
	//
	// => Returns [ left , top ] coordinates in an array:
	// => Also increments the iconified window counter, so this
	//    should only be called by the window when going into an iconified state!
	// 
	this.getNextIconifiedPosition = function(){
		//
		// Increment the iconified window count (starts at -1 so that the first
		// window will put the counter at zero:
		//
		_iconifiedStackCount++;
		//
		// Four different iconification options:
		//
		switch(_iconifiedStackPosition){
		case POSITION.left:
			return [ _iconifiedStackPadding , _iconifiedStackPadding + _iconifiedStackCount*_iconifiedHeight ];
			break;
		case POSITION.right:
			return [ DIMENSIONS.width - _iconifiedStackPadding - _iconifiedWidth , _iconifiedStackPadding + _iconifiedStackCount*_iconifiedHeight ];
			break;
		case POSITION.top:
			return [ _iconifiedStackPadding + _iconifiedStackCount*_iconifiedWidth , _iconifiedStackPadding ];
			break;
		case POSITION.bottom:
			return [ _iconifiedStackPadding + _iconifiedStackCount*_iconifiedWidth , DIMENSIONS.height - _iconifiedStackPadding - _iconifiedHeight ];
			break;
		}
	}
	
	//
	// releaseIconifiedWindow()
	//
	this.releaseIconifiedWindow = function(){
		_iconifiedStackCount--;
	}
	
}

//
// Default Global User Interface Manager (UIM) instance:
//
var UIM = new gUIM();


//
// Window Class
//
// title:       Window title
// id:          Window id
// left:        Left coordinate pixel offset
// top:         Top  coordinate pixel offset
// width:       Width in pixels
// height:      Height in pixels
// contents:    Either 1) a String or 2) an element Node containing the window contents
// show:        Whether to display the window or not (true or false). Defaults to true.
// parentNode:  Optional Node where the window will be inserted into the DOM.
//              Defaults to the document's Body node.
//
function gWindow(title,id,left,top,width,height,contents,show,parentNode){
	
	
	/////////////////////////////////////////////
	//
	// Min and Max widths/heights
	//
	/////////////////////////////////////////////
	var _minWidth =100;
	var _minHeight=100;
	var _maxWidth =3000;
	var _maxHeight=3000;
	
	/////////////////////////////////////////////
	//
	// _self variable: Needed because of an 
	// ECMAScript standards definition error
	// whereby inner methods do not have access to the
	// containing class' "this" reference:
	//
	/////////////////////////////////////////////
	var _self =this;
	
	///////////////////////////////////////////////////////////
	//
	// Process parameters, providing reasonable defaults:
	//
	///////////////////////////////////////////////////////////
	var _title;
	if(title) _title=title;
	else      _title="My Window";
	
	var _id;
	if(id) _id=id;
	else   _id="myWindow";
	
	var _left;
	if(left) _left=left;
	else     _left=12;
	var _top;
	if(top) _top=top;
	else    _top=12;
	
	var _width;
	if(width && width>=_minWidth) _width=width;
	else      _width=_minWidth;
	
	var _height;
	if(height && height>=_minHeight) _height=height;
	else       _height=_minHeight;
	
	var _contents;
	if(contents) _contents=contents;
	else         _contents="";
	
	//else         _contents="<p>-- Window has no content-- </p>";
	
	var _show;
	if(typeof show == 'undefined') _show=true;
	else                           _show=show;
	
	var _showTitleBar = true;
	var _canvasTop;         // Value is queried from CSS
	var _canvasBorderWidth; // Value is queried from CSS
	var _canvasBorderColor; // Value is queried from CSS
	var _titleBarHeight;    // Value is queried from CSS
	var _shadowHeight;      // Value is queried from CSS
	
	// Closing a window by default does not remove it from
	// the DOM:
	var _removeFromDOMOnClose=false;
	
	//
	// If window was created in a rtl environment, remember
	// this:
	//
	var _rtl = false;
	if(typeof LC != "undefined"){
		_rtl = ( LC.getDirection() == "rtl" );
	}
	
	//////////////////////////////////////////////
	//
	// USE W3C DOM METHODS TO CREATE THE WINDOW:
	//
	//////////////////////////////////////////////
	
	// CREATE THE WINDOW AND SET ITS ID AND CLASS:
	var _thisWindow = document.createElementNS(NS.xhtml,"div");
	_thisWindow.id=_id;
	_thisWindow.setAttribute("class","window");
	
	// ADD SHADOW COMPONENTS:
	//var _sc = new Array();
	var shadowComponent = document.createElementNS(NS.xhtml,"div");
	shadowComponent.setAttribute("class","sRT");
	//_sc[0]=shadowComponent;
	_thisWindow.appendChild(shadowComponent);
	shadowComponent = document.createElementNS(NS.xhtml,"div");
	shadowComponent.setAttribute("class","sR");
	//_sc[1]=shadowComponent;
	_thisWindow.appendChild(shadowComponent);
	shadowComponent = document.createElementNS(NS.xhtml,"div");
	shadowComponent.setAttribute("class","sRB");
	_thisWindow.appendChild(shadowComponent);
	//_sc[2]=shadowComponent;
	shadowComponent = document.createElementNS(NS.xhtml,"div");
	shadowComponent.setAttribute("class","sB");
	//_sc[3]=shadowComponent;
	_thisWindow.appendChild(shadowComponent);
	shadowComponent = document.createElementNS(NS.xhtml,"div");
	shadowComponent.setAttribute("class","sLB");
	//_sc[4]=shadowComponent;
	_thisWindow.appendChild(shadowComponent);
	// TITLE BAR:
	var _titleBar = document.createElementNS(NS.xhtml,"div");
	_titleBar.setAttribute("class","windowTitleBar");
	// TITLE BAR MEMBERS (CHILD NODES):
	
	// dirClass is appended to specify right-to-left versions of the window classes if rtl:
	var dirClass=(_rtl)?"_rtl":"";
	
	var _iconTray    = document.createElementNS(NS.xhtml,"div"); _iconTray.setAttribute("class","iconTray"   + dirClass);
	var _iconifyIcon = document.createElementNS(NS.xhtml,"div"); _iconifyIcon.setAttribute("class","iconify" + dirClass);
	var _minimizeClass = "minimize" + dirClass;
	var _maximizeClass = "maximize" + dirClass;
	var _minMaxIcon  = document.createElementNS(NS.xhtml,"div"); _minMaxIcon.setAttribute("class", _maximizeClass );
	var _closeIcon   = document.createElementNS(NS.xhtml,"div"); _closeIcon.setAttribute("class","close" + dirClass);
	var _titleTextNode = document.createTextNode(_title);
	var _titleNode   = document.createElementNS(NS.xhtml,"p"  ); _titleNode.appendChild(_titleTextNode);
	
	_iconifyIcon.setAttribute("title","Iconify <-> Restore");
	_minMaxIcon.setAttribute("title","Maximize <-> Restore");
	_closeIcon.setAttribute("title","Close");
	
	//
	// Note: the order of adding icons is important
	// because the icons are now floated right:
	//
	_iconTray.appendChild(_closeIcon);
	_iconTray.appendChild(_minMaxIcon);
	_iconTray.appendChild(_iconifyIcon);
	
	_titleBar.appendChild(_iconTray   );
	_titleBar.appendChild(_titleNode  );
	_thisWindow.appendChild(_titleBar);
	
	//
	// WINDOW CANVAS AND RESIZE ANCHOR:
	//
	var _canvas       = document.createElementNS(NS.xhtml,"div");
	if(_rtl) _canvas.setAttribute("class","windowCanvas_rtl");
	else     _canvas.setAttribute("class","windowCanvas");
	
	//
	// Find out the _canvas' real top position
	// and border attributes (we query border-bottom):
	// ==> Also get _titleBarHeight, shadowHeight:
	//
	_getPropertiesFromStyleSheet();
	
	if(_contents){
		
		if(isString(_contents)){
			_canvas.innerHTML = _contents;
		}else{
			_canvas.appendChild(_contents);
		}
	}
	
	var _resizeAnchor = document.createElementNS(NS.xhtml,"div"); _resizeAnchor.setAttribute("class","resizeAnchor"+dirClass);
	_thisWindow.appendChild(_canvas);
	_thisWindow.appendChild(_resizeAnchor);
	
	////////////////////////////////////////////////
	//
	// Add the window node to the DOM tree:
	// By default, add window to the BODY element,
	// unless some other parentNode was supplied as
	// an argument to the constructor:
	//
	////////////////////////////////////////////////
	if(parentNode){
		parentNode.appendChild(_thisWindow);
	}else{
		// Using document.body.appendChild is convenient, but 
		// apparently it is not in the W3C standard ...
		// ==> document.body.appendChild(_thisWindow);
		// The W3C standards way to get the document body:
		var bodyRef = document.getElementsByTagName("body").item(0);
		bodyRef.appendChild(_thisWindow);
	}
	
	////////////////////////////////////////////////////////////////////
	//
	// Now set the window's CSS position, size, and display properties:
	//
	////////////////////////////////////////////////////////////////////
	_thisWindow.style.left   = _left   + "px";
	_thisWindow.style.top    = _top    + "px";
	_thisWindow.style.width  = _width  + "px";
	_thisWindow.style.height = _height + "px";
	if(_show){
		_thisWindow.style.display="block";
	}else{
		_thisWindow.style.display="none";
	}
	
	//_titleBarHeight    = getComputedWidthAndHeight(_titleBar)[1];
	//_shadowHeight      = getComputedWidthAndHeight(shadowComponent)[1];
	////////////////////////
	//
	// PRIVATE METHODS:
	//
	////////////////////////
	
	//////////////////////////////////////////////////////////////////////
	//
	// shade() PRIVATE method:
	//
	//////////////////////////////////////////////////////////////////////
	
	var _isShaded = false;
	//
	// shade()
	//
	function shade(e){
		e = gEvent(e);
		e.preventDefault();
		
		if(_isShaded){
			
			_thisWindow.style.height = _height + "px";
			if(_allowResizing) _resizeAnchor.style.display="block";
			_isShaded = false;
			
		}else{
			
			_thisWindow.style.height = "35px";
			_resizeAnchor.style.display="none";
			_isShaded = true;
			
		}
		//
		// Theoretically this stops additional onclick handler action:
		//
		//e.stopPropogation();
		return false;
	}
	
	var _isIconified=false;
	//
	// iconify()
	//
	function iconify(e){
		
		if(_isIconified){
			//
			// Restore:
			//
			_thisWindow.style.left   = _left   + "px";
			_thisWindow.style.top    = _top    + "px";
			_thisWindow.style.width  = _width  + "px";
			_thisWindow.style.height = _height + "px";
			// NEXT LINE IS TEMPORARY:
			_iconTray.style.width = "68px";
			if(_allowResizing) _resizeAnchor.style.display="block";
			if(_allowMinMax  ) _minMaxIcon.style.display  ="block";
			if(_allowClose   ) _closeIcon.style.display   ="block";
			_isIconified = false;
			//
			// unregister / release iconified windows:
			//
			UIM.releaseIconifiedWindow();
			
		}else{
			//
			// Iconify : Get info from the interface manager:
			//
			var iconifiedWidthAndHeight = UIM.getIconifiedWidthAndHeight();
			//
			// getNextIconifiedPosition also registers the number of
			// iconified windows with the UIM:
			//
			var iconifiedPosition       = UIM.getNextIconifiedPosition();
			
			_thisWindow.style.width  = iconifiedWidthAndHeight[0] + "px";
			_thisWindow.style.height = iconifiedWidthAndHeight[1] + "px";
			_thisWindow.style.left   = iconifiedPosition[0] + "px";
			_thisWindow.style.top    = iconifiedPosition[1] + "px";
			_iconTray.style.width    = "24px";
			_resizeAnchor.style.display="none";
			_closeIcon.style.display   ="none";
			_minMaxIcon.style.display  ="none";
			_isIconified = true;
			
		}
		return false;
	}
	
	var _isClosed=false;
	//
	// close() :
	//
	function close(e){
		e = gEvent(e);
		e.preventDefault();
		
		if(_removeFromDOMOnClose){
			
			var parent = _thisWindow.parentNode;
			parent.removeChild(_thisWindow);
			//
			// Delete the window from the window manager:
			//
			UIM.deleteWindow(_id);
			// Can we delete _self?
			delete _self;
			//for(var i in _self){
			//	alert(_self[i]);
			//}
			
		}else{
			_thisWindow.style.display="none";
			//fadeOut(_id,1.0);
			_isClosed=true;
		}
		return false;
		
	}
	
	/////////////////////////////////////
	//
	// DRAG AND RESIZE METHODS:
	//
	/////////////////////////////////////
	var _mouseStartX;
	var _mouseStartY;
	var _isMoveable=false;
	
	//
	// grabWindow():
	//
	function grabWindow(e){
		
		//
		// Always prevent the default ...
		//
		e=gEvent(e);
		e.preventDefault();
		//
		// .. but don't do anything else if the window is 
		// already maximized or iconified:
		//
		if(_isMaximized || _isIconified) return false;
		
		//
		// bring window to top to avoid ugly screen
		// movement artifacts on windows that might
		// otherwise be on top of this one:
		//
		_self.bringToTop();

		// This is a speed optimization:	
		if(_isShaded) _canvas.style.display="none";
		
		_mouseStartX = e.xPosition;
		_mouseStartY = e.yPosition;
		
		_isMoveable  = true;
		//
		// Add an event listener to the whole document:
		// This is better than adding it just to title bar, because
		// the user can easily move the mouse so fast that it leaves the
		// titleBar's event area, leaving the window "frozen".  
		//
		document.addEventListener("mousemove",moveWindow   ,false);
		document.addEventListener("mouseup"  ,releaseWindow,false);
		
		return false;
	}
	
	//
	// moveWindow:
	//
	function moveWindow(e){
		e=gEvent(e);
		e.preventDefault();
		
		if(_isMoveable){
			
			var newX = _left - _mouseStartX + e.xPosition;
			var newY = _top  - _mouseStartY + e.yPosition;
			
			// Don't let window ever go completely off screen:
			if(newX > DIMENSIONS.width -DIMENSIONS.padding) newX=DIMENSIONS.width-DIMENSIONS.padding;
			if(newY > DIMENSIONS.height-DIMENSIONS.padding) newY=DIMENSIONS.height-DIMENSIONS.padding;
			if(newX < DIMENSIONS.padding-_width ) newX = DIMENSIONS.padding-_width;
			if(newY < DIMENSIONS.padding-_height) newY = DIMENSIONS.padding-_height;
			
			_thisWindow.style.left=newX+"px";
			_thisWindow.style.top=newY+"px";
		}
		return false;
	}
	
	//
	// releaseWindow()
	//
	function releaseWindow(e){
		e = gEvent(e);
		e.preventDefault();
		if(_isMoveable){
			// Set _left and _top to correspond to
			// where the window has moved:
			// ==> But don't do this if window is iconified or maximized:
			if(!(_isIconified || _isMaximized)){
				_left = parseInt(_thisWindow.style.left,10);
				_top  = parseInt(_thisWindow.style.top ,10);
			}
			// Stop moving the window:
			document.removeEventListener("mousemove",moveWindow   ,false);
			document.removeEventListener("mouseup"  ,releaseWindow,false);
			_isMoveable = false;
	
			// This is a speed optimization:	
			if(_isShaded) _canvas.style.display="block";
		}
		
		return false;
	}
	
	var _isResizable=false;
	//
	// grabResize():
	//
	function grabResize(e){
		e = gEvent(e);
		e.preventDefault();
		_mouseStartX = e.xPosition;
		_mouseStartY = e.yPosition;
		_isResizable = true;
		//
		// Add an event listener to the whole document:
		// This is better than adding it just to title bar, because
		// the user can easily move the mouse so fast that it leaves the
		// resizeAnchor's event area, leaving the window "frozen".  
		//
		document.addEventListener("mousemove",resizeWindow ,false);
		document.addEventListener("mouseup"  ,releaseResize,false);
		return false;
	}
	
	//
	// resizeWindow
	//
	// ROUGH SPOT: STILL NEEDS WORK WHEN RESIZING WITH SCROLLBARS PRESENT (I.E., WHEN
	//             DOCUMENT IS BIGGER THAN WINDOW ...
	//
	function resizeWindow(e){
		e = gEvent(e);
		e.preventDefault();
		
		if(_isResizable){
			//
			// How much do we resize the window in the horizontal direction?
			//
			var deltaX    = e.xPosition - _mouseStartX;
			//
			// In RTL mode, moving the mouse to the right makes the window
			// narrower, while in LTR mode it makes the window wider:
			//
			if(_rtl) deltaX *= -1;
			
			//
			// WINDOW WIDTH:
			//
			var newWidth  = _width  + deltaX;
			if(newWidth  < _minWidth ){  
				newWidth  = _minWidth;
				// ... In this case, don't change "left" in RTL case...
			}else if(newWidth  > _maxWidth ){
				newWidth  = _maxWidth;
				// ... and also in this case don't change "left" in RTL case ...
			}else{
				// ... Only in the normal case change "left" in RTL case:
				if(_rtl){
					_thisWindow.style.left = (_left - deltaX) + "px";
				}
			}
			_thisWindow.style.width  = newWidth  + "px";
			
			//
			// WINDOW HEIGHT:
			//
			var newHeight = _height + e.yPosition - _mouseStartY;
			if(newHeight < _minHeight)  newHeight = _minHeight;
			if(newHeight > _maxHeight)  newHeight = _maxHeight;
			_thisWindow.style.height = newHeight + "px";
			
			
			
		}
		return false;
	}
	
	//
	// releaseResize()
	//
	function releaseResize(e){
		e = gEvent(e);
		e.preventDefault();
		if(_isResizable){
			// Update _width and _height:
			_width  = parseInt( _thisWindow.style.width ,10);
			_height = parseInt( _thisWindow.style.height,10);
			if(_rtl){
				// Set _left to correspond to
				// where the window has moved because
				// resizing in RTL mode requires moving
				// the left position:
				//
				_left = parseInt(_thisWindow.style.left,10);
			}
			// Stop resizing the window:
			document.removeEventListener("mousemove",resizeWindow ,false);
			document.removeEventListener("mouseup"  ,releaseResize,false);
			_isResizable = false;
		}
		return false;
	}
	
	//
	// bringToTop(): Puts this window on top
	//
	this.bringToTop = function(){
		
		// Call UIM's bringToTop method:
		UIM.bringToTop(_id);
		
	}
	
	
	var _isMaximized=false;
	//
	// minMax()
	//
	function minMax(){
		
		if(_isMaximized){
			//
			// Restore:
			//
			_thisWindow.style.left   = _left   + "px";
			_thisWindow.style.top    = _top    + "px";
			_thisWindow.style.width  = _width  + "px";
			_thisWindow.style.height = _height + "px";
			_minMaxIcon.setAttribute("class", _maximizeClass );
			_resizeAnchor.style.display="block";
			_isMaximized=false;
		}else{
			//
			// Maximize:
			//
			_thisWindow.style.left   = 0 + "px";
			_thisWindow.style.top    = 0 + "px";
			_thisWindow.style.width  = DIMENSIONS.width  + "px";
			_thisWindow.style.height = DIMENSIONS.height + "px";
			_minMaxIcon.setAttribute("class", _minimizeClass );
			_resizeAnchor.style.display="none";
			_isMaximized=true;
		}
	}
	
	//
	// _getPropertiesFromStyleSheet()
	//
	function _getPropertiesFromStyleSheet(){
		
		var myStyleSheet   = getStyleSheet("gladiatorWindows");
		
		var myStyle        = getCSSClassStyle(myStyleSheet,".windowCanvas");
		_canvasTop         = myStyle.top;
		
		//
		// Title bar height needs to include bottom border to get the
		// correct canvas height calculation:
		//
		myStyle            = getCSSClassStyle(myStyleSheet,".windowTitleBar");
		_titleBarHeight    = parseInt(myStyle.height);
		_titleBarHeight   += parseInt(myStyle.borderBottomWidth);
		
		myStyle            = getCSSClassStyle(myStyleSheet,".window .sRB");
		_shadowHeight      = parseInt(myStyle.height);
		
		myStyle            = getCSSClassStyle(myStyleSheet,".windowCanvas");
		_canvasBorderWidth = myStyle.borderBottomWidth;
		_canvasBorderColor = myStyle.borderBottomColor;
		
	}
	
	//////////////////////////////
	//
	// PUBLIC METHODS:
	//
	//////////////////////////////
	
	//
	// The standardized "base class" API method 
	// to get the canvas node is "getNode" as shown
	// here: ...
	// 
	// : Returns the XHTML node of the Window's canvas:
	//
	this.getNode = function(){
		
		return _canvas;
		
	}
	
	//
	// addContent( contentNode )
	//
	this.addContent = function(contentNode){
		
		_canvas.appendChild(contentNode);
		
	}
	
	
	// ... This is a convenience method.  It is identical to getNode():
	//
	// getCanvas() : Returns the XHTML node of the window's canvas
	//
	this.getCanvas = function(){
		
		return _canvas;
		
	}
	
	//
	// allowIconify()
	//
	this.allowIconify = function( allow ){
		
		if(allow) _iconifyIcon.style.display="block";
		else      _iconifyIcon.style.display="none";
		
	}
	
	//
	// allowMinMax()
	//
	var _allowMinMax = true;
	this.allowMinMax = function( allow ){
		
		// Return if no state change:
		if(allow == _allowMinMax) return;
		// Get here if state change:
		_allowMinMax = allow;
		if(_allowMinMax) _minMaxIcon.style.display="block";
		else             _minMaxIcon.style.display="none";
		
	}
	
	//
	// allowClose()
	//
	var _allowClose = true;
	this.allowClose = function( allow ){
		// Return if no state change:
		if(allow == _allowClose) return;
		// Get here if state change:
		_allowClose = allow;
		if(_allowClose) _closeIcon.style.display="block";
		else            _closeIcon.style.display="none";
		
	}
	
	//
	// allowAll()
	//
	this.allowAll = function( allow ){
		
		if(allow){
			_iconifyIcon.style.display="block";
			_self.allowMinMax(true);
			_self.allowClose(true);
			_iconTray.style.display="block";
		}else{
			_iconifyIcon.style.display="none";
			_self.allowMinMax(false);
			_self.allowClose(false);
			_iconTray.style.display="none";
		}
	}
	
	//
	// allowResize():
	//
	var _allowResizing=true;
	
	this.allowResize = function( allow ){
		
		// Set state flag:
		_allowResizing = allow;
		// Update display of resizeAnchor:
		if(_allowResizing) _resizeAnchor.style.display="block";
		else               _resizeAnchor.style.display="none";
		
	}
	
	//
	// show()
	//
	this.show = function( showIt ){
		
		_show = showIt;
		if(_show){
			_thisWindow.style.display="block";
			_thisWindow.style.opacity=1.0;
		}else{  
			_thisWindow.style.display="none";    
			//fadeOut(_id,1.0);
		}
	}
	
	//
	// isVisible(): True if is visible
	//
	this.isVisible = function(){
		return _show;
	}
	
	//
	// Closing a window by default does not remove it from
	// the DOM: Pass true to this set method so that the
	// window will be removed from the DOM when closed:
	//
	this.removeFromDOMOnClose = function( removeIt ){
		
		_removeFromDOMOnClose=removeIt;
		
	}
	
	//
	// showTitleBar() : Show or hide the title bar.
	// 
	this.showTitleBar = function( showIt ){
		
		//
		// Don't do anything if there is no
		// change in state:
		//
		if( showIt == _showTitleBar ) return;
		
		_showTitleBar = showIt;
		if( _showTitleBar ){
			
			_titleBar.style.display="block";
			_canvas.style.top = _canvasTop;
			//
			// Restore the default setting of
			// no top border on the canvas:
			//
			_canvas.style.borderTop="none";
			
		}else{
			
			_titleBar.style.display="none";
			//
			// By default there is no top border on the canvas
			// but without the title bar we need to have one:
			//
			_canvas.style.top = "0px";
			_canvas.style.borderTop= _canvasBorderWidth+" solid "+_canvasBorderColor;
			
		}
		
	}
	
	//
	// setHeight():
	//
	this.setHeight = function(height){
	
		_height = height +
		          (_showTitleBar ? _titleBarHeight : 0 ) +
		          _shadowHeight +
		          2*parseInt(_canvasBorderWidth);
		
		_thisWindow.style.height = _height+"px";
		
	}

	//
	// getTitleBarHeight
	//
	this.getTitleBarHeight = function(){
		
		return (_showTitleBar ? _titleBarHeight : 0 );
		
	}
	
	//
	// getShadowWidth
	//
	this.getShadowWidth = function(){
		return _shadowHeight;
	}
	
	//
	// getWidth
	//
	this.getWidth = function(){
		return _width;
	}
	
	//
	// getHeight
	//
	this.getHeight = function(){
		return _height;
	}
	
	//
	// getLocation()
	//
	this.getLocation = function(){
		
		return [  _left , _top ];
		
	}

	//
	// setLocation
	//
	this.setLocation = function( left , top ){
		
		_left = left;
		_top  = top;
		_thisWindow.style.left = _left + "px"; 
		_thisWindow.style.top  = _top  + "px";
	}

	this.iconify = function(){
		iconify();
	}
	
	//
	// setTitle:
	//
	this.setTitle = function( title ){
		_titleTextNode.nodeValue=title;
	}
	
	//
	// setTitleNodeIconTrayClass:
	//
	this.setTitleNodeIconTrayClass = function(titleNodeClass,iconTrayClass){
		_titleNode.setAttribute("class",titleNodeClass);
		_iconTray.setAttribute("class",iconTrayClass);
	}
	
	/////////////////////////////
	//
	// CONNECT EVENT LISTENERS:
	//
	/////////////////////////////
	
	_titleBar.addEventListener("dblclick" ,shade        ,false);
	_titleBar.addEventListener("mousedown",grabWindow   ,false);
	
	_iconifyIcon.addEventListener("click",iconify,false);
	_closeIcon.addEventListener("click",close,false);
	_minMaxIcon.addEventListener("click",minMax,false);
	
	_resizeAnchor.addEventListener("mousedown",grabResize   ,false);
	
	_thisWindow.addEventListener("click",_self.bringToTop,false);
	
	//////////////////////////////////////////////////////
	//
	// Add this window to global user interface manager:
	//
	//////////////////////////////////////////////////////
	UIM.addWindow(_thisWindow,_id);
	
}
