// These are the common CI JavaScript Functions

// This was created because XHTML does not support target="_blank", in fact it does not support "target" attribute at all.
// So in your "a" tag you use the "rel" attribute, which is for relativity I believe, and assign it the value "external"
// This passes the XHTML validation, and because JavaScript lets you assign the "target" you can open the external link
// in a new window.
function externalLinks() {
	if (!document.getElementsByTagName) return;
	var anchors = document.getElementsByTagName("a");
 	for (var varCounter=0; varCounter<anchors.length; varCounter++) {
   		var anchor = anchors[varCounter];
   		if (anchor.getAttribute("href") && anchor.getAttribute("rel") == "external") {
     		anchor.target = "_blank";
		}
 	}
}
window.onload = externalLinks;

// Create global mouse variables and find the position of the mouse at any given time when the mouse moves
var furthest = 'empty';
var xMouse;
var yMouse;
document.onmousemove = shouldIHide;

// This is used in the CSS menu system. It determines if the mouse is out of the submenu and hides the element and its parents.
function shouldIHide(e) {
	getMousePosition(e);
	var element = getElement(furthest);
	if (element) {
		var topPosition = getTopPosition(furthest);
		var rightPosition = getRightPosition(furthest);
		var bottomPosition = getBottomPosition(furthest);
		var leftPosition = getLeftPosition(furthest);

 		if (xMouse > rightPosition) {
			hideMe(furthest); 
		}
		else if (yMouse < topPosition) {
			hideMe(furthest); 
		}
		else if (yMouse > bottomPosition) {
			hideMe(furthest); 
		}
		else {
			showMe(furthest);
		}
	}
}

function getMousePosition(e) {
	if (!e) {e = window.event}
	xMouse = e.clientX;
	yMouse = e.clientY + getScrollTop();
}

function getScrollTop(){
	if(typeof window.pageYOffset=="number") {
		return window.pageYOffset;
	}
	if(document.documentElement.scrollTop) {
		return Math.max(document.documentElement.scrollTop,document.body.scrollTop);
	}
	/*else if(document.body.scrollTop!=null) {*/
	else {
		return document.body.scrollTop;
	}
	return 0;
}

function getNode(element_id) {
	var theNode;
	for (varCounter = 0; varCounter<nodes.length; varCounter++) {
		if (nodes[varCounter].id == element_id) {
				theNode = varCounter;
				break;
		}
	}
	return theNode;
}

// Grab the Element by id using the id="" attribute in a given xhtml tag which must be unique per page
function getElement(element_id) {
	return document.getElementById ? document.getElementById(element_id) :
	document.all ? document.all(element_id) : null;
}

// The next 4 functions get the position of the 4 points of a given element
function getLeftPosition(element_id) {
	var element = getElement(element_id);
	if (element) {
		xPosition = element.offsetLeft;
		tempElement = element.offsetParent;
		while (tempElement != null) {
			xPosition += tempElement.offsetLeft;
			tempElement = tempElement.offsetParent;
		}
		return xPosition;
	}
}

function getRightPosition(element_id) {
	return getLeftPosition(element_id) + getElement(element_id).offsetWidth;
}

function getTopPosition(element_id) {
	var element = getElement(element_id);
	if (element) {
		yPosition = element.offsetTop;
		tempElement = element.offsetParent;
		while (tempElement != null) {
			yPosition += tempElement.offsetTop;
			tempElement = tempElement.offsetParent;
		}
		return yPosition;
	}
}

function getBottomPosition(element_id) {
	return getTopPosition(element_id) + getElement(element_id).offsetHeight;
}

// The next 6 functions move the first element with respect to the reference element
function moveElementLeft(moving_element_id, reference_element_id) {
	var element = getElement(moving_element_id);
	if (element) {
		var leftPosition = getLeftPosition(reference_element_id);
		element.style.left = leftPosition + 'px';
	}
}

function moveElementRight(moving_element_id, reference_element_id) {
	var element = getElement(moving_element_id);
	if (element) {
		var rightPosition = getRightPosition(reference_element_id);
		element.style.left = rightPosition + 'px';
	}
}

function moveElementTop(moving_element_id, reference_element_id) {
	var element = getElement(moving_element_id);
	if (element) {
		var topPosition = getTopPosition(reference_element_id);
		element.style.top = topPosition + 'px';
	}
}

function moveElementBottom(moving_element_id, reference_element_id) {
	var element = getElement(moving_element_id);
	if (element) {
		var bottomPosition = getBottomPosition(reference_element_id);
		element.style.top = bottomPosition + 'px';
	}
}

function moveElementHorizontalCenter(moving_element_id, reference_element_id) {
	var element = getElement(moving_element_id);
	if (element) {
		var leftPosition = getLeftPosition(reference_element_id);
		leftPosition = (leftPosition + getElement(reference_element_id).offsetWidth/2) - (element.offsetWidth/2);
		element.style.left = leftPosition + 'px';
	}
}

function moveElementVerticalCenter(moving_element_id, reference_element_id) {
	var element = getElement(moving_element_id);
	if (element) {
		var topPosition = getTopPosition(reference_element_id);
		topPosition = (topPosition + getElement(reference_element_id).offsetHeight/2) - (element.offsetHeight/2);
		element.style.top = topPosition + 'px';
	}
}

// Used for the current submenu system where the submenu is positioned at the top and to the right of the menu item
function displaySubmenu(moving_element_id, reference_element_id) {
	moveElementTop(moving_element_id, reference_element_id);
	moveElementRight(moving_element_id, reference_element_id);
	showElement(moving_element_id);
	var parentVisibility = getVisibility(reference_element_id);
	for (varCounter=0; varCounter<arrValues.length; varCounter++) {
		if ((arrValues[varCounter] != moving_element_id) && (parentVisibility == 'hidden')) {
			hideElement(arrValues[varCounter]);
		}
	}
	
}

function hideSubMenus(element_id) {
	var theNode = getNode(element_id);
	for (varCounter=0; varCounter<nodes[theNode].level_ids.length; varCounter++) {
		if (nodes[theNode].level_ids[varCounter] != nodes[theNode].id) {
			hideElement(nodes[theNode].level_ids[varCounter]);
		}
	}
	furthest = 'empty';
}

function showMe(element_id) {
	var theSecondNode;
	var theNode = getNode(element_id);
	moveElementTop(nodes[theNode].id, nodes[theNode].ref_id);
	moveElementRight(nodes[theNode].id, nodes[theNode].ref_id);
	showElement(nodes[theNode].id);
	for (varCounter=0; varCounter<nodes[theNode].level_ids.length; varCounter++) {
		if (nodes[theNode].level_ids[varCounter] != nodes[theNode].id) {
			//theSecondNode = getNode(nodes[theNode].level_ids[varCounter]);
			//window.status = nodes[theNode].level_ids[varCounter];
			hideElement(nodes[theNode].level_ids[varCounter]);
			
			//if (nodes[theSecondNode].child_ids != null) {
			//	for (varSecondCounter=0; varSecondCounter<nodes[theSecondNode].child_ids.length; varSecondCounter++) {
			//		hideElement(nodes[theSecondNode].child_ids[varSecondCounter]);
			//	}
			//}
		}
	}
	furthest = nodes[theNode].id;
	//if (nodes[theNode].parent_id != null) {
	//	showMe(nodes[theNode].parent_id);
	//}
	//alert(furthest);
}

function hideMe(element_id) {
	var theNode = getNode(element_id);
	hideElement(nodes[theNode].id); 
	if (nodes[theNode].parent_id != null) {
		hideMe(nodes[theNode].parent_id);
	}
	furthest = 'empty';
}

// The next 3 functions either show, hide, or return the visibility of an element
function getVisibility(element_id) {
	var element = getElement(element_id);
	if (element) {
		return element.style.visibility;
	}
}

function hideElement(element_id) {
	var element = getElement(element_id);
	if (element) {
		element.style.visibility = 'hidden';
	}
}

function showElement(element_id) {
	var element = getElement(element_id);
	if (element) {
		element.style.visibility = 'visible';
	}
}

// The next 4 functions are used for a block type menu system. For example you click on a plus sign and an extended submenu show up.
// Also good for site maps.
function getBlock(element_id) {
	var element = getElement(element_id);
	if (element) {
		return element.style.display;
	}
}

function showBlock(element_id) {
	var element = getElement(element_id);
	if (element) {
		element.style.display = 'block';
	}
}

function hideBlock(element_id) {
	var element = getElement(element_id);
	if (element) {
		element.style.display = 'none';
	}
}

function blockMenuSystem(element_id) {
	var element = getElement(element_id);
	if (element) {
		var blockStatus = getBlock(element_id);
		if (blockStatus == 'block') {
			hideBlock(element_id);
		}
		else {
			showBlock(element_id);
		}
	}
}

// The 2 functions below get the value or length of a field in a form. The field needs the id attribute, which is required in WCAG 
// because of the for attribute in the label tag.
function getValue(element_id) {
	var element = getElement(element_id);
	if (element) {
		return element.value;
	}
}

function getValueLength(element_id) {
	var element = getElement(element_id);
	if (element) {
		return element.value.length;
	}
}

// The next 7 functions are testing the validity of the data in a form field.
function verifyItemNotEmpty(element_id, error_text) {
	var element = getElement(element_id);
	if (element) {
		var theItem = getValue(element_id);
		if (theItem == '') {
			alert(error_text);
			element.focus();
			return false;
		}
		else {
			return true;
		}
	}
}

function verifyItemsMatch(first_element_id, second_element_id, error_text) {
	var element = getElement(first_element_id);
	if (element) {
		var theItemOne = getValue(first_element_id);
		var theItemTwo = getValue(second_element_id);
		if (theItemOne != theItemTwo) {
			alert(error_text);
			element.focus();
			return false;
		}
		else {
			return true;
		}
	}
}

function verifyItemLength(element_id, element_length, error_text) {
	var element = getElement(element_id);
	if (element) {
		var theItem = getValueLength(element_id);
		if (theItem < element_length) {
			alert(error_text);
			element.focus();
			return false;
		}
		else {
			return true;
		}
	}
}

function verifyItemLengthLessThan(element_id, element_length, error_text) {
	var element = getElement(element_id);
	if (element) {
		var theItem = getValueLength(element_id);
		if (theItem <= element_length) {
			return true;
		}
		else {
			var message = error_text + "\nThe current character count is: " + theItem + ".";
			alert(message);
			element.focus();
			return false;
		}
	}
}

function verifyItemHasDigits(element_id, number_of_digits, error_text) {
	var element = getElement(element_id);
	if (element) {
		var theRegularExpression = '';
		for (varCounter=1; varCounter<number_of_digits+1; varCounter++) {
			theRegularExpression = theRegularExpression + '[0-9]';
		}
		var regNumberOfDigits = new RegExp(theRegularExpression);
		var theItem = getValue(element_id);
		if (!(regNumberOfDigits.test(theItem))) {
			alert(error_text);
			element.focus();
			return false;
		}
		else {
			return true;
		}
	}
}

function verifyItemIsNumber(element_id,  error_text) {
	var element = getElement(element_id);
	if (element) {
		var theItem = getValue(element_id);
		if (!(isFinite(theItem))) {
			alert(error_text);
			element.focus();
			return false;
		}
		else {
			return true;
		}
	}
}


function verifyItemHasLowercase(element_id, error_text) {
	var element = getElement(element_id);
	if (element) {
		var theRegularExpression = '[a-z]';
		var regLowercase = new RegExp(theRegularExpression);
		var theItem = getValue(element_id);
		if (!(regLowercase.test(theItem))) {
			alert(error_text);
			element.focus();
			return false;
		}
		else {
			return true;
		}
	}
}

function verifyItemHasUppercase(element_id, error_text) {
	var element = getElement(element_id);
	if (element) {
		var theRegularExpression = '[A-Z]';
		var regUppercase = new RegExp(theRegularExpression);
		var theItem = getValue(element_id);
		if (!(regUppercase.test(theItem))) {
			alert(error_text);
			element.focus();
			return false;
		}
		else {
			return true;
		}
	}
}

function verifyItemHasSpecial(element_id, error_text) {
	var element = getElement(element_id);
	if (element) {
		var theRegularExpression = '[^A-Za-z0-9]';
		var regSpecial= new RegExp(theRegularExpression);
		var theItem = getValue(element_id);
		if (!(regSpecial.test(theItem))) {
			alert(error_text);
			element.focus();
			return false;
		}
		else {
			return true;
		}
	}
}

function verifyDate(month_element_id, day_element_id, year_element_id) {
	var element = getElement(month_element_id);
	if (element) {
		var theMonth = getValue(month_element_id);
		var theDay = getValue(day_element_id);
		var theYear = getValue(year_element_id);
		var theResult = isDate(theMonth, theDay, theYear);
		if (!theResult) {
			alert('This is not a valid date.');
			element.focus();
			return false;
		}
		else {
			return true;
		}
	}
}

// This changes the display status of a field with reference to a value in another field
function changeFieldStatus(test_element_id, test_value, result_element_id) {
	var test_element = getElement(test_element_id);
	var result_element = getElement(result_element_id);
	if (test_element) {
		var theItem = getValue(test_element_id);
		if (theItem == test_value) {
			enableField(result_element_id);
		}
		else {
			disableField(result_element_id);
		}
	}
}

// The next 3 functions clear, enable, or disable a field.
function clearField(element_id) {
	var element = getElement(element_id);
	if (element) {
		element.value = '';
	}
}

function disableField(element_id) {
	var element = getElement(element_id);
	if (element) {
		element.disabled = true;
		element.style.backgroundColor = 'lightgrey';
	}
}

function enableField(element_id) {
	var element = getElement(element_id);
	if (element) {
		element.disabled = false;
		element.style.backgroundColor = 'white';
		element.value = '12345678';
	}	
}

// This checks that a given date is a valid one.
function isDate(theMonth, theDay, theYear) {
	if (theMonth < 1 || theMonth > 12) {
        return false;
    }

    if (theDay < 1 || theDay > 31) {
        return false;
    }

    if ((theMonth==4 || theMonth==6 || theMonth==9 || theMonth==11) && theDay==31) {
        return false;
    }

    if (theMonth == 2) { // check for february 29th
        var isLeapYear = (theYear % 4 == 0 && (theYear % 100 != 0 || theYear % 400 == 0));
        if (theDay > 29 || (theDay==29 && !isLeapYear)) {
            return false;
        }
    }
    return true; // date is valid
}

// These two functions are for displaying table data by changing the BG color every other row
// This function is needed to work around a bug in IE related to element attributes
function hasClass(element_id) {
	var theResult = false;
	if (element_id.getAttributeNode("class") != null) {
		theResult = element_id.getAttributeNode("class").value;
	}
	return theResult;
}

function stripeTableRows(element_id) {
	var theColorIndicator = false;
    // if arguments are provided to specify the colors of the even & odd rows, then use the them; otherwise use the following defaults:
    var evenColor = arguments[1] ? arguments[1] : "#fff";
    var oddColor = arguments[2] ? arguments[2] : "#eee";
  
    // obtain a reference to the desired table if no such table exists, abort
    var theTable = document.getElementById(element_id);
    if (! theTable) { return; }
    
    // by definition, tables can have more than one tbody element, so we'll have to get the list of child <tbody> and loop through them
    var theTBody = theTable.getElementsByTagName("tbody");
    for (var h = 0; h < theTBody.length; h++) {
    	// find all the <tr> elements and loop through them 
		var theTRs = theTBody[h].getElementsByTagName("tr");
      	for (var i = 0; i < theTRs.length; i++) {
			// avoid rows that have a class attribute or backgroundColor style
        	if (! hasClass(theTRs[i]) && ! theTRs[i].style.backgroundColor) {
				// get all the cells in this row and loop through them
          		var theTDs = theTRs[i].getElementsByTagName("td");
          		for (var j = 0; j < theTDs.length; j++) {
            		var theCurrentTD = theTDs[j];
					// avoid cells that have a class attribute or backgroundColor style
            		if (! hasClass(theCurrentTD) && ! theCurrentTD.style.backgroundColor) {
						theCurrentTD.style.backgroundColor = theColorIndicator ? evenColor : oddColor;
					}
				}
			}
			// flip theRow from false to true, or vice-versa
			theColorIndicator =  ! theColorIndicator;
		}
	}
}

function highlightTableRow()
{
	if (document.getElementById && document.createTextNode) {
   		var tables=document.getElementsByTagName('table');
   		for (var i=0;i<tables.length;i++) {
    		if(tables[i].className=='ruler') {
     			var trs=tables[i].getElementsByTagName('tr');
     			for(var j=0;j<trs.length;j++) {
      				if(trs[j].parentNode.nodeName=='TBODY' && trs[j].parentNode.nodeName!='TFOOT') {
       					trs[j].onmouseover=function(){this.className='ruled';return false}
						trs[j].onmouseout=function(){this.className='';return false}
		 			}
    			}
   			}
  		}
 	}
}
