/*
 *	Generic show popup window function.
 */
function showPopupWindow(url, name, features, returnValue, returnID)
{
	// Only one popup is allowed at any time, so...
	try
	{
		// ... if current window already has reference to a child popupWindow object
		if(window.childPopup)
			// ... and the object refers to an open browser window
			if(!window.childPopup.window.closed)
				// ... close existing window (and its children)
				window.childPopup.close();
	}
	catch(e){};
	
	// Create new popupWindow object which inplicitly opens new popup window
	var w = new popupWindow(url, name, features, returnValue, returnID);
	
	// Return reference to new window
	return w.window;
}

/*
 * Close any child popup window(s) opened by the current window. Any grand, great grandchildren etc
 * will be recursively closed. Relies on existence of reference to child popupWindow object in
 * window property, childPopup. This property is automatically set by popupWindow.open()
 */
function closeChildPopup()
{
	try{ self.childPopup.close(); } catch(e){};
}

/*
 *	popupWindow constructor
 */
function popupWindow(url, name, features, returnValue, returnID)
{
	this.open = ppwOpen;
	this.close = ppwClose;
	this.getParent = ppwGetParent;
	this.open(url, name, features, returnValue, returnID);
}

function ppwOpen(url, name, features, returnValue, returnID)
{
	var parsedFeatures = '';
	var left = 0;
	var top = 0;
	var width = 0;
	var height = 0;
	
	// Fill in default values in features string passed to us.
	parsedFeatures = features;
	parsedFeatures = ppwParseFeatures(parsedFeatures, 'resizeable',	'no');
	parsedFeatures = ppwParseFeatures(parsedFeatures, 'caption',	'no');
	parsedFeatures = ppwParseFeatures(parsedFeatures, 'title',		'no');
	parsedFeatures = ppwParseFeatures(parsedFeatures, 'toolbar',	'no');
	parsedFeatures = ppwParseFeatures(parsedFeatures, 'menubar',	'no');
	parsedFeatures = ppwParseFeatures(parsedFeatures, 'status',		'no');
	parsedFeatures = ppwParseFeatures(parsedFeatures, 'height',		'500');
	parsedFeatures = ppwParseFeatures(parsedFeatures, 'width',		'500');
	width  = parseInt(ppwGetFeatureValue(parsedFeatures, 'width' ));		//
	height = parseInt(ppwGetFeatureValue(parsedFeatures, 'height'));		// Get width and height as integers so as
	left = (screen.width  - parseInt(width))  / 2;							// to calculate default left/top coordinates 
	top  = (screen.height - parseInt(height)) / 2;							//
	parsedFeatures = ppwParseFeatures(parsedFeatures, 'left', left);
	parsedFeatures = ppwParseFeatures(parsedFeatures, 'top', top);

	try
	{
		// Open popup window and save reference to it
		this.window = window.open(url, name, parsedFeatures);

		// Set well known properties in opener window.
		if(arguments.length > 3)
			this.getParent().returnValue = returnValue;			// Target field for any text returned from this popup
		if(arguments.length > 4)
			this.getParent().returnID = returnID;				// Target field for any id associated with text returned
		
		this.getParent().childPopup = this;						// Reference to this object
		
		// Keyboard focus to new popup
		this.window.focus();
	}
	catch(e)
	{
		this.window = null;
	}
}

function ppwClose()
{
	// Close any child (which will recursively close all children)
	if(this.window.childPopup)
	{
		this.window.childPopup.close();
	}
	this.getParent().childPopup = null;
	this.window.close();
}

function ppwGetParent()
{
	return window;
}

/*
 *  Parse given window.open() features string for named feature/valuen pair. 
 *  If not found return the original string with given name/default value appended. 
 *  If feature  pair is found return original features string as passed in.
 */
function ppwParseFeatures(features, name, defaultValue)
{
	var feature = ppwGetFeatureValue(features, name, defaultValue)
	
	if(feature == '')
   		return features + ',' + name + '=' + defaultValue;
	else		  	
		return features;
}

/*
 *  Return value portion part of named feature in given window.open() features string.
 */
function ppwGetFeatureValue(features, name)
{
  	// Expression to find "name=xxxxx" in string such as "caption=no,height=400,width=200".
	// Features are comma separated but no terminating separator is required.
   	var exp = new RegExp(name + '=(\\w*)[,;]*');
   	
	// Search for match and put results in array, r[]
	var r = exp.exec(features);

   	// Value should be in 2nd element, else return empty string.
   	if( r && r.length > 0)
   		return r[1];
   	else
   		return '';
}
