// $Header: http://77.68.60.202/repos/tags/B3_XDEV1/sites/b3accounts/js/generic.js 10027 2011-12-07 10:39:18Z lance $

var xmlHttp;

function GetXmlHttpObject()
{
	var xmlHttp=null;
	
	try
	{
		// Firefox, Opera 8.0+, Safari
		xmlHttp=new XMLHttpRequest();
	}
	
	catch (e)
	{
		//Internet Explorer
		try
		{
			xmlHttp=new ActiveXObject("Msxml2.XMLHTTP");
		}
		
		catch (e)
		{
			xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
		}
	}
	
	return xmlHttp;
}

// THIS FUNCTION SHOWS LOADING IMAGE WHILE WAITING FOR SERVER CALLS

function showLoading(sElementId)
{
	if(document.getElementById(sElementId))
	{
		document.getElementById(sElementId).innerHTML = '<img src="../images/ajax_loading.gif" />';
	}
}

function triggerOnclickWithEnter(oEvent, oElement)
{
	if(oEvent.keyCode == 13)
	{
		oElement.onclick();
	}
}

// THIS FUNCTION TAKES AN ELEMENT AND DETERMINES WHETHER IT HAS A CERTAIN 
// CLASS NAME - REQUIRED FOR MULTIPLE CLASSES ON THE SAME ELEMENT AS OPPOSED TO
// USING EL.CLASSNAME
function isClassOfElement(el, cl) {
	aClasses = el.className.split(" ");
	for(var i=0; i<aClasses.length; i++) {
		aClasses[i].trim();
		if(aClasses[i] == cl) return true;
	}
	
	return false;
}

function stripClass(el, cl) {
	aClasses = el.className.split(" ");
	for(var i=0; i<aClasses.length; i++) {
		aClasses[i].trim();
		if(aClasses[i] == cl) delete aClasses[i];
	}
	el.className = aClasses.join(" ");
	
	return true;
}

function addClass(el, cl) {
	if(! isClassOfElement(el, cl)) {
		el.className = el.className.trim();
		
		if(el.className != "") el.className+= " " + cl;
		else el.className = cl;
	}
	
	return true;
}

function getElementsByClass(searchClass,node,tag) {
	var classElements = new Array();
	if ( node == null )
		node = document;
	if ( tag == null )
		tag = "*";
	var els = node.getElementsByTagName(tag);
	var elsLen = els.length;
	var pattern = pattern = new RegExp("(^|\\s)"+searchClass+"(\\s|$)");
	for (i = 0, j = 0; i < elsLen; i++) {
		if ( pattern.test(els[i].className) ) {
			classElements[j] = els[i];
			j++;
		}
	}
	return classElements;
}

function fnDoNav(sUrl)
{
	document.location.href = sUrl;
}

function fnOpenNewWindow(sUrl)
{
	window.open('/'+sUrl);
}


var gaVisibleSubMenus = new Array; // this will contain a reference to the currently displayed submenu

// stop bubble effect
// this is where onmouseover if activated for the active parent (where the cursor is) and that event 
// triggers; however, the parent menu is triggered and that parent menu and so on .. this is causing 
// problems. So,hense the flag (see code)
var gbStopBubbling = false;

function showSubMenu(oItem, iLevel) {
	
	if(! iLevel) iLevel = 0;
	
	// this will not allow us to continue if stop bubbling is on (=true). If stop bubbling is
	// turned off
	if(gbStopBubbling) {
		if(iLevel == 0) gbStopBubbling = false
		
		return false;
	}
	
	// this part here will hide any submenus open for this level and further (if any)
	i=iLevel;
	while(gaVisibleSubMenus[i]) {
		gaVisibleSubMenus[i].style.display = "none";
		gaVisibleSubMenus[i] = null;
		i++;
	}
	
	// find the submenu we wish to open
        if (oItem) {
            for(var i=0; i<oItem.childNodes.length; i++) {
                    if(oItem.childNodes[i].tagName == "UL") {
                            oItem.childNodes[i].style.display = "block";
                            gaVisibleSubMenus[iLevel] = oItem.childNodes[i];
                    }
            }
        }
	
	// be setting this to true bubble wont happen. This flag will be reset when we
	// hit the top level again
	gbStopBubbling = true;
	
}

function closeMenus() {
    var oTopMenu = document.getElementById('topMenu');
    for (var child1 in oTopMenu.children) {
        //child1 = oTopMenu.children[child1];
        for (var child2 in oTopMenu.children[child1].children) {
            //child2 = child1.children[child2];
            //alert(oTopMenu.children[child1].children[child2].nodeName);
            if (oTopMenu.children[child1].children[child2].nodeName == 'UL' && oTopMenu.children[child1].children[child2].getAttribute('id')!='homeMenuItem') {
                oTopMenu.children[child1].children[child2].style.display = 'none';
            }
        }
    }
    showSubMenu(document.getElementById('homeMenuItem'));
}

function popup(url, name, settings) {
	if(! settings) settings = "resizable=yes,scrollbars=yes,status=yes,width=990,height=720";
	
	var newWindow = window.open(url, name, settings);
	newWindow.focus();
	newWindow.moveTo(0,0);
}


function closePopup()
{
	window.close();
	window.opener.focus();
}

var otherTypes = 0;
function fnPopUp(popupname,sWidth,sHeight,oForm,popupUrl)
{
	if(oForm)
	{
		var selectedvalue = oForm.project.value;
	}
	else
	{
		var selectedvalue = document.getElementById(popupname).value;
	}
	if(selectedvalue == "[Add New]")
	{
                if (popupUrl) {
                    popupUrl = popupUrl ;
                } else {
                    popupUrl = popupname+'.php';
                }
		var newWindow = window.open('/'+popupUrl+"&isPopup=1&bPopup=true&otherTypes="+otherTypes,"_blank","width="+sWidth+", height="+sHeight+", toolbar=yes, location=yes, menubar=yes, scrollbars=yes, resizable=yes, copyhistory=yes");
	
		newWindow.focus();
		newWindow.moveTo(0,0);
	}
}

function fnPopUpWindow(popuplink)
{
	var newWindow = window.open(popuplink,"_blank","width=840, height=495, toolbar=yes, location=yes, menubar=yes, scrollbars=yes, resizable=yes, copyhistory=yes");
	
	newWindow.focus();
	newWindow.moveTo(0,0);
}

/************** HIDE ELEMENT WITH TIME **************/

var timerID;

function fnHideTimedLayer(sElementId)
{
	//if(document.getElementById(sElementId))
	{
		clearTimeout(timerID);
		
		clearInnerHtml(document.getElementById(sElementId));
		
		//document.getElementById(sElementId).style.display = "none";
	}
}

function fnTimedLayer(sElementId, iMilliSec)
{
	if(iMilliSec)
	{
		//
	}
	
	else
	{
		iMilliSec = 10000; // 10 seconds
	}
		
	//if(document.getElementById(sElementId))
	{
		setTimeout("fnHideTimedLayer(\"" + sElementId + "\")", iMilliSec);
	}
}


/******************* ALERTBOX FUNCTIONS *******************/

function fnAlert(sAlertMessage, sOnFocusObj)
{
	alert(sAlertMessage);
	
	clearInputErrorHighlights();
	
	if(sOnFocusObj)
	{
		sOnFocusObj.focus();
	
		addClass(sOnFocusObj, "inputError");
	}
}


function clearInputErrorHighlights()
{
	var aElements = getElementsByClass("inputError");
	
	for(var i=0; i<aElements.length; i++) {
		stripClass(aElements[i], "inputError");
	}
}



/******************* DATE TIME FUNCTIONS  *******************/



function dateFormat(oDate, sFormat)
{
	var sFormattedDate;
	
	var iDate = oDate.getDate();
	
	if(iDate < 10)
	{
		iDate = "0" + iDate;
	}
	
	var iMonth = oDate.getMonth();
	
	iMonth = iMonth + 1;
	
	if(iMonth < 10)
	{
		iMonth = "0" + iMonth;
	}
	
	var iYear = oDate.getFullYear();
	
	
	switch(sFormat) {
		
		case "dd-mm-yyyy" : 
			sFormattedDate = iDate + "-"+ iMonth + "-"+ iYear;
			break;
		
		case "mm-dd-yyyy" : 
			sFormattedDate = iMonth + "-"+ iDate + "-"+ iYear;
			break;
		
		case "yyyy-mm-dd" : 
			sFormattedDate = iYear + "-"+ iMonth + "-"+ iDate;
			break;
			
		case "dd/mm/yyyy" : 
			sFormattedDate = iDate + "/"+ iMonth + "/"+ iYear;
			break;
		
		case "mm/dd/yyyy" : 
			sFormattedDate = iMonth + "/"+ iDate + "/"+ iYear;
			break;
		
		case "yyyy/mm/dd" : 
			sFormattedDate = iYear + "/"+ iMonth + "/"+ iDate;
			break;
		
		default : 
			sFormattedDate = iDate + "-"+ iMonth + "-"+ iYear;
			break;
		
	}
	
	return sFormattedDate;
}


/*******************  *******************/

var gsSelectedTab;


// extends String set of functions to include trim()
String.prototype.trim = function() {
	a = this.replace(/^\s+/, "");
	return a.replace(/\s+$/, "");
};


function showHideTab(oLink, sTabId) {
	
	var oMenu;
	var oTab;
	
	// links
	// first, unselect
	oMenu = oLink

        while(oMenu.tagName != "UL") {
                oMenu = oMenu.parentNode;
        }

        aLinks = oMenu.getElementsByTagName("A");
        for(var i=0; i<aLinks.length; i++) {
                stripClass(aLinks[i], "selected");
        }

	
	// now select the one we want
	addClass(oLink, "selected");
	
	// tabs
	
	oTab = document.getElementById(sTabId);
	
	// hide all by fetching the parents and hiding the children
	aTabs = getElementsByClass("tab", oTab.parentNode);
	for(var i=0; i<aTabs.length; i++) {
		aTabs[i].style.display = "none";
	}
	
	// show the tab
	oTab.style.display = "block";
	
	gsSelectedTab = sTabId;
	oLink.blur();
	
}


function showHideAllByElementClassImageChange(sClassName, iShow)
{
	var aElements = getElementsByClass(sClassName);
	
	for(var i=0; i<aElements.length; i++) {
		fnShowHideByElementClassImageChange(aElements[i].name, aElements[i].id, iShow);
	}
}



function showHideStripAddClassImageChange(sElementClass,sImageId, sStripAddClass)
{
	var aElements = getElementsByClass(sElementClass);
	
	var sImageSource = document.getElementById(sImageId).src;
	
	sImageSource = sImageSource.toLowerCase();
	
	if(sImageSource.indexOf("minus.gif") == -1)
	{
		for(var i=0; i<aElements.length; i++) {
			stripClass(aElements[i], sStripAddClass);
		}
		document.getElementById(sImageId).src = "../images/minus.gif";
	}
	else
	{
		for(var i=0; i<aElements.length; i++) {
			addClass(aElements[i], sStripAddClass);
		}
		document.getElementById(sImageId).src = "../images/plus.gif";
	}
}


function fnShowHideByElementClassImageChange(sElementClass,sImageId, iShow)
{
	var aElements = getElementsByClass(sElementClass);
	
	var sImageSource = document.getElementById(sImageId).src;
	
	sImageSource = sImageSource.toLowerCase();
	
	if(iShow == 0)
	{
		for(var i=0; i<aElements.length; i++) {
			aElements[i].style.display = "none";
		}
		document.getElementById(sImageId).src = "../images/plus.gif";
	}
	
	else if(iShow == 1)
	{
		for(var i=0; i<aElements.length; i++) {
			aElements[i].style.display = "";
		}
		document.getElementById(sImageId).src = "../images/minus.gif";
	}
	
	else
	{
		if(sImageSource.indexOf("minus.gif") == -1)
		{
			for(var i=0; i<aElements.length; i++) {
				aElements[i].style.display = "";
			}
			document.getElementById(sImageId).src = "../images/minus.gif";
		}
		else
		{
			for(var i=0; i<aElements.length; i++) {
				aElements[i].style.display = "none";
			}
			document.getElementById(sImageId).src = "../images/plus.gif";
		}
	}
}


function fnShowHideByElementIdImageChange(sElementId,sImageId)
{
	if(document.getElementById(sElementId))
	{
		var sDisplay = document.getElementById(sElementId).style.display;
		
		if(sDisplay == "none")
		{
			document.getElementById(sElementId).style.display = "";
			document.getElementById(sImageId).src = "../images/minus.gif";
		}
		else
		{
			document.getElementById(sElementId).style.display = "none";
			document.getElementById(sImageId).src = "../images/plus.gif";
		}
	}
}


function fnShowHideByElementId(sElementId, iShow)
{
	if(document.getElementById(sElementId))
	{
		if(iShow)
		{
			document.getElementById(sElementId).style.display = "";
		}
		else
		{
			document.getElementById(sElementId).style.display = "none";
		}
	}
}

function showHideElementByCheckBoxId(oCheckBox, oElement, iReverse)
{
	if(document.getElementById(oElement))
	{
		if(iReverse)
		{
			if(oCheckBox.checked)
			{
				document.getElementById(oElement).style.display = "none";
			}
			else
			{
				document.getElementById(oElement).style.display = "";
			}
		}
		else
		{
			if(oCheckBox.checked)
			{
				document.getElementById(oElement).style.display = "";
			}
			else
			{
				document.getElementById(oElement).style.display = "none";
			}
		}
	}
}

function showHideElementClassByCheckBoxId(oCheckBox, sElementClass, iReverse)
{
	var aElements = getElementsByClass(sElementClass);
	
	if(iReverse)
	{
		if(oCheckBox.checked)
		{
			for(var i=0; i < aElements.length; i++) {
				aElements[i].style.display = "none";
			}
		}
		else
		{
			for(var i=0; i < aElements.length; i++) {
				aElements[i].style.display = "";
			}
		}
	}
	else
	{
		if(oCheckBox.checked)
		{
			for(var i=0; i < aElements.length; i++) {
				aElements[i].style.display = "";
			}
		}
		else
		{
			for(var i=0; i < aElements.length; i++) {
				aElements[i].style.display = "none";
			}
		}
	}
}


function loadInnerHtml(oElement, sHtml)
{
	if(oElement)
	{
		if(sHtml)
		{
			oElement.innerHTML = sHtml;
		}
	}
}


function clearInnerHtml(oElement)
{
	if(oElement)
	{
		oElement.innerHTML = "";
	}
}


function toggleExclude(oChkElement, sElementClass, sAddStripClass)
{
	var aElements = getElementsByClass(sElementClass);
	
	var sFunctionName = (oChkElement.checked) ? addClass : stripClass ;
	
	for(var i=0; i<aElements.length; i++) {
		sFunctionName(aElements[i], sAddStripClass);
	}
}



/*******************  LOGIN VALIDATION SCRIPT   *******************/

function fnValidate(oForm)
{
	
	if(! oForm) oForm = document.loginform;
	
	if(oForm.elements.username.value == "")
	{
		fnAlert("Please enter Username", oForm.elements.username);
		return false;
	}
	if(oForm.elements.password.value == "")
	{
		fnAlert("Please enter a password", oForm.elements.password);
		return false;
	}
	oForm.action = "/sessionHandler.php";
	oForm.sessionHandlerLogin.value = "validateLogin";
	oForm.method = "POST";
	oForm.submit();
}

function validateUsername(oElement)
{
	var sUsername = oElement.value;
	
	if(sUsername != "")
	{
		// MAKE AJAX CALL
		
		var oAjax = new AjaxWrapper;
		
		var sUrl = "selectHandler.php?selectHandler=checkUserAvailability";
		
		sUrl = sUrl + "&username=" + sUsername;
		
		sUrl = sUrl + "&sid=" + Date() + Math.random();
		
		oAjax.url = sUrl;
		
		oAjax.onSuccess = function() {
		
			var sResponse = this.responseText;
			
			var aResponse = sResponse.split("{}");
			
			loadInnerHtml(document.getElementById("validationMessage"), aResponse[0]);
			
		};
		
		oAjax.get();
		
		showLoading("validationMessage");
	}
}


function signUpForTrial(oForm)
{
	if(!fnecheck(document.getElementById('email').value))
	{
		document.getElementById('email').focus();
                alert("Please enter a valid email address.");
		return false;
	}
	
	if(document.getElementById('captchatext').value == "" || document.getElementById('captchatext').value != document.getElementById("captchacodenumber").value)
	{
		document.getElementById("captchatexterror").innerHTML = "Incorrect Code !!";
		addClass(document.getElementById('captchatext'), " inputError ");
		document.getElementById('captchatext').select();
		document.getElementById('captchatext').focus();
                alert("Please enter the correct captcha.");
		return false;
	}
	
	var fullname = document.getElementById('fullname').value;
	
	var username = document.getElementById('email').value;
	
	var address1 = document.getElementById('address1').value;
	
	var address2 = document.getElementById('address2').value;
	
	var town_city = document.getElementById('town_city').value;
	
	var postcode = document.getElementById('postcode').value;
	
	var phonenumber = document.getElementById('phonenumber').value;
	
	/*// MAKE AJAX CALL

	var oAjax = new AjaxWrapper;
	
	var sUrl = "registeruser?username=" + sUserName;

	sUrl = sUrl + "&password=" + sPassword;

	sUrl = sUrl + "&fullname=" + sFullName;

	sUrl = sUrl + "&email=" + sEmail;
	
	sUrl = sUrl + "&sid=" + Date() + Math.random();
	
	oAjax.url = sUrl;
	
	oAjax.onSuccess = function() {
		
		var sResponseText = this.responseText;
		
		if(sResponseText == 0) // SUCCESS
		{ */
			// MAKE AJAX CALL 

	     var oAjax = new AjaxWrapper;
			
			var sUrl = "saveHandler.php?saveHandler=signUpForTrial";
			
			sUrl = sUrl + "&fullname=" + fullname;
			
			sUrl = sUrl + "&username=" + username;
			
			sUrl = sUrl + "&address1=" + address1;
			
			sUrl = sUrl + "&address2=" + address2;
			
			sUrl = sUrl + "&town_city=" + town_city;
			
			sUrl = sUrl + "&postcode=" + postcode;
			
			sUrl = sUrl + "&phonenumber=" + phonenumber;
			
			oAjax.url = sUrl;
			
			oAjax.onSuccess = function() {

				loadInnerHtml(document.getElementById("mainMiddleContent"), this.responseText);

			};
			
			oAjax.get();
		/*}
		
	};
                        
	
	oAjax.get();*/
	
	oForm.submitButton.value = "Please Wait...";
	
	oForm.submitButton.disabled = "disabled";
	
	showLoading("loadingData");
	
	oForm.elements.fullname.readOnly = true;
	
	oForm.elements.email.readOnly = true;
	
	oForm.elements.address1.readOnly = true;
	
	oForm.elements.address2.readOnly = true;
	
	oForm.elements.town_city.readOnly = true;
	
	oForm.elements.postcode.readOnly = true;
	
	oForm.elements.phonenumber.readOnly = true;
	
	oForm.elements.captchatext.readOnly = true;
}

/******************************* GENERIC FUNCTIONS *******************************/


/******************* DISPALY NONE *******************/

function fnDisplayNone(displayid)
{
	document.getElementById(displayid).style.display="none";
}


/******************* WHETHER A NUMBER IS NUMERIC *******************/

function fnIsNumeric(stringvalue)
{
	var numericExpression = /^[0-9\.]+$/;
	if(!(stringvalue.match(numericExpression)))
	{
		return false;
	}
	return true;
}


function isNumberKey(evt)
{
	var charCode = (evt.which) ? evt.which : event.keyCode;
	
	if (charCode > 31 && (charCode < 48 || charCode > 57))
		return false;

	return true;
}


/******************* WHETHER A NUMBER IS ALPHABET *******************/

function fnIsAlpha(stringvalue)
{
	var alphaExpression = /^[a-zA-Z]+$/;
	if(!(stringvalue.match(alphaExpression)))
	{
		return false;
	}
}


function isAlphaKey(evt)
{
	var charCode = (evt.which) ? evt.which : event.keyCode;
	
	if (charCode > 31 && (charCode < 48 || charCode > 57))
		return false;

	return true;
}

/******************* WHETHER A STRING IS ALPHA-NUMERIC *******************/

function fnIsAlphaNumeric(stringvalue)
{
	var alphaNumericExpression = /^[0-9a-zA-Z]+$/;
	if(!(match(alphaNumericExpression)))
	{
		return false;
	}
}


function isAlphaNumericKey(evt)
{
	var charCode = (evt.which) ? evt.which : event.keyCode;
	
	if (charCode > 31 && (charCode < 48 || charCode > 57))
		return false;

	return true;
}

/******************* WHETHER A STRING HAS SPECIAL CHARECTERS *******************/

function isSpecialChar(checkString)
{
	var iChars = "!@#$%^&*()+=-[]\';,./{}|\":<>?";
	
	for (var i = 0; i < checkString.length; i++)
	{
		if (iChars.indexOf(checkString.charAt(i)) != -1)
		{
			return true;
		}
	}
}

/*******************   PHONE NUMBER VALIDATION SCRIPT   *******************/
var digits = "0123456789";
// non-digit characters which are allowed in phone numbers
var phoneNumberDelimiters = "()- ";
// characters which are allowed in international phone numbers (a leading + is OK)
var validWorldPhoneChars = phoneNumberDelimiters + "+";
// Minimum no of digits in an international phone no.
var minDigitsInIPhoneNumber = 10;

function isInteger(s)
{   var i;
    for (i = 0; i < s.length; i++)
    {   
        // Check that current character is number.
        var c = s.charAt(i);
        if (((c < "0") || (c > "9"))) return false;
    }
    // All characters are numbers.
    return true;
}
function trim(s)
{   var i;
    var returnString = "";
    // Search through strings characters one by one.
    // If character is not a whitespace, append to returnString.
    for (i = 0; i < s.length; i++)
    {   
        // Check that current character is not whitespace.
        var c = s.charAt(i);
        if (c != " ") returnString += c;
    }
    return returnString;
}
function stripCharsInBag(s, bag)
{   var i;
    var returnString = "";
    // Search through strings characters one by one.
    // If character is not in bag, append to returnString.
    for (i = 0; i < s.length; i++)
    {   
        // Check that current character is not whitespace.
        var c = s.charAt(i);
        if (bag.indexOf(c) == -1) returnString += c;
    }
    return returnString;
}

function checkInternationalPhone(strPhone){
var bracket=3
strPhone=trim(strPhone)
if(strPhone.indexOf("+")>1) return false
if(strPhone.indexOf("-")!=-1)bracket=bracket+1
if(strPhone.indexOf("(")!=-1 && strPhone.indexOf("(")>bracket)return false
var brchr=strPhone.indexOf("(")
if(strPhone.indexOf("(")!=-1 && strPhone.charAt(brchr+2)!=")")return false
if(strPhone.indexOf("(")==-1 && strPhone.indexOf(")")!=-1)return false
s=stripCharsInBag(strPhone,validWorldPhoneChars);
return (isInteger(s) && s.length >= minDigitsInIPhoneNumber);
}

/*******************   EMAIL-ID VALIDATION SCRIPT   *******************/

function fnecheck(str) {

		var at="@"
		var dot="."
		var lat=str.indexOf(at)
		var lstr=str.length
		var ldot=str.indexOf(dot)
		if (str.indexOf(at)==-1){
		   alert("Invalid E-mail!")
		   return false
		}

		if (str.indexOf(at)==-1 || str.indexOf(at)==0 || str.indexOf(at)==lstr){
		   alert("Invalid E-mail!")
		   return false
		}

		if (str.indexOf(dot)==-1 || str.indexOf(dot)==0 || str.indexOf(dot)==lstr){
		    alert("Invalid E-mail!")
		    return false
		}

		 if (str.indexOf(at,(lat+1))!=-1){
		    alert("Invalid E-mail!")
		    return false
		 }

		 if (str.substring(lat-1,lat)==dot || str.substring(lat+1,lat+2)==dot){
		    alert("Invalid E-mail!")
		    return false
		 }

		 if (str.indexOf(dot,(lat+2))==-1){
		    alert("Invalid E-mail!")
		    return false
		 }
		
		 if (str.indexOf(" ")!=-1){
		    alert("Invalid E-mail!")
		    return false
		 }

 		 return true
	}

/*******************  BACK BUTTON DISABLE SCRIPT  *******************/

function backButtonOverride()
{
	// Work around a Safari bug
	// that sometimes produces a blank page
	setTimeout("backButtonOverrideBody()", 0);

}

function backButtonOverrideBody()
{
	// Works if we backed up to get here
	try {
		history.forward();
	} catch (e) {
		// OK to ignore
	}
	// Every quarter-second, try again. The only
	// guaranteed method for Opera, Firefox,
	// and Safari, which do not always call
	// onLoad but *do* resume any timers when
	// returning to a page
	setTimeout("backButtonOverrideBody()", 500);
}


/******************* READONLY STYLE CHANGE FUNCTION *******************/

function fnReadOnlyFields()
{
	var el, els, e, f = 0, sForm, forms = document.getElementsByTagName("form");
	while (sForm = forms.item(f++))
	{
		e = 0; els = sForm.getElementsByTagName("input");
		while (el = els.item(e++))
			if (el.readOnly)
				el.className = "readonly";
	}
}


/******************* BROSWE FOLDER TREE STRUCTURE FUNCTION *******************/

function init_php_file_tree() {
	if (!document.getElementsByTagName) return;
	
	var aMenus = document.getElementsByTagName("LI");
	for (var i = 0; i < aMenus.length; i++) {
		var mclass = aMenus[i].className;
		if (mclass.indexOf("pft-directory") > -1) {
			var submenu = aMenus[i].childNodes;
			for (var j = 0; j < submenu.length; j++) {
				if (submenu[j].tagName == "A") {
					
					submenu[j].onclick = function() {
						var node = this.nextSibling;
											
						while (1) {
							if (node != null) {
								if (node.tagName == "UL") {
									var d = (node.style.display == "none")
									node.style.display = (d) ? "block" : "none";
									this.className = (d) ? "open" : "closed";
									return false;
								}
								node = node.nextSibling;
							} else {
								return false;
							}
						}
						return false;
					}
					
					submenu[j].className = (mclass.indexOf("open") > -1) ? "open" : "closed";
				}
				
				if (submenu[j].tagName == "UL")
					submenu[j].style.display = (mclass.indexOf("open") > -1) ? "block" : "none";
			}
		}
	}
	return false;
}


/******************* MULTIPLE UPLOAD SCRIPT *******************/

function MultiSelector( list_target, max ){

	// Where to write the list
	this.list_target = list_target;
	// How many elements?
	this.count = 0;
	// How many elements?
	this.id = 0;
	// Is there a maximum?
	if( max ){
		this.max = max;
	} else {
		this.max = -1;
	};
	
	/**
	 * Add a new file input element
	 */
	this.addElement = function( element ){

		// Make sure it is a file input element
		if( element.tagName == "INPUT" && element.type == "file"){

			// Element name -- what number am I?
			//element.name = "file_" + this.id++;
			element.name = "attachment[]";

			// Add reference to this object
			element.multi_selector = this;

			// What to do when a file is selected
			element.onchange = function(){

			// TO CHECK THE EXTENSION OF THE FILE
			var sFile = element.value;
			
			var filenameLength = sFile.length;
			
			var uploadfileExt = sFile.substring(filenameLength-4);
			
			uploadfileExt = uploadfileExt.toLowerCase();
			
			if(uploadfileExt != ".pdf" && uploadfileExt != ".zip")
			{
				alert("Please Select a PDF / ZIP File to Upload!");
				return false;
			}
			
			// NEW FILE INPUT
			var new_element = document.createElement( "input" );
			new_element.type = "file";

			// ADD NEW ELEMENT
			this.parentNode.insertBefore( new_element, this );

			// APPLY UPDATE TO ELEMENT
			this.multi_selector.addElement( new_element );

			// UPDATE LIST
			this.multi_selector.addListRow( this );

			// HIDE THIS: WE CANT USE DISPLAY:NONE BECAUSE SAFARI DOESNT LIKE IT
			this.style.position = "absolute";
			this.style.left = "-1000px";

		};
			// IF WEVE REACHED MAXIMUM NUMBER, DISABLE INPUT ELEMENT
			if( this.max != -1 && this.count >= this.max ){
				element.disabled = true;
			};

			// FILE ELEMENT COUNTER
			this.count++;
			// MOST RECENT ELEMENT
			this.current_element = element;
			
		} else {
			// THIS CAN ONLY BE APPLIED TO FILE INPUT ELEMENTS!
			alert( "Error: Not a file input element" );
		};

	};


	 // ADD A NEW ROW TO THE LIST OF FILES
	this.addListRow = function( element ){

		// ROW DIV
		var new_row = document.createElement( "div" );

		// DELETE BUTTON
		/*var new_row_button = document.createElement( "input" );
		new_row_button.type = "button";
		new_row_button.value = "Delete";*/
		var new_row_button = document.createElement( "img" );
		new_row_button.src = "../images/stop-sign.png";
		new_row_button.value = "Delete";

		// REFERENCES
		new_row.element = element;

		// DELETE FUNCTION
		new_row_button.onclick= function(){

			// REMOVE ELEMENT FROM FORM
			this.parentNode.element.parentNode.removeChild( this.parentNode.element );

			// REMOVE THIS ROW FROM THE LIST
			this.parentNode.parentNode.removeChild( this.parentNode );

			// DECREMENT COUNTER
			this.parentNode.element.multi_selector.count--;

			// RE-ENABLE INPUT ELEMENT (IF ITS DISABLED)
			this.parentNode.element.multi_selector.current_element.disabled = false;

			// APPEASE SAFARI
			//    WITHOUT IT SAFARI WANTS TO RELOAD THE BROWSER WINDOW
			//    WHICH NIXES YOUR ALREADY QUEUED UPLOADS
			return false;
		};

		// ADD  DELETE  BUTTON
		new_row.appendChild( new_row_button );

		var new_span = document.createElement( "span" );
		new_span.className = "textcolor bold";
		new_span.innerHTML = "&nbsp;&nbsp;"+element.value;
		
		// ADD SPAN
		new_row.appendChild( new_span );

		// ADD IT TO THE LIST
		this.list_target.appendChild( new_row );
		
	};

};


/******************* CUSTOM-ALERT BOXES FUNCTIONS *******************/

// CONSTANTS TO DEFINE THE TITLE OF THE ALERT AND BUTTON TEXT.
var ALERT_TITLE = "Oops!";
var ALERT_BUTTON_TEXT = "Close";

var CONFIRM_TITLE = "Are You Sure?";
var CONFIRM_BUTTON1_TEXT = "Yes";
var CONFIRM_BUTTON2_TEXT = "Cancel";

// OVER-RIDE THE ALERT METHOD ONLY IF THIS A NEWER BROWSER.
// OLDER BROWSER WILL SEE STANDARD ALERTS
if(document.getElementById)
{
	/*window.alert = function(txt)
	{
		// REPLACE "\n" WITH "<br />"
		
		txt.replace(/\n/gi, "<br />\n");
		
		createCustomAlert(txt);
	}*/
	
	/*window.confirm = function(txt)
	{
		// REPLACE "\n" WITH "<br />"
		
		txt.replace(/\n/gi, "<br />\n");
		
		createCustomAlert(txt);
	}*/
}

function createCustomAlert(txt) {
  // SHORTCUT REFERENCE TO THE DOCUMENT OBJECT
  d = document;

  // IF THE MODALCONTAINER OBJECT ALREADY EXISTS IN THE DOM, BAIL OUT.
  if(d.getElementById("modalContainer")) return;

  // CREATE THE MODALCONTAINER DIV AS A CHILD OF THE BODY ELEMENT
  mObj = d.getElementsByTagName("body")[0].appendChild(d.createElement("div"));
  mObj.id = "modalContainer";
  
   // MAKE SURE ITS AS TALL AS IT NEEDS TO BE TO OVERLAY ALL THE CONTENT ON THE PAGE
  mObj.style.height = document.documentElement.scrollHeight + "px";

  // CREATE THE DIV THAT WILL BE THE ALERT 
  alertObj = mObj.appendChild(d.createElement("div"));
  alertObj.id = "alertBox";
  
  // MSIE DOESNT TREAT POSITION:FIXED CORRECTLY, SO THIS COMPENSATES FOR POSITIONING THE ALERT
  if(d.all && !window.opera) alertObj.style.top = document.documentElement.scrollTop + "px";
  
  // CENTER THE ALERT BOX
  alertObj.style.left = (d.documentElement.scrollWidth - alertObj.offsetWidth)/2 + "px";

  // CREATE AN H1 ELEMENT AS THE TITLE BAR
  h1 = alertObj.appendChild(d.createElement("h3"));
  h1.appendChild(d.createTextNode(ALERT_TITLE));

  // CREATE A PARAGRAPH ELEMENT TO CONTAIN THE TXT ARGUMENT
  msg = alertObj.appendChild(d.createElement("p"));
  msg.innerHTML = txt;
  
  // CREATE AN ANCHOR ELEMENT TO USE AS THE CONFIRMATION BUTTON.
  btn = alertObj.appendChild(d.createElement("a"));
  btn.id = "closeBtn";
  btn.appendChild(d.createTextNode(ALERT_BUTTON_TEXT));
  btn.href = "#";
  
  // SET UP THE ONCLICK EVENT TO REMOVE THE ALERT WHEN THE ANCHOR IS CLICKED
  btn.onclick = function() { removeCustomAlert();return false; }
}

// REMOVES THE CUSTOM ALERT FROM THE DOM
function removeCustomAlert() {
  document.getElementsByTagName("body")[0].removeChild(document.getElementById("modalContainer"));
}


/*******************  GREETING TEXT SCRIPT *******************/
/*///////////// SCRIPT TO DISPLAY GREETING /////////////*/
function fnDisplayGreeting()
{
  var Greeting = "Hello, ";
  var Today = new Date();
  var CurrentHour = Today.getHours();
  if (CurrentHour < 12) 
  {
    Greeting = "Good Morning, ";
  }
  if (CurrentHour >= 12 && CurrentHour < 17)
  { 
    Greeting = "Good Afternoon, ";
  }
  if (CurrentHour >= 17) 
  {
    Greeting = "Good Evening, "; 
  }
  document.write(Greeting);
}
/*///////////// END OF GREETING SCRIPT /////////////*/
/*///////////// SCRIPT TO DISPLAY FULL DATE /////////////*/
function fnDisplayDate()
{
  var Today = new Date();
  var Days = new Array("Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday");
  var Months = new Array("January","February","March","April","May","June","July","August","September","October","November","December");
  var Year = Today.getYear();
  if (Year < 1000) 
  {
    Year += 1900;
  }
  var Day = Today.getDate();
  var DateEnding = "th";
  if (Day == 1 || Day == 21 || Day == 31)
  {
    DateEnding = "st"; 
  }
  else if (Day == 2 || Day == 22)
  {
    DateEnding = "nd";
  }
  else if (Day == 3 || Day == 23) 
  {
    DateEnding = "rd";
  }
  document.write( Days[Today.getDay()] + " " + Day + DateEnding + " " + Months[Today.getMonth()] + " " + Year );
}
/*///////////// END OF DATE SCRIPT /////////////*/





/************************************** UTILS   **************************************/


String.prototype.stripHTML = function() {
        // What a tag looks like
        var matchTag = /<(?:.|\s)*?>/g;
        // Replace the tag
        return this.replace(matchTag, "");
};


Number.prototype.toCurrency = function() {
	// pass a number and it will return it in a currency formatted string.
	// what it does that others dont though is onl
	// - dNumber: 
	
	var sNumber = this.toString();
	
	// first validate it as a number
	
	bSuccess = sNumber.match(/^[0-9]+([.]+[0-9]+){0,1}$/);
	if(! bSuccess) {
		return false;
	}
	
	// now, validate it and different decimal places (for now, 2 is enough)
	// ** this could do with some kinda of loop depending on decimal places
	//    required. At the mo, just fixed at two limit
	
	// whole number
	bSuccess = sNumber.match(/^[0-9]+$/);
	if(bSuccess) {
		return sNumber;
	}
	
	// one decimal place
	bSuccess = sNumber.match(/^[0-9]+([.]+[0-9]{1})+$/);
	if(bSuccess) {
		return sNumber+"0";
	}
	
	// two decimal place
	bSuccess = sNumber.match(/^[0-9]+([.]+[0-9]{2})+$/);
	if(bSuccess) {
		return sNumber;
	}
	
	return this.toFixed(2);
}



function setCookie(name, value, days) {
	if (days) {
		var date = new Date();
		date.setTime(date.getTime()+(days*24*60*60*1000));
		var expires = "; expires="+date.toGMTString();
	}
	else var expires = "";
	document.cookie = name+"="+value+expires+"; path=/";
}


function getCookie(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;
}


function deleteCookie(name) {
	setCookie(name,"",-1);
}


function cropText(sText, iMaxChars) {
	// this function will take a string and crop it if neccessary with trailing 
	// dotted characters - ie. Martyn Bis...
	// - iMaxChars: max number of characters allowed 
	
	if (sText.length > iMaxChars){
		sText = sText.substring(0,iMaxChars-3)+'...';
	}
	
	return sText;
}


function cloneObj(o) {
	if(typeof(o) != 'object') return o;
	if(o == null) return o;
	
	var newO = new Object();
	
	for(var i in o) newO[i] = cloneObj(o[i]);
	return newO;
}


function formatNumber(value,decimal){
	value = value-0; // cast to integer
	if (!decimal) decimal = (value>=1.05) ? 2 : 3;
	var num = value.toFixed(decimal);
	var tmp= num + '';
	var regexp = (decimal==3) ? '\.000' : '\.00';
	var reg_match = new RegExp(regexp);
	if (tmp.match(reg_match)){
		num = value.toFixed(0);
	}
	tmp = num+'';
	reg_match = new RegExp('\\\.'); // silly escaping
	if (tmp.match(reg_match)){
		var re = new RegExp("0$");
  		tmp = tmp.replace(re,"");
		num = tmp-0;
	}
	return num;
}


function cancelEvent(e)
{
	e = e ? e : window.event;
	if(e.stopPropagation) e.stopPropagation();
	if(e.preventDefault) e.preventDefault();
	e.cancelBubble = true;
	e.cancel = true;
	e.returnValue = false;
	return false;
}


function getIEVersion() {
	// this returns which version of IE we're using. If not ie, will return -1
	
	var rv = -1; // Return value assumes failure.
	
	if (navigator.appName == 'Microsoft Internet Explorer') {
	
	var ua = navigator.userAgent;
	var re = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})");
	
	if (re.exec(ua) != null)
		rv = parseFloat(RegExp.$1);
	}
	
	return rv;
}


/***************** BROWSER DETECTION SCRIPT *****************/


// www.quirksmode.org/js/detect.html

var BrowserDetect = {
	init: function () {
		this.browser = this.searchString(this.dataBrowser) || "An unknown browser";
		this.version = this.searchVersion(navigator.userAgent)
			|| this.searchVersion(navigator.appVersion)
			|| "an unknown version";
		this.OS = this.searchString(this.dataOS) || "an unknown OS";
	},
	searchString: function (data) {
		for (var i=0;i<data.length;i++)	{
			var dataString = data[i].string;
			var dataProp = data[i].prop;
			this.versionSearchString = data[i].versionSearch || data[i].identity;
			if (dataString) {
				if (dataString.indexOf(data[i].subString) != -1)
					return data[i].identity;
			}
			else if (dataProp)
				return data[i].identity;
		}
	},
	searchVersion: function (dataString) {
		var index = dataString.indexOf(this.versionSearchString);
		if (index == -1) return;
		return parseFloat(dataString.substring(index+this.versionSearchString.length+1));
	},
	dataBrowser: [
		{
			string: navigator.userAgent,
			subString: "Chrome",
			identity: "Chrome"
		},
		{ 	string: navigator.userAgent,
			subString: "OmniWeb",
			versionSearch: "OmniWeb/",
			identity: "OmniWeb"
		},
		{
			string: navigator.vendor,
			subString: "Apple",
			identity: "Safari",
			versionSearch: "Version"
		},
		{
			prop: window.opera,
			identity: "Opera"
		},
		{
			string: navigator.vendor,
			subString: "iCab",
			identity: "iCab"
		},
		{
			string: navigator.vendor,
			subString: "KDE",
			identity: "Konqueror"
		},
		{
			string: navigator.userAgent,
			subString: "Firefox",
			identity: "Firefox"
		},
		{
			string: navigator.userAgent,
			subString: "Mozilla",
			identity: "Mozilla"
		},
		{
			string: navigator.vendor,
			subString: "Camino",
			identity: "Camino"
		},
		{
			string: navigator.userAgent,
			subString: "MSIE",
			identity: "Explorer",
			versionSearch: "MSIE"
		},
		{
			string: navigator.userAgent,
			subString: "Gecko",
			identity: "Mozilla",
			versionSearch: "rv"
		},
		{
			string: navigator.userAgent,
			subString: "Andriod",
			identity: "Andriod"
		},
		{		// for newer Netscapes (6+)
			string: navigator.userAgent,
			subString: "Netscape",
			identity: "Netscape"
		},
		{ 		// for older Netscapes (4-)
			string: navigator.userAgent,
			subString: "Mozilla",
			identity: "Netscape",
			versionSearch: "Mozilla"
		}
	],
	dataOS : [
		{
			string: navigator.platform,
			subString: "Win",
			identity: "Windows"
		},
		{
			string: navigator.platform,
			subString: "Mac",
			identity: "Mac"
		},
		{
			string: navigator.userAgent,
			subString: "iPhone",
			identity: "iPhone/iPod"
	    },
		{
			string: navigator.userAgent,
			subString: "iPad",
			identity: "iPad"
	    },
		{
			string: navigator.userAgent,
			subString: "Andriod",
			identity: "Andriod"
	    },
		{
			string: navigator.platform,
			subString: "Linux",
			identity: "Linux"
		}
	]

};

BrowserDetect.init();





var gbKeyPressed = false;
var goKeyPressedTimeout;

function ffSetKeyPressed() {
// will set the timeout to prevent any duplicate calls being made on 
// keyup (after keydown to kill the alert box)

gbKeyPressed = true;

//alert(gbKeyPressed)

goKeyPressedTimeout = setTimeout(function() {
	ffResetKeyPressed();
}, 500);
}

function ffResetKeyPressed() {
// will reset the key pressed var after a given time period

clearTimeout(goKeyPressedTimeout);
gbKeyPressed = false;
}



function dump(arr) {
	dumped_text = dumpRec(arr);
	
	alert(dumped_text);
}



function dumpRec(arr,level) {
	var dumped_text = "";
	if(!level) level = 0;
	
	//The padding given at the beginning of the line.
	var level_padding = "";
	for(var j=0;j<level+1;j++) level_padding += "    ";
	
	if(typeof(arr) == 'object') { //Array/Hashes/Objects 
		for(var item in arr) {
			var value = arr[item];
			
			if(typeof(value) == 'object') { //If it is an array,
				dumped_text += level_padding + "'" + item + "' ...\n";
				dumped_text += dumpRec(value,level+1);
			} else {
				dumped_text += level_padding + "'" + item + "' => \"" + value + "\"\n";
			}
		}
	} else { //Stings/Chars/Numbers etc.
		dumped_text = "===>"+arr+"<===("+typeof(arr)+")";
	}
	return dumped_text;
}


/**************************************    **************************************/

/*************************  CUSTOM DATE METHODS  ************************/
/* Custom Date methods
 * addDays
 * addWeeks
 * addYears
 * addMonths
 * addMonthsTrunc
 * copy
 * getDaysBetween
 * getCDay
 * getDayName
 * getDayOfYear
 * getCMonth
 * getMonthName
 * getWeekDays
 * addWeekDays
 * getMonthsBetween
 * getYearsBetween
 * getAge
 * lastDay
 * sameDayEachWeek
 * to12HourString
 * to24HourString
 */

Date.prototype.DAYNAMES = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
Date.prototype.MONTHNAMES = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
Date.prototype.msPERMIN = 1000 * 60;
Date.prototype.msPERDAY = 1000 * 60 * 60 * 24;

Date.prototype.addWeekDays = function(d) {
    /* Adds the necessary number of days
     * to the date to include the required
     * weekdays.
     */
    var startDay = this.getDay();    //day of week 0 through 6
    var wkEnd = 0;              //number of weekends needed
    var m = d % 5;              //number of weekdays for partial week

    if (d < 0) {
        wkEnd = Math.ceil(d/5); //Yields a negative number of weekends

        switch (startDay) {
        case 6: 			//Staring day Sat. 1 less weekend
            if (m == 0 && wkEnd < 0) 
				wkEnd++;
            break;
        case 0:
            if (m == 0) 
				d++;        //decrease - part of weekend
            else 
				d--;        //increase - part of weekend
            break;
        default:
            if (m <= -startDay) 
				wkEnd--;	//add weekend if not enough days to cover
        }
    }
    else if (d > 0) {
        wkEnd = Math.floor(d/5);

        switch (startDay) {
        case 6:
            if (m == 0) 
				d--;
            else 
				d++;
            break;
        case 0:
            if (m == 0 && wkEnd > 0) 
				wkEnd--;
            break;
        default:
            if (5 - startDay < m) 
				wkEnd++;
        }
    }

    d += wkEnd * 2; //Add weekends to weekdays needed

    this.addDays(d);
};
Date.prototype.addDays = function(d) {
        /* Adds the number of days to the date */
        this.setDate( this.getDate() + d );
    };
Date.prototype.addWeeks = function(w) {
        /* Adds the number of weeks to the date */
        this.setDate(this.addDays(w * 7));
    };
Date.prototype.addMonths = function(m) {
        /* Adds the number of months to date
         * If starting with a day that is
         * greater than the number of days
         * in the new month the new date is
         * in the next month
         */
        this.setMonth(this.getMonth() + m);
    };
Date.prototype.addMonthsTrunc = function(m) {
        /* Adds the number of months to date,
         * but unlike addMonths this method
         * truncates extra days at end of month
         * when the start day of month is greater
         * than the number of days in the target
         * ending month (js overflows into the following month)
         */
         var d = this.getDate();
         this.setMonth(this.getMonth() + m);

         /* Adjust when original month has more days then new month and overflows */
         if (this.getDate() < d)
             this.setDate(0);
    };
Date.prototype.addYears = function(y) {
        /* Adds the number of years to date
         * If adding to 2/29 and result is not
         * a leap year the day is set to 28
         */
        var m = this.getMonth();
        this.setFullYear(this.getFullYear() + y);

        //Adjust for leap years
        if (m < this.getMonth()) {
            this.setDate(0);
        }
    };
Date.prototype.copy = function () {
        /* Creates a copy of date by value
         * Normal assignment only creates
         * a reference to the date, whereas
         * this creates a new date object
         */
        return new Date(this.getTime());
    };
Date.prototype.getDaysBetween = function(d) {
        /*Returns number of days between two dates
        * including the last day, but not the first.
        *
        * This is value can be added
        * to one date get the other date.
        */
		var tmp = d.copy();
		tmp.setUTCHours(this.getUTCHours(), this.getUTCMinutes(), this.getUTCSeconds(), this.getUTCMilliseconds());		

		var time = tmp.getTime() - this.getTime();
		return time/this.msPERDAY;
    };
Date.prototype.getCDay = function() {
        //Returns first 3 letters in day name
        return this.getDayName().slice(0,3);
    };
Date.prototype.getDayName = function() {
        //Returns full name of day
        return this.DAYNAMES[this.getDay()];
    };
Date.prototype.getDayOfYear = function() {
        //Returns day of year 1 through 365 or 366
        var start = new Date(this.getFullYear(), 0, 0);
        return this.getDaysBetween(start) * -1;
    };
Date.prototype.getCMonth = function() {
        //Returns first 3 letters in month name
        return this.getMonthName().slice(0, 3);
    }
Date.prototype.getMonthName = function() {
        //Returns full name of month
        return this.MONTHNAMES[this.getMonth()];
    };
Date.prototype.getWeekDays = function(d) {
        var wkEnds = 0, days = 0;
        var s = 0, e = 0;

        days = Math.abs(this.getDaysBetween(d));

        if (days) {
            s = (d < this) ? d.getDay() : this.getDay() ;
            e = (d < this) ? this.getDay() : d.getDay();

            wkEnds = Math.floor(days/7);

            if (s != 6 && s > e) 
				wkEnds++;
            if (s != e && (s == 6 || e == 6) ) 
				days--;

            days -= (wkEnds * 2);
        }
        return days;
    };
Date.prototype.getMonthsBetween = function(d) {
        //returns months between dates
        var d1 = this.getFullYear() * 12 + this.getMonth();
        var d2 = d.getFullYear() * 12 + d.getMonth();
        return d2 - d1;
    };
Date.prototype.getMonthsBetween2 = function(d) {
	var sDate, eDate;   
	var d1 = this.getFullYear() * 12 + this.getMonth();
	var d2 = d.getFullYear() * 12 + d.getMonth();
	var sign;
	var months = 0;
	var sDay, sLastDay, sAdj, eDay, eLast, eAdj, adj;

	if (this == d) {
		months = 0;
	} else if (d1 == d2) { //same year and month
		months = (d.getDate() - this.getDate())/this.lastday();
	} else {
		if (d1 <  d2) {
			sDate = this;
			eDate = d;
			sign = 1;
		} else {
			sDate = d;
			eDate = this;
			sign = -1;
		}

		sDay = sDate.getDate();
		sLastDay = sDate.lastday();
		eDay = eDate.getDate();
		eLastDay = eDate.lastday();

		if (sDay > eLastDay) {
			adj = eDay/eLastDay;
		} else {
			sAdj = sLastDay - sDay;
			eAdj = eDay > sLastDay ? sLastDay : eDay;
			adj = (sAdj + eAdj)/sLastDay;
		}
		months = Math.abs(d2 - d1) + (adj -1);

		if (months % 1 != 0 )
			months = (months * sign).toFixed(2);
		else
			months = (months * sign);
	}
	return months;
}
Date.prototype.getYearsBetween = function(d) {
        //returns years and fraction between dates
        var months = this.getMonthsBetween(d);
        return months/12;
    };
Date.prototype.getAge = function(d) {
		if (!d)
        	d = new Date();

        return this.getYearsBetween(d).toFixed(2);
    };
Date.prototype.lastday = function() {
        //returns number of days in month
        var d = new Date(this.getFullYear(), this.getMonth() + 1, 0);
        return d.getDate();
    };
Date.prototype.sameDayEachWeek = function (d, date) {
        /* Returns array of dates of same day each week in range */
        var aDays = new Array();
        var eDate, nextDate, adj;

        if (this > date) {
            eDate = this;
            nextDate = new Date(date.getTime());
        } else {
            eDate = date;
            nextDate = new Date(this.getTime());
        }

        adj = (d - nextDate.getDay() + 7) %7;
        nextDate.setDate(nextDate.getDate() + adj);

        while (nextDate < eDate) {
            aDays[aDays.length] = new Date(nextDate.getTime() );
            nextDate.setDate(nextDate.getDate() + 7);
        }
        return aDays;
    };
Date.prototype.to12HourString = function () {
    var h = this.getHours();
    var m = "0" + this.getMinutes();
    var s = "0" + this.getSeconds();

    var ap = "am";

    if (h >= 12) {
        ap = "pm";

        if (h >= 13)
            h -= 12;

    } else if (h == 0) {
        h = 12;
	}

    h = "0" + h;
    return h.slice(-2) + ":" + 
           m.slice(-2) + ":" + 
           s.slice(-2) + " " + ap;
}
Date.prototype.to24hourString = function () {
	var h = "0" + this.getHours();
    var m = "0" + this.getMinutes();
    var s = "0" + this.getSeconds();
    return h.slice(-2) + ":" + m.slice(-2) + ":" + s.slice(-2);
}

/* Add built-in method to earlier browsers*/
if (!Date.prototype.toDateString) {
    Date.prototype.toDateString = function() {
            return this.toString().replace(/\d\d:\d\d:\d\d\s\w{2,3}\s/, '');
        };
}
if (!Date.prototype.toLocaleDateString) {
    Date.prototype.toLocaleDateString = function() {
            return (this.getMonth() + 1) + "/" + this.getDate() + "/" + this.getFullYear();
        };
}



/**************************** SCREEN GREYOUT FUNCTION   ****************************/


function insertOptionBefore(oElement, sOptionText, sOptionValue)
{
	//var elSel = document.getElementById(oElement);
	
	var elSel = oElement;

	if (elSel.selectedIndex >= 0) {
		
		var elOptNew = document.createElement('option');
		
		elOptNew.text = sOptionText;
		
		elOptNew.value = sOptionValue;
		
		var elOptOld = elSel.options[elSel.selectedIndex];  
		
		try {
			elSel.add(elOptNew, elOptOld); // standards compliant; doesn't work in IE
		}
		catch(ex) {
			elSel.add(elOptNew, elSel.selectedIndex); // IE only
		}
	}
}



function removeSelectedOption(oElement)
{
	//var elSel = document.getElementById(oElement);
	
	var elSel = oElement;
	
	var i;
	
	for (i = elSel.length - 1; i>=0; i--) {
		if (elSel.options[i].selected) {
			elSel.remove(i);
		}
	}
}


function appendOptionLast(oElement, sOptionText, sOptionValue)
{
	var elOptNew = document.createElement('option');

	elOptNew.text = sOptionText;

	elOptNew.value = sOptionValue;
	
	//var elSel = document.getElementById(oElement);
	
	var elSel = oElement;

	try {
		elSel.add(elOptNew, null); // standards compliant; doesn't work in IE
	}
	
	catch(ex) {
		elSel.add(elOptNew); // IE only
	}
}


function removeLastOption(oElement)
{
	//var elSel = document.getElementById(oElement);
	
	var elSel = oElement;
	
	if (elSel.length > 0)
	{
		elSel.remove(elSel.length - 1);
	}
}



/**************************** SCREEN GREYOUT FUNCTION   ****************************/


function grayOut(vis, options) {
  // Pass true to gray out screen, false to ungray
  // options are optional.  This is a JSON object with the following (optional) properties
  // opacity:0-100         // Lower number = less grayout higher = more of a blackout 
  // zindex: #             // HTML elements with a higher zindex appear on top of the gray out
  // bgcolor: (#xxxxxx)    // Standard RGB Hex color code
  // grayOut(true, {'zindex':'50', 'bgcolor':'#0000FF', 'opacity':'70'});
  // Because options is JSON opacity/zindex/bgcolor are all optional and can appear
  // in any order.  Pass only the properties you need to set.
  var options = options || {}; 
  var zindex = options.zindex || 70;
  var opacity = options.opacity || 80;
  var opaque = (opacity / 100);
  var bgcolor = options.bgcolor || '#000000';
  var dark=document.getElementById('darkenScreenObject');
  if (!dark) {
    // The dark layer doesn't exist, it's never been created.  So we'll
    // create it here and apply some basic styles.
    // If you are getting errors in IE see: support.microsoft.com/default.aspx/kb/927917
    var tbody = document.getElementsByTagName("body")[0];
    var tnode = document.createElement('div');           // Create the layer.
        tnode.style.position='absolute';                 // Position absolutely
        tnode.style.top='0px';                           // In the top
        tnode.style.left='0px';                          // Left corner of the page
        tnode.style.overflow='hidden';                   // Try to avoid making scroll bars            
        tnode.style.display='none';                      // Start out Hidden
        tnode.id='darkenScreenObject';                   // Name it so we can find it later
    tbody.appendChild(tnode);                            // Add it to the web page
    dark=document.getElementById('darkenScreenObject');  // Get the object.
  }
  if (vis) {
    // Calculate the page width and height 
    if( document.body && ( document.body.scrollWidth || document.body.scrollHeight ) ) {
        var pageWidth = document.body.scrollWidth+'px';
        var pageHeight = document.body.scrollHeight+'px';
    } else if( document.body.offsetWidth ) {
      var pageWidth = document.body.offsetWidth+'px';
      var pageHeight = document.body.offsetHeight+'px';
    } else {
       var pageWidth='100%';
       var pageHeight='100%';
    }   
    //set the shader to cover the entire page and make it visible.
    dark.style.opacity=opaque;                      
    dark.style.MozOpacity=opaque;                   
    dark.style.filter='alpha(opacity='+opacity+')'; 
    dark.style.zIndex=zindex;        
    dark.style.backgroundColor=bgcolor;  
    dark.style.width= pageWidth;
    dark.style.height= pageHeight;
    dark.style.display='block';                          
  } else {
     dark.style.display='none';
  }
}


/****************  SUPPORTED BROWSERS CHECK SCRIPT  *******************/


