/********************************************************************************
 * 
 * File:
 *	JavaScript.js 
 * 
 * Description:
 *	Contains generic JavaScript support routines.
 * 
 * Revision History:
 *
 *	2009.07.10	dwo
 *				createCookie(name, value, days): Added.
 *				readCookie(name): Added.
 *				eraseCookie(name): Added.
 *				areCookiesEnabled(): Added.
 *				
 *	2009.01.12	dwo
 *				Original.
 * 
 * Copyright (c) 2009 Oxford Consulting, LLC
 *	All rights reserved worldwide by Oxford Consulting, LLC
 *	http://www.OxfordConsulting.us
 * 
 ********************************************************************************/

////////////////////////////////////////////////////////////////////////////////
// If the given DOM Element's display style is currently set to 'none', then
// set it to 'block'.
// Otherwise, set it to 'none'.
// Caution:  IE does not support blockType = 'table-row'.
////////////////////////////////////////////////////////////////////////////////
function ToggleDisplayVisibility(id, blockType, idIndicatorImage, imgVisibleURL, imgHiddenURL)
	{
	var ctl = document.getElementById(id);
	var ctlIndicator = document.getElementById(idIndicatorImage);
	if ( ! blockType )
		blockType = 'block';
	if (ctl)
		{
		if ( ctl.style.display == 'none' )
			{
			ctl.style.display = blockType;
			if ( ctlIndicator )
				ctlIndicator.src = imgVisibleURL;
			}
		else
			{
			ctl.style.display = 'none';
			if ( ctlIndicator )
				ctlIndicator.src = imgHiddenURL;
			}
		}
	}	// End ToggleDisplayVisibility()
	
////////////////////////////////////////////////////////////////////////////////
// If the given DOM Element's display class is currently set to
//	the given classNameHidden, then set it to the given classNameVisible;
// Otherwise, set its class to the given classNameHidden.
////////////////////////////////////////////////////////////////////////////////
function ToggleDisplayVisibilityClass(id, blockType, idLink, classNameVisible, classNameHidden, idIndicatorImage, imgVisibleURL, imgHiddenURL)
	{
	var ctl = document.getElementById(id);
	var ctlLink = document.getElementById(idLink);
	var ctlIndicatorImage = document.getElementById(idIndicatorImage);
	if (ctl)
		{
		if ( ! blockType )
			blockType = 'block';
		if ( ctl.style.display == 'none' )
			{
			ctl.style.display = 'block';
			if ( ctlLink )
				{
				ctlLink.className = classNameVisible;
				}
			if ( ctlIndicatorImage )
				ctlIndicatorImage.src = imgVisibleURL;
			}
		else
			{
			ctl.style.display = 'none';
			if ( ctlLink )
				{
				ctlLink.className = classNameHidden;
				}
			if ( ctlIndicatorImage )
				ctlIndicatorImage.src = imgHiddenURL;
			}
		}
	}	// End ToggleDisplayVisibilityClass()
	
////////////////////////////////////////////////////////////////////////////////
// Add a table row to the given table.
////////////////////////////////////////////////////////////////////////////////
function AddTableRow(idTable)
	{
	var ctlTable = document.getElementById(idTable);

	if ( ctlTable )
		{
		// Get the Table's Body.
		var arrCtlTableBody = ctlTable.getElementsByTagName('tbody');
		var ctlTableBody = arrCtlTableBody[0];
		// Get the current number of rows in the table.
		var arrRows = ctlTableBody.getElementsByTagName('tr');
		var intRowCount = arrRows.length;
		// Create a copy of the 1st Row.
		var ctlNewRow = arrRows[0].cloneNode(true);
		var strHTML = ctlNewRow.innerHTML;
		var strCheckedID = null;
		// Get the elements within this row.
		var elements = ctlNewRow.getElementsByTagName("*");
		for (i = 0; i < elements.length; i++)
			{
			if ( elements[i].type == "radio" )
				{
				var attributes = elements[i].attributes;
				var strAttributes = "";
				strCheckedID = null;
				for (var j = 0; j < attributes.length; j++)
					switch(attributes[j].name)
						{
						case 'id':
							strNewID = attributes[j].value.replace("_0", "_" + intRowCount);
						case 'type':
						case 'name':
						case 'style':
						case 'class':
						case 'value':
							strAttributes = strAttributes + " " + attributes[j].name + "=\"" + attributes[j].value.replace("_0", "_" + intRowCount) + "\"";
							break;
						default:
							break;						
						}
				//alert("Checked: " + elements[i].getAttribute('id') + " = " + getCheckedValue(elements[i]));

				if ( getCheckedValue(elements[i]) )
					strCheckedID = strNewID;
				strElement = "<input " + strAttributes + ">";
				//alert(strElement + " - CheckedID: " + strCheckedID);
				var newElement;
			    try
					{
					newElement = document.createElement(strElement);
					//alert("New Element: " + newElement.tagName + "\n" + strElement);
					}
				catch( err )
					{
					newElement = document.createElement('input');
					for (var j = 0; j < attributes.length; j++)
						{
						newElement.setAttribute(attributes[j].name, attributes[j].value.replace("_0", "_" + intRowCount));
						//alert(attributes[j].name + ", " + newElement.getAttribute(attributes[j].name));
						}
					}
				elements[i].parentNode.replaceChild(newElement, elements[i]);
				}
			else
				{
				//alert(elements[i].tagName + ":\n    Id (before): " + elements[i].getAttribute("id") + "\n    Name (before): " + elements[i].getAttribute("name"));
				ReplaceAttributeValue(elements[i], "id", /0/g, intRowCount);
				ReplaceAttributeValue(elements[i], "name", /0/g, intRowCount);
				//alert(elements[i].tagName + ":\n    Id (after): " + elements[i].getAttribute("id") + "\n    Name (after): " + elements[i].getAttribute("name"));
				}
			}

		strHTML = ctlNewRow.innerHTML;
		//alert(strHTML);
		ctlTableBody.appendChild(ctlNewRow);
		//alert("CheckedID: " + strCheckedID);
		if ( strCheckedID )
			document.getElementById(strCheckedID).checked = true;
		}
	}	// End AddTableRow()
	
// return the value of the radio button that is checked
// return an empty string if none are checked, or
// there are no radio buttons
function getCheckedValue(radioObj) {
	if(!radioObj)
		return "";
	var radioLength = radioObj.length;
	if(radioLength == undefined)
		if(radioObj.checked)
			return radioObj.value;
		else
			return "";
	for(var i = 0; i < radioLength; i++) {
		if(radioObj[i].checked) {
			return radioObj[i].value;
		}
	}
	return "";
}

/*
function getCheckedValue(radioObj)
	{
	if (radioObj.length)
		{
		var radioLength = radioObj.length;
		for(var i = 0; i < radioLength; i++)
			{
			if(radioObj[i].checked)
				{
				return true;
				document.frm.txt_recordid.value = radioObj[i].value;
				}
			}
		}
	else if (radioObj.checked)
		return true;

	return false;
	}
*/	
	/*
function createRadioElement( name, checked ) {
    var radioInput;
    try {
        var radioHtml = '<input type="radio" name="' + name + '"';
        if ( checked ) {
            radioHtml += ' checked="checked"';
        }
        radioHtml += '/>';
        radioInput = document.createElement(radioHtml);
    } catch( err ) {
        radioInput = document.createElement('input');
        radioInput.setAttribute('type', 'radio');
        radioInput.setAttribute('name', name);
        if ( checked ) {
            radioInput.setAttribute('checked', 'checked');
        }
    }

    return radioInput;
}
*/
	
////////////////////////////////////////////////////////////////////////////////
// Removes the given Element (given by its id) from the current document.
// Returns:
//		The Element just removed.
//		null, if the Element did not exist in the document.
////////////////////////////////////////////////////////////////////////////////
function DeleteElement(id)
	{
	var ctl = document.getElementById(id);
	if ( ctl )
		{
		if ( ctl.parentNode )
			{
			return ctl.parentNode.removeChild(ctl);
			}
		}
	return null;
	}	// End DeleteElement()

////////////////////////////////////////////////////////////////////////////////
// Search/Replace in the Attribute of the given document element.
// Search using the given regEx search pattern and replace any found text
// with the given replacement string.
////////////////////////////////////////////////////////////////////////////////
function ReplaceAttributeValue(element, attr, searchPattern, replaceWith)
	{
	if ( element )
		{
		var strAttributeValue = element.getAttribute(attr);
		if ( strAttributeValue )
			{
			if ( strAttributeValue.length )
				{
				//alert("New Attribute value for " + attr + ": " + strAttributeValue);
				// Replace any 'searchPattern' with 'replaceWith'.
				strAttributeValue = strAttributeValue.replace(searchPattern, replaceWith);
				//alert("New Attribute value for " + attr + ": " + strAttributeValue);
				element.setAttribute(attr, strAttributeValue);
				}
			}
		}
	}	// End ReplaceAttributeValue()
			
////////////////////////////////////////////////////////////////////////////////
// Search for the given 'id' and return the value associated with it.
// The given value string is a Form Field value string.
// I.E.:
//		QuestionID=2&PossibleAnswerID=5
//	FieldValue("QuestionID=2&PossibleAnswerID=5", "QuestionID")
//		returns "2"
//	FieldValue("QuestionID=2&PossibleAnswerID=5", "PossibleAnswerID")
//		returns "5"
////////////////////////////////////////////////////////////////////////////////
function FieldValue(str, id)
	{
	var re = new RegExp(id + "=([^&]*)", "");
	var result = str.match(re);
	if ( result )
		{
		//alert("Match 1: " + id + "=" + result[1]);
		return result[1];
		}
	}	// End FieldValue()
	
	
////////////////////////////////////////////////////////////////////////////////
// Return the X position of the mouse cursor within the webpage.
// Argument:
//		Mouse event containing the cursor position.
////////////////////////////////////////////////////////////////////////////////
function mouseX(evt)
	{
	if (evt.pageX)
		return evt.pageX;
	else if (evt.clientX)
		return evt.clientX + (document.documentElement.scrollLeft ?
				document.documentElement.scrollLeft :
				document.body.scrollLeft);
	else
		return null;
	}	// End mouseX()
	
////////////////////////////////////////////////////////////////////////////////
// Return the Y position of the mouse cursor within the webpage.
// Argument:
//		Mouse event containing the cursor position.
////////////////////////////////////////////////////////////////////////////////
function mouseY(evt)
	{
	if (evt.pageY)
		return evt.pageY;
	else if (evt.clientY)
		return evt.clientY + (document.documentElement.scrollTop ?
				document.documentElement.scrollTop :
				document.body.scrollTop);
	else
		return null;
	}	// End mouseY()
	

////////////////////////////////////////////////////////////////////////////////
//
// Return the next HTML Element/Object in the sibling list of the given object.
// This function is necessary because the nextSibling method will include
// blank space as a valid node (nodeType = 1).
// Argument:
//		HTML Element Node whose next sibling is to be returned.
//
////////////////////////////////////////////////////////////////////////////////
function nextObject(n)
	{
	do n = n.nextSibling;
	while (n && n.nodeType != 1);
	return n;
	}
 
////////////////////////////////////////////////////////////////////////////////
//
// Return the previous HTML Element/Object in the sibling list of the given object.
// This function is necessary because the previousSibling method will include
// blank space as a valid node (nodeType = 1).
// Argument:
//		HTML Element Node whose previous sibling is to be returned.
//
////////////////////////////////////////////////////////////////////////////////
function previousObject(n)
	{
	do n = n.previousSibling;
	while (n && n.nodeType != 1);
	return n;
	}
	
////////////////////////////////////////////////////////////////////////////////
// Return the next HTML Element/Object in the sibling list of the given object
// whose element 'id' matches the given regular expression pattern.
// Argument:
//		n			=> HTML Element Node whose next sibling is to be returned.
//		idPattern	=> Regular expression to match against each of the given
//						node's siblings.
////////////////////////////////////////////////////////////////////////////////
function nextObjectWithId(n, idPattern)
	{
	do
		{
		n = n.nextSibling;
		if ( ! n ) break;

		if ( n.nodeType == 1 )
			{
			id = n.getAttribute('id');
			if ( id )
				{
				if ( id.search(idPattern) != -1 )
					break;
				}
			}
		}
	while (1);
	return n;
	}		

////////////////////////////////////////////////////////////////////////////////
// Return the previous HTML Element/Object in the sibling list of the given object
// whose element 'id' matches the given regular expression pattern.
// Argument:
//		n			=> HTML Element Node whose previous sibling is to be returned.
//		idPattern	=> Regular expression to match against each of the given
//						node's siblings.
////////////////////////////////////////////////////////////////////////////////
function previousObjectWithId(n, idPattern)
	{
	do
		{
		n = n.previousSibling;
		if ( ! n ) break;

		if ( n.nodeType == 1 )
			{
			id = n.getAttribute('id');
			if ( id )
				{
				if ( id.search(idPattern) != -1 )
					break;
				}
			}
		}
	while (1);
	return n;
	}		

////////////////////////////////////////////////////////////////////////////////
//
//	Limit the number of characters that can be entered into a <textarea>
//
////////////////////////////////////////////////////////////////////////////////
function LimitText(e, ctl, intMaxLength, ctlCounter)
	{
	var blnResult = true;
	if ( typeof ctlCounter != 'object' )
		ctlCounter = document.getElementById(ctlCounter);

	if (ctl.value.length == intMaxLength && (window.event || e))
		{
		// Alert message if maximum limit is reached.
		// If required Alert can be removed.
		//var msg = "You have reached your maximum limit of characters allowed.";
		//alert(msg);
		// Reached the Maximum length so trim the textarea
		var KeyID = (window.event) ? window.event.keyCode : e.which;
		//alert(KeyID);
		if ( (window.event) ? window.event.ctrlKey : e.ctrlKey )
			{
			blnResult = true;
			}
		else
			{
			if ( KeyID < 48 && KeyID != 32 )
				blnResult = true;
			else
				blnResult = false;
			}
		}
	else if (ctl.value.length > intMaxLength)
		{
		ctl.value = ctl.value.substring(0, intMaxLength);
		}
	
	// Report the current number of characters remaining.
	if ( ctlCounter )		
		ctlCounter.value = intMaxLength - ctl.value.length;

	return blnResult;
	}

////////////////////////////////////////////////////////////////////////////////
//
//	Create a cookie on the local machine
//
////////////////////////////////////////////////////////////////////////////////
    function createCookie(name, value, days) {
        var expires;
        if (days) {
            var date = new Date();
            date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
            expires = "; expires=" + date.toGMTString();
        }
        else expires = "";
        document.cookie = name + "=" + value + expires + "; path=/";
    }

////////////////////////////////////////////////////////////////////////////////
//
//	Read a cookie on the local machine
//
////////////////////////////////////////////////////////////////////////////////
    function readCookie(name) {
        var nameEQ = name + "=";
        var ca = document.cookie.split(';');
        for (var i = 0; i < ca.length; i++) {
            var c = ca[i];
            while (c.charAt(0) == ' ') c = c.substring(1, c.length);
            if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length);
        }
        return null;
    }

////////////////////////////////////////////////////////////////////////////////
//
//	Delete a cookie from the local machine
//
////////////////////////////////////////////////////////////////////////////////
    function eraseCookie(name) {
        createCookie(name, "", -1);
    }

////////////////////////////////////////////////////////////////////////////////
//
//	Determine if cookies are enabled within the current client browser.
//
////////////////////////////////////////////////////////////////////////////////
    function areCookiesEnabled() {
        var r = false;
        createCookie("testing", "Hello", 1);
        if (readCookie("testing") != null) {
            r = true;
            eraseCookie("testing");
        }
        return r;
    }

////////////////////////////////////////////////////////////////////////////////
//
//	Get the current document's url and remove the webpage/filename.
//
////////////////////////////////////////////////////////////////////////////////
function getPathWithoutFilename()
	{
	var pathname = document.location.pathname;
	var iPos = document.location.pathname.toString().toLowerCase().lastIndexOf('/');
	if(iPos>0) return pathname.substring(0, iPos);
	return pathname;
	}
/*
var W3CDOM = (document.createElement && document.getElementsByTagName);

 * Alter all file upload input fields to allow for a special 'Browse' button.
 
function initFileUploads(cmdImageURL)
	{
	if (!W3CDOM) return;
	var fakeFileUpload = document.createElement('div');
	fakeFileUpload.className = 'fakefile';
	fakeFileUpload.appendChild(document.createElement('input'));
	var image = document.createElement('img');
	image.src=cmdImageURL;	//'pix/button_select.gif';
	fakeFileUpload.appendChild(image);
	var x = document.getElementsByTagName('input');
	for (var i=0;i<x.length;i++)
		{
		if (x[i].type != 'file') continue;
		if (x[i].parentNode.className != 'fileinputs') continue;
		x[i].className = 'file hidden';
		var clone = fakeFileUpload.cloneNode(true);
		x[i].parentNode.appendChild(clone);
		x[i].relatedElement = clone.getElementsByTagName('input')[0];
		x[i].onchange = x[i].onmouseout = function ()
			{
			this.relatedElement.value = this.value;
			}
		}
	}
 */

