/****************** GLOBAL VARS *********************/
/*  See also _control::Page::API, which sets some dynamic
 *  global Javascript variables. 
 */
var STYLE_SHEETS = new Array();

// 8709	- Incoporated from NPSN's npsn.js
/*********************  GENERIC UTILITIES  *******************/
var Util = {
	ParseDelimitedInt: function(string, delimiter)
	{
		if (! delimiter ) delimiter = /,/;
		var number = string.replace(delimiter, '');
		return parseInt(number); 
	},
	
	/**
	 * ShowLoadingMessage()
	 * This method assumes there is a hidden div on the page with
	 * and id of 'loading_message'.  This will unhide that div.
	 */
	ShowLoadingMessage: function()
	{
		var elem = document.getElementById('loading_message');
		if (! elem ) return;
		elem.style.visibility = "visible";
	}
};

/** Util.Table
 * Utility functions for HTML tables, such as sorting.
**/
Util.Table = {
	/** Sort(TableCell) : void
	 * Takes a header cell element from an HTML table and sorts the rows in
	 * that cell's table section (tbody -- usually the entire table).  Each
	 * regular cell in the table (td) is required to have a sortValue attribute.
	 * The value of this attribute is the value to be sorted on, which is not
	 * necessarily the same as the value between the td tags.
	**/
	Sort: function(tCell) {
		
		// We will pull the rows out of the table's tbody element and put them
		// into this array to sort them.
		var rows = [];
		
		// Get tbody element from the header cell on which we are sorting
		var tbody = tCell.parentNode.parentNode;
		if ( tbody.tagName.toLowerCase() != "tbody" ) throw new Error("not a tbody");
		
		// Pull out all rows except the heading row and push them onto the array
		for ( var index = 1; tbody.rows.length > 1; )
		{
			var nextRow = tbody.rows.item(index);
			rows.push(tbody.removeChild(nextRow));
		}
		
		// Sort the array based on tCell, the selected header cell
		rows = this.sortRows(rows, tCell);
		
		// Push the sorted rows back into the table
		var odd = true;
		for ( var index = 0; index < rows.length; index++ ) {
			var nextRow = rows[index];
			
			// Make sure the row highlighting fits the new ordering.
			if ( odd ) nextRow.className = "odd";
			else       nextRow.className = "even";
			odd = ! odd;
			tbody.appendChild(nextRow);
		}
	},
	
	/**  sortRows(HtmlCollection<TableRow>, TableCell)
	 * Helper function for Sort()
	**/
	sortRows: function(rows, sortCell) {
		var sortIndex = sortCell.cellIndex;
		var isNumeric = sortCell.getAttribute("sortNumeric");
		rows.sort( function(a, b) {

			var aCell = a.getElementsByTagName('td')[sortIndex];
			var bCell = b.getElementsByTagName('td')[sortIndex];
			var aVal = aCell.getAttribute("sortValue");
			var bVal = bCell.getAttribute("sortValue");
			
			// If there is no "sortValue" attribute, fall back on
			// the contents of the cell.
			if ( aVal == undefined )
			{
				aVal = aCell.innerHTML;
			}
			if ( bVal == undefined )
			{
				bVal = bCell.innerHTML;
			}

			if ( isNumeric || (parseFloat(aVal) == aVal && parseFloat(bVal) == bVal)){ return aVal - bVal; }
			else { return aVal.toLowerCase().localeCompare(bVal.toLowerCase()); }
		});
		return rows;
	}
}
// \8709


/*********************  DHTML  **********************/
function ShowHide(id)
{
	var obj = document.getElementById(id)
	if ( IsHidden(obj) )  // 4613
	{
		ShowObject(obj)
	}
	else
	{
		HideObject(obj)
	}
}
function ShowElement(id)
{
	var obj = document.getElementById(id)
	ShowObject(obj)	
}
function HideElement(id)
{
	var obj = document.getElementById(id)
	HideObject(obj)	
}
function ShowObject(obj)
{
	obj.style.display = "block"
}
function HideObject(obj)
{
	obj.style.display = "none"
}
function IsHidden(obj)
{
	if ( obj.style.display == "none" ) return true
	if (! obj.style.display ) return true
	return false
}


/****************  POP-UP WINDOWS ********************/
function PopupWindow(url, parameters)
{
	if (!parameters){ parameters ='scrollbars,resizable,width=400,height=400' }
	var newWin = window.open(url,'',parameters)
	newWin.moveTo(15,15)
	newWin.focus()  // 4952
}

// Add a style sheet to the list of printable style sheets.
// This is mostly used for keeping track of style sheets that need
// to be linked when printing a new popup window
function AddStyleSheet(sheetPath) 
{
	if(sheetPath && sheetPath.length) 
	{
		STYLE_SHEETS.push(sheetPath);
	}
	return STYLE_SHEETS.length;
}

// Print out a list of links to all of the stored style sheets
function PrintStyleSheets() 
{
	var out = '';
	if(STYLE_SHEETS.length) 
	{
		for(var i = 0; i < STYLE_SHEETS.length; i++) 
		{
			out += "<link rel=\"stylesheet\" type=\"text/css\" href=\"" + STYLE_SHEETS[i] + "\"></link>\n";
		}
	} 
	else 
	{
		out = "<link rel=\"stylesheet\" type=\"text/css\" href=\"/css/pc.css\"></link>\n";
	}
	return out;
}

// Generic print icon
function PrintIcon() {
	return "<a href=javascript:window.print()>PRINT</a>"
}

// Generic CloseWindow icon
function CloseWindowIcon() {
	return "<a href=javascript:window.close()>CLOSE</a>"
}

/* 5227 */
/* CloseAndRefresh()
 * Closes the current popup window and refreshes the parent.
 */
function CloseAndRefresh() {
	parent.opener.location.href=parent.opener.location; // to refresh the parent window.
	window.close(); // to close the child/popup window.
}


/****************  CONFIRMATION POPUPS ********************/

// 5037
/* DeleteConfirm()
 * Takes a record id, that record's table name, and an
 * optional, UNENCODED return url.  Confirms that the user
 * wants to delete the given record, deletes it, and returns
 * the user back to the url given.
 *
 * Encoding the URL here (as opposed to in cgi) avoids some 
 * browser-specific problems that I ran into.  Some browsers
 * required the string to be encoded more than once, while
 * others did not.  Using JS encoding as below seems to 
 * do the trick.
 */
function DeleteConfirm(id, table, return_url)
{
	if (confirm('Are you sure you wish to delete this record?'))
	{
		// 5316 
		// REFERRER does not include posted parameters,
		// which can be problematic.
		//alert("return url before: "+ return_url)
		if (! return_url )
		{
			return_url = REFERRER
		}
		// 5337
		else  // REFERRER is already URL-encoded
		{
			return_url = encodeURIComponent(return_url)
		}
		//alert("return url after: "+ return_url)
		location = SERVER+CGIpath+"/rm.cgi?ok=1&tab="+table+"&id="+id+"&return="+return_url
	}
}


/* ConfirmRedirect(url, message)  # 5076
 * Given a url and a message, allows the user to confirm that she
 * wants to be redirected before taking her to the given url.
 */
function ConfirmRedirect(url, message)
{
	if (confirm(message) )
	{
		location = url;
	}
}


// 6247
/****************  STRING MANIPULATION  ********************/

/**
 * ShowData
 * A Javascript implementation of Lib::HTML::ShowData().  Takes
 * a string indicating the format ("integer", "date", etc) and
 * the string to be formatted and returns the formatted string. 
 **/
function ShowData(format, value)
{
	if ( format == 'integer' )
	{
		value = AddCommas(value);
	}
	return value;
}

function AddCommas(nStr)
{
	nStr += '';
	x = nStr.split('.');
	x1 = x[0];
	x2 = x.length > 1 ? '.' + x[1] : '';
	var rgx = /(\d+)(\d{3})/;
	while (rgx.test(x1)) {
		x1 = x1.replace(rgx, '$1' + ',' + '$2');
	}
	return x1 + x2;
}
// 6247

// 8398
/********************  EVENT HANDLER  **********************/
/* This function can be added to an onKeyPress handler to form inputs such as a 
	 text box. When the user hits enter, the form would be submitted.
	 
	 When using this handler, be sure to pass in the keyword 'event', 
	 ie. onKeyPress="EnterKeyHandler(event, FunctionName)" and,
	 the name of the function to be executed. */
function EnterKeyHandler(e, functionName)
{
	// Here we try to get the keycode
	var keycode;
	if (window.event) 
	{
		keycode = window.event.keyCode;
	}
	else if (e)
	{
		keycode = e.which;
	}
	// If none is found, simply return true, which means the user is only typing.
	else
	{
		return true;
	}
	// If the key pressed is the enter key
	if (keycode == 13)
	{
		// Execute the function.
		eval(functionName+'()');
	}
	// else, we don't do anything and let the user keep on typing.
	else
	{
		return true;
	}
}
// \8389
