//Public Constants
var NUMBERS 			= 0;  //Numbers only
var LETTERS 			= 1;  //Letters only
var EMPTY				= 2;  //Not Empty
var EMAIL				= 3;  //In the form X@X.X[;Y@Y.Y[...]]
var PHONE				= 4;  //In the form (XXX) XXX-XXXX.  Parenthesis, spaces, and dashes are optional
var MONEY				= 5;  //In the form $X.XX. Dollar sign and decimal point are optional
var DATE				= 6;  //In the form XX/XX/XXXX.  Separators can be / or -.  Month and day are 1 or 2 digits.  Year is 4 digits.
var ADDRESS				= 7;  //Checks for a number followed by a word or words. 
var SSNUMBER			= 8;  //In the form XXX-XX-XXXX. Dashes are optional.
var INITIAL				= 9;  //An Initial only
var ZIP					= 10; //Valid US zip code
var DATELENIENT			= 11; //accepts 2 or 4 digit year
var DATEOFBIRTH 		= 12; //must be before or equal to the current date
var FUTUREDATE			= 13; //must be after the current date
var PASTDATE			= 14; //must be before or equal to the current date
var MUSTCONTAINLETTERS	= 15; //musttesttest contain at least 1 letter
var MONTHYEAR			= 16; //mm/yyyy
var PASTMONTHYEAR		= 17; //mm/yyyy >= this month
var FUTUREMONTHYEAR		= 18; //mm/yyyy <= this month
var SINGLELINE			= 19; //printable characters only
var MULTILINE			= 20; //printable charachters plus TAB, CR and LF
var SMALLINT			= 21; //validate smallint -32768 to 32767
var WEIGHT				= 22; //validate weight within range 0 - 32767 no decimal no negative
var CHARACTER			= 23; //validate only letter, digit, whitespace and \".,()\" characters
var LETTERANDDIGIT      = 24; //validate only letter and digit characters
var HEIGHT				= 25; //validate height within range include(0) 0 - 32767 no decimal no negative
var CONTACTNAME			= 26; //validate only letter and \"-\" characters

//Public Variables
var useAssociatedElements	= false;
var restoreValue 			= true; //saves values when disabling, then restores them on reenable
var usingPictures			= true;
var dontValidate 			= false; //used to bypass validation if they want to quit and save their work
var dontShowErrorMessage	= false; //hide the error message if set to true
var displaySaveWorkAlert	= false; //used to display the save work alert if a change on page element values has been detected
var highlightField 			= false; //highlights the field if set to true
var invalidFieldColor		= "#FFD2C4";
var disableDependencies		= false; //disables/enables dependencies upon choice of parent
var validateOnChange		= false; //automatically adds onchange validation to each element
var debugTiming				= false;
var validatePageEmailBool = false; //whether to examine the EMAIL
try {
    var baseDateForValidationOfFuture = new Date();
}
catch (e) { }
//Declared for backward compatibility (not used any more)
var alreadySubmitted		= true;
var radioHighlightColor		= "#F7FBFF"; //color to turn radio buttons back to (used for non white tables)
var checkboxHighlightColor	= "#F7FBFF"; //color to turn checkbox back to (used for non white tables)

//Protected
var nodeTable = new Hashtable();
var InitComplete = false;
var formElementsAltered	= false; //internally used to bypass/display (true/false) the save work alert

//addEvent(window, "load", onLoadDisableDependencies);
//addEvent(window, "load", fillValues);
addEvent(window, "load", InitDomObjectsAndDependencies);
//addEvent(window, "beforeunload", saveWorkAlert);
window.onbeforeunload=saveWorkAlert;


//the event handler for beforeunload event
function saveWorkAlert(theForm, URL) {
    try {
        if (displaySaveWorkAlert && formElementsAltered) {
            return "You will lose all changes made since your last save.";
        }
    }
    catch (e) { }
}

function alertError(message)
{
	if(!dontShowErrorMessage)
	{
		alert(message);
	}
}

function ClearPageElements()
{
	nodeTable = new Hashtable();
	InitComplete = false;
}

function InitDependencies(node)
{
	if(!node)
	{
		return;
	}
	
	var dependencies = node.dependencies;
	var length = dependencies.length;
	var parentNode = null;

	for(var i = 0; i < length; ++i)
	{
		parentNode = nodeTable.get(dependencies[i].split(";")[0]);

		if(parentNode)
		{
			parentNode.dependentChildNodes.push(node);
		}
	}
}

function AddElementChangedHandler(element)
{

	var theField = element;
	
	if(theField)
	{	
		
		var functionToCall = function(){validateFormElement(document.forms[0], theField.name)};

		if(theField.type == "radio" || theField.type == "checkbox" || theField[0])
		{		
			if(theField[0])
			{
				for(var i = 0; i < theField.length; ++i)
				{				
					addEvent(theField[i], "click", functionToCall);//	addOnClickEvent(theField[i], functionToCall);	
				}
			}
			else
			{
				addEvent(theField, "click", functionToCall);		
			}
		}
		else if(theField.type == "select-one" || theField.type == "text")
		{
			addEvent(theField, "change", functionToCall);
		}					
	
	}
		
		
}

function InitDomObjectsAndDependencies()
{
	if(InitComplete || !document.forms[0])
	{
		return;
	}
	try {
	    var start = new Date();

	    var currentNode = null;
	    var elements = document.forms[0].elements;
	    var length = elements.length;
	    var currentElement = null;
	    var temp = null;

	    for (var i = 0; i < length; ++i) {
	        currentElement = elements[i];

	        if (currentElement && validateOnChange) {
	            AddElementChangedHandler(currentElement);
	        }

	        currentNode = nodeTable.get(currentElement.name);

	        if (currentNode) {
	            if (currentNode.formField) {
	                if (currentNode.formField.push) {
	                    currentNode.formField.push(currentElement);
	                }
	                else {
	                    temp = currentNode.formField;
	                    currentNode.formField = new Array();
	                    currentNode.formField.push(temp);
	                    currentNode.formField.push(currentElement);
	                }
	            }
	            else {
	                InitDependencies(currentNode);
	                currentNode.formField = currentElement;
	            }
	        }

	    }

	    nodeTable.moveFirst();
	    var currentElement;
	    while (nodeTable.next()) {
	        currentElement = nodeTable.getValue();
	        currentElement.domElement = DomElementFactory.Create(currentElement.formField);
	    }

	    InitComplete = true;

	    var end = new Date();

	    if (debugTiming) {
	        alert("InitDomObjectsAndDependencies: " + (end - start));
	    }
	}
	catch (e) { }
}

function pageElementValue(elementName, elementValue)
{
	this.elementName 	= elementName;
	this.elementValue 	= elementValue;
}

pageElementValue.prototype.fillValue = function(theForm)
{
	var currNode = nodeTable.get(this.elementName);
	if(currNode != undefined)
	{
		if(currNode.name == this.elementName)
		{
			var domElement = currNode.domElement;
			
			if(domElement)
			{
				domElement.SetValue(unescape(this.elementValue));
			}	
		}
	}
}   
	
	
function fillValues(theForm)
{	
	InitDomObjectsAndDependencies();
	
	var start = new Date();
	if(!theForm)
	{
		theForm = document.forms[0];
	}
	try
	{
		if(pageElementValues)
		{
			for(var i = 0; i < pageElementValues.length; ++i)
			{
				if(pageElementValues[i] != null)
				{
					pageElementValues[i].fillValue(theForm);
				}
			}
		}	
	}
	catch(e)
	{
	}
	var end = new Date();
	if(debugTiming)
	{
		alert("fillValues: " + (end - start) );
	}
}

	
//constructor for a pageElement	
function pageElement(name, displayName, picName, validateFor, dependencies, theLength, valueConstraints, next, associatedElements, customError)
{

	this.name 	 				= name;
	this.validateFor			= validateFor;
	this.dependencies 			= dependencies;
	this.theLength				= theLength;
	this.valueConstraints		= valueConstraints;
	this.associatedElements 	= associatedElements != ""? associatedElements : name + "Element";	
	this.picName	 			= picName != ""? picName : name + "Pic";	
	this.formField 				= null;
	this.dependentChildNodes	= new Array();
	this.displayName 			= displayName != ""? displayName : getDisplayName(name);
	this.restoreValue			= restoreValue;
	this.customError			= customError;
}

function addPageElement(name, displayName, picName, validateFor, dependencies, theLength, valueConstraints, associatedElements, theForm, customError)
{
	if(associatedElements == undefined)
	{
		var associatedElements = "";
	}
	var temp = new pageElement(name, displayName, picName, validateFor, dependencies, theLength, valueConstraints, null, associatedElements, customError);
	nodeTable.put(name, temp);
	return temp;
}

function removePageElement(name)
{
	nodeTable.remove(name);
}

//main function called by the pageElement.  Does all the validating
pageElement.prototype.validate = function(theForm)
{
	var theField 	= this.domElement;
	var isValid		= true;
	
	if(theField == undefined)
	{
		return true;
	}

	//ugly fix for multiple form pages
	//since the element might exist on both forms
	//we have to use the correct form to relookup
	//the form field		
	if(document.forms.length > 1)
	{
		theField.element = eval("theForm." + this.name);
	}	
	
	if(!theField.element)
	{
		return true;
	}

	isValid = isValid && validateField(this, theField.element);
	isValid = isValid && validateDependencies(this, theField.element, theForm);
	isValid = isValid && validateLength(this, theField.element);
	isValid = isValid && validateValue(this, theField.element);
	
	handlePicDisplay(this, theForm, isValid);
	
	if(highlightField)
	{
		theField.HighlightField(isValid);
	}
	
	return isValid; 	
}
  
function validateValue(objThis, theField)
{
	var valueConstraints = objThis.valueConstraints;
	if(valueConstraints == "" || theField.value == "")
	{
		return true;
	}

	var datePattern = getDatePattern(theField.value);
	var theValueIsDate = (datePattern != 99);
	if (theValueIsDate) 
	{
		theField.value = formatDate(theField.value, theField, datePattern);
	}
	var theValue = theValueIsDate ? getAge(theField.value, baseDateForValidationOfFuture) : theField.value;
	var compExp = getComparisonExpression(valueConstraints, "theValue");
	var customError = objThis.customError;

	if(! eval(compExp.eval))
	{
		if (customError && customError.message && (!customError.valueConstraints || eval(getComparisonExpression(customError.valueConstraints, "theValue").eval)))
			alertError(customError.message);
		else if(theValueIsDate)
			alertError("The value of the " + objThis.displayName + " field must represent an age" + compExp.sentence)
		else
			alertError("The value of the " + objThis.displayName + " field must be" + compExp.sentence);
		return false;
	
	}
	return true;	
}


function handlePicDisplay(objThis, theForm, isValid)
{


	if(!usingPictures)
	{
		return;
	}

	var thePic = "theForm." + objThis.picName;	
	var picExists = eval(thePic);
	
	if(!picExists)
	{
		usingPictures = false;
		return;
	}
	
	//if it didnt pass validation, show the picture and return false.  
	//Otherwise hide the pic and return true;
	if(!isValid)
	{
	
		if(picExists)
		{
			evalString = "theForm." + objThis.picName + ".style.visibility = ''";
			eval(evalString);
		}
	}
	else
	{
		if(picExists)
		{
			evalString = "theForm." + objThis.picName + ".style.visibility = 'hidden'";
			eval(evalString);
		}
	}

}

function validateLength(objThis, theField)
{ 
	var theLength = objThis.theLength;
	if(theLength == "")
		return true;
		
	if(theField.value == "")
		return true;
		
	var compExp = getComparisonExpression(theLength, "theField.value.length");
	var customError = objThis.customError;

	if(! eval(compExp.eval))
	{
		if (customError && customError.message && (!customError.lengthConstraints || eval(getComparisonExpression(customError.lengthConstraints, "theField.value.length").eval)))
			alertError(customError.message);
		else
			alertError("The length of the " + objThis.displayName + " field must be" + compExp.sentence);
		return false;	
	}
	
	return true;	
}

//helper function used by validate to traverse the dependencies
//if one of the dependencies is not empty then this field validates for empty
function validateDependencies(currField, theValue, theForm)
{
	var isValid = true;

	//dependencies	--> array of <dependency>
	//dependency	--> <field name>;<value 1>[||<value 2>[...]][;<behavior>]
	//behavior		--> {true|false}
	//traverse the dependencies and if they arent empty, then validate this field for empty.
	for(var i = 0; i < currField.dependencies.length; ++i)
	{
		var splitArray = currField.dependencies[i].split(";");

		var	theFieldTestValue = splitArray.length > 1 ? splitArray[1] : "";

		var isRequiredIfDependencyIsActive = splitArray.length <= 2 ? true : (splitArray[2] == "true");

		if(isRequiredIfDependencyIsActive)
		{
			if(NonEmptyValueMatchesOptionalTestValue(theForm, nodeTable.get(splitArray[0]).domElement, theFieldTestValue))
			{
				isValid = isValid && validateForEmpty(theValue, currField.displayName);
			}
		}
	}

	return isValid;
}

//this function is used externally, do not remove
function findPageElement(name)
{
	return nodeTable.get(name);	
}

//helper function used by validate to run through each type
//of validation set by the user.  returns if the validation
//passed or not.
function validateField(currField, theValue)
{
	var isValid = true;

	var numberOfValidations	= currField.validateFor.length;

	//if no validation is requested for a page element or the only validation is "EMPTY"":
	if(numberOfValidations == 0 || (numberOfValidations == 1 && ForceArray(currField.validateFor)[0]) == EMPTY)
	{

		switch (theValue.type)
		{
		//	for 'text' or 'hidden' elements, the validator performs the "SINGLELINE" validation by default
		case "text": case "hidden":
			isValid = isValid && validateForSingleLine(theValue, currField.displayName);
			break;
		//	for 'textarea' elements, the validator performs the "MULTILINE" validation by default.
		case "textarea":
			isValid = isValid && validateForMultiLine(theValue, currField.displayName);
			break;
		}
	}
	for(var i = 0; i < numberOfValidations; ++i)
	{
		var currValidation = currField.validateFor[i];
		switch (currValidation)
		{
		
			case NUMBERS: 				isValid = isValid && validateForNumbersOnly(theValue, currField.displayName); break;
			case LETTERS: 				isValid = isValid && validateForLettersOnly(theValue, currField.displayName); break;
			case EMPTY:					isValid = isValid && validateForEmpty(theValue, currField.displayName); break;
			case EMAIL: 				
			{	
							if(validatePageEmailBool)
							{
								
							}
							else
							{
								isValid = isValid && validateForEmail(theValue, currField.displayName); 
							}
							break;
			}
			case PHONE:	 				isValid = isValid && validateForPhoneNumber(theValue, currField.displayName); break;
			case MONEY: 				isValid = isValid && validateForMoney(theValue, currField.displayName); break;
			case DATE: 					isValid = isValid && validateForDate(theValue, currField.displayName); break;
			case ADDRESS: 				isValid = isValid && validateForAddress(theValue, currField.displayName); break;
			case SSNUMBER: 				isValid = isValid && validateForSSNumber(theValue, currField.displayName); break;
			case INITIAL: 				isValid = isValid && validateForInitial(theValue, currField.displayName); break;
			case DATELENIENT:			isValid = isValid && validateForDateLenient(theValue, currField.displayName); break;
			case DATEOFBIRTH: 			isValid = isValid && validateForDateOfBirth(theValue, currField.displayName); break;
			case FUTUREDATE:			isValid = isValid && validateForFutureDate(theValue, currField.displayName, currField.customError); break;
			case PASTDATE:				isValid = isValid && validateForPastDate(theValue, currField.displayName); break;
			case MUSTCONTAINLETTERS:	isValid = isValid && validateForContainsLetter(theValue, currField.displayName); break;
			case MONTHYEAR:				isValid = isValid && validateForMonthYear(theValue, currField.displayName); break;
			case PASTMONTHYEAR:			isValid = isValid && validateForPastMonthYear(theValue, currField.displayName); break;
			case FUTUREMONTHYEAR:		isValid = isValid && validateForFutureMonthYear(theValue, currField.displayName); break;
			case SINGLELINE:			isValid = isValid && validateForSingleLine(theValue, currField.displayName); break;
			case MULTILINE:				isValid = isValid && validateForMultiLine(theValue, currField.displayName); break;
			case SMALLINT:				isValid = isValid && validateForSmallInt(theValue, currField.displayName);break;
			case WEIGHT:				isValid = isValid && validateForWeight(theValue, currField.displayName);break;
			case CHARACTER:				isValid = isValid && validateForCharacter(theValue, currField.displayName); break;
			case LETTERANDDIGIT:		isValid = isValid && validateForLetterAndDigit(theValue, currField.displayName); break;
			case HEIGHT:				isValid = isValid && validateForHeight(theValue, currField.displayName); break;
			case CONTACTNAME:			isValid = isValid && validateForContactName(theValue, currField.displayName); break;
		}		
			
	}
	
	return isValid;
}

//used with "onclick" or "onchange" by elements on the page
//to validate a certain field
function validateFormElement(theForm, fieldName)
{

	var currNode = nodeTable.get(fieldName);
	
	if(currNode)
	{
		//because this function supposed to be called only when a field is changed,
		//we can be 99% sure that have unsubmitted inputs on the page at this point
		formElementsAltered = true;	//Will cause the display of save work alert

		//Before validations handle dependency rules and associated elements
		HandleDependenciesAndAssociatedElements(theForm, currNode);

		//Skip on validations if the element is empty
		if(!currNode.domElement.IsEmpty())
		{
			//Perform validations and return the result
			return currNode.validate(theForm);
		}	
	}

	return true;
	
}

function HandleDependenciesAndAssociatedElements(theForm, currNode)
{
	//First Check Dependencies, Disable/Enable children, Clear/Restore values and Show/Hide their associated elements
	var alreadyProcessed = new Array();
	HandleFormElementDependencies(theForm, currNode, alreadyProcessed);		

	//Then Show/Hide "current" node's associated elements
	handleAssociatedElements(theForm, currNode);
}

//Check Dependencies recursively, Disable/Enable children, Show/Hide associated elements, Clear/Restore values
//No error message will return here
function HandleFormElementDependencies(theForm, pageElement, alreadyProcessed)
{	
	
	if(!alreadyProcessed[pageElement.name])
	{
		alreadyProcessed[pageElement.name] = true;
		var dependentChildNodes = pageElement.dependentChildNodes;
		var length = dependentChildNodes.length;
	
		//for each dependent node
		for(var i = 0; i < length; ++i)
		{						
			//Disable/Enable dependent node based on its dependency rule to current node
			handleDependency(theForm, dependentChildNodes[i], GetDependencyText(dependentChildNodes[i], pageElement));

			//Show/Hide dependent node's associated elements (if applies)
			handleAssociatedElements(theForm, dependentChildNodes[i]);

			//drill down 
			HandleFormElementDependencies(theForm, dependentChildNodes[i], alreadyProcessed); 		
		}
	}
}

//Show/Hide current node's associated elements
//associatedElements	--> <associatedElement> (TODO: array of <associatedElement>)
//associatedElement	--> <element name>;<value 1>[||<value 2>[...]][;<behavior>]
//behavior		--> {true}
function handleAssociatedElements(theForm, currNode)
{
	if(useAssociatedElements)
	{
		var currDomElement	= currNode.domElement;
		var element	= document.getElementById(GetAssociatedElementId(currNode.associatedElements));
		if(element)
		{
			//associated element should be visible, if the base element is:
			//		- visible and enable
			//		- match a test value (when one or more test values specified for associated element)
			//		- not empty (when associated element behavior is "true")
			var setVisible	= currDomElement.IsVisible() && currDomElement.IsEnabled();
			if(setVisible)
			{
				var theFieldTestValue = GetAssociatedElementTestValue(currNode.associatedElements)
				if(theFieldTestValue != "" && theFieldTestValue != undefined)
				{
					setVisible = setVisible && NonEmptyValueMatchesOptionalTestValue(theForm, currDomElement, theFieldTestValue);
				}
			}
			if(setVisible)
			{
				var associatedElementBehavior = GetAssociatedElementBehavior(currNode.associatedElements);
				if(associatedElementBehavior == "true")
				{
					setVisible = setVisible && !currDomElement.IsEmpty()
				}
			}

			DomElementFactory.Create(element).SetVisible(setVisible);

		}
	}
}

function GetDependencyText(childPageElement, parentPageElement)
{
	var dependencies 	= childPageElement.dependencies;
	var length 			= dependencies.length;
	var parentName 		= parentPageElement.name;
	
	for(var i = 0; i < length; ++i)
	{
		if(GetDependencyFieldName(dependencies[i]) == parentName)
		{
			return dependencies[i];
		}
	}
}

function GetAssociatedElementId(associatedElementText)
{
	return associatedElementText.split(";")[0];
}

function GetAssociatedElementTestValue(associatedElementText)
{
	return associatedElementText.split(";")[1];
}

//true = to show when the base element is enable, visible and not empty
//undefined = to show when base element is enable and visible
function GetAssociatedElementBehavior(associatedElementText)
{
	return associatedElementText.split(";")[2];
}

function GetDependencyFieldName(dependencyText)
{
	return dependencyText.split(";")[0];
}

function GetDependencyValue(dependencyText)
{
	return dependencyText.split(";")[1];
}

//true = always enabled, required when parent checked
//false = disables with parent, never required
//undefined = disables with parent, required when parent checked
function GetDependencyBehaviour(dependencyText)
{
	return dependencyText.split(";")[2];
}

function ChildDisablesWithParent(textDependencyBehaviour)
{
	return textDependencyBehaviour == "false" || textDependencyBehaviour == undefined;
}

//This function does not work correctly and should be removed
//replace with logic that alerts the user AFTER the hexvalidemail
//validates the email
function validateEmailBeforeValidateForm(theForm,emailTo,emailFrom)
{
	return validateForm(theForm);
	
    //alert(emailTo+emailFrom);
	if(validatePageEmail(emailTo,emailFrom))
	{
		validatePageEmailBool=true;
		return validateForm(theForm);
	}
	else
	{
		return false;
	}
}

//Experience page EMAIL
function validatePageEmail(emailTo,emailFrom)
{
	var errorMessage = "";
	var emailToErrorMessage="";
	var emailFromErrorMessage="";
	
	emailToErrorMessage=IsValidEmailList(emailTo);
	emailFromErrorMessage=IsValidEmailList(emailFrom);
	
	if(emailToErrorMessage !="")
	{
		errorMessage=errorMessage+emailTo;
		
	}
	if(emailFromErrorMessage !="")
	{
		if(errorMessage !="")
		{
			errorMessage = errorMessage+",";
		}
		
		errorMessage = errorMessage+emailFrom;
	}
	if(errorMessage !="")
	{
		errorMessage = errorMessage+' failed validation.  If you still want to attempt to send this email using this address, press \"Ok\".  Otherwise, press \"Cancel\" to abort sending the email.';
		
		if(confirm(errorMessage))
		{
			return true;
		}
		else
		{
			return false;
		}
	}

	return true;

}

//toplevel function used by html page 
function validateForm(theForm)
{
	if(dontValidate)
		return true;
	
	nodeTable.moveFirst();
	
	var currNode = null;

	while(nodeTable.next())
 	{
 		currNode = nodeTable.getValue();
 		
 		if(currNode)
 		{
			if(!currNode.validate(theForm))
			{
			 	setFocus(currNode.formField);
				return false;
			}
		}
	}	 

	formElementsAltered	= false;
	
	return true;
}

//Recursively traverses the document object model and force objects to be visible.
//It will visit a hirarchy of html tags containing the field
function setVisible(theField, iteration)
{
	
	//this function needs to be rewritten.  We need to find a reliable way to find when we
	//are at the top of the hierarchy.  
	if(iteration > 100)
	{
		return;
	}
	
	
	//radio buttons and form tags have a field[0]
	//if radio button, keep going up the tree
	//alert(theField + " " + theField[0] + " " + theField.tagName + " " + theField.parentNode);
	if(theField[0] && !theField.tagName)
	{
		theField = theField[0];
	}
	
	if(theField && theField.style && theField.style.display)
	{
		theField.style.display = "";
	}	
	
	var parentNode = theField.parentNode;
	
	if(parentNode)
	{
		setVisible(parentNode, ++iteration);	
	}
	
	
}

//Just need to call this function before returning false from validateForm
//Can't set the focus to the field on validateFormElement because it won't work and the focus will go to the place that user has intended to go there.
function setFocus(theField)
{
	setVisible(theField, 0);

	//dropdown (theField[0] is true for dropdowns so this should be the first if)
	if(theField.type == "select-one" || theField.type == "select-multiple")
	{
		theField.focus();
	}
	//checkBox/radio
	else if(theField.type == "checkbox" || theField.type == "radio" || theField[0])
	{
			//if the field is a group (theField.type is undefined in this case)
			if(theField[0])
			{
				//set focus to the first option
				theField[0].focus();
			}
			else
			{
				//set focus to the field
				theField.focus();
			}
	}
	//text/textarea
	else if(theField.type == "text" || theField.type == "textarea" || theField.type == "password")
	{
		theField.focus();
		theField.select();
	}
}

function validateForLettersOnly(theField, displayName)
{
	if(isEmpty(theField.value))
		return true;
		
	var letters = theField.value;
	var pattern = /^[a-zA-Z\s,\.]+$/;

	if(!pattern.test(letters))
	{
		alertError("Please only enter letters in the " + displayName +" field.");
		return false;
	}
	return true;
}

function validateForEmpty(theField, displayName)
{
	//dropdown menu
	if(theField.type == "select-one")
	{
		for(var i = 0; i < theField.options.length; ++i)
		{
			if(theField.options[i].selected)
			{
				if(isEmpty(theField.options[i].value))
				{
					alertError("Please select an option for the " + displayName + " field.");
					return false;
				}
				
				else
					return true;
			}
		}	
					
	}
	//checkBox/radio
	if(theField.type == "checkbox" || theField.type == "radio" || theField[0])
	{
		if(theField[0])
		{
			var hasValue = false;
			for(var i = 0; i < theField.length; ++i)
			{
				if(theField[i].checked)
				{
					hasValue = true;
					break;
				}	
			}
		}
		else
			hasValue = theField.checked;
		if(!hasValue)
		{
			alertError("Please check an option for the " + displayName + " field.");
			return false;
		}
			
	
	}

	//text box

	if(theField.value)
	{
		if(isEmpty(trim(theField.value)))
		{
			alertError("Please enter a value for the " + displayName + " field.");
			return false;
		}
	}
	else
		if(isEmpty(theField.value))
		{
			alertError("Please enter a value for the " + displayName + " field.");
			return false;
		}
	
	 
	return true;
}

function validateForNumbersOnly(theField, displayName)
{
	if(isEmpty(theField.value))
		return true;
	
	if(theField.value)
		if(isNaN(theField.value) || (theField.value!=trim(theField.value)))
		{
			alertError("Please only enter numbers in the " + displayName + " field");
			return false;
		}
	
	return true;
}

function validateForEmail(theField, displayName)
{
	var errorMessage = ""
	
	errorMessage = IsValidEmailList(theField.value);

	if(errorMessage != "")
	{
		alertError(errorMessage);
		return false;
	}	

	return true;
}

function IsValidEmailList(emailList)
{
	var errorMessage = "";
	var valueArray = emailList.split(";");

	for(var i = 0; i < valueArray.length; ++i)
	{	
		errorMessage = IsValidEmail(trim(valueArray[i]));
		if(errorMessage != "")
		{
			break;
		}
	}

	return errorMessage;	
}


function IsValidEmail(emailStr)
{
	if(isEmpty(emailStr))
		return "";

	
	var emailPat=/^(.+)@(.+)$/;
	var specialChars="\\(\\)<>@*{}#,;:\\\\\\\"\\.\\[\\]";
	var validChars="\[^\\s" + specialChars + "\]";
	var quotedUser="(\"[^\"]*\")";
	var ipDomainPat=/^\[(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\]$/;
	var atom=validChars + '+';
	var word="(" + atom + "|" + quotedUser + ")";
	var userPat=new RegExp("^" + word + "(\\." + word + ")*$");
	var domainPat=new RegExp("^" + atom + "(\\." + atom +")*$");
	var matchArray=emailStr.match(emailPat);
	var superuserPat=new RegExp("^" + word + "(\\." + word + ")*$");
	if (matchArray==null) 
	{
		return "The email address \"" + emailStr + "\" is not in the correct format...\n\n   Check @ and .'s";
	}

	var user=matchArray[1];
	var domain=matchArray[2];

	if (user.match(userPat)==null) 
	{
    		return "The email address \"" + emailStr + "\" is not in the correct format...\n\n   Check the username";
	}
	else
	{
		if(user.match(new RegExp("'"))!=null)
		{
			return "Although the email address \"" + emailStr + "\" is in the correct format,\n most email programs do not support apostrophe in this format.\n\n  Please provide a different email address.";
		}
	}
	var IPArray=domain.match(ipDomainPat);
	if (IPArray!=null)
	{
    	// this is an IP address
	  	for (var i=1;i<=4;i++) 
	  	{
	    	if (IPArray[i]>255) 
	    	{
	        	return "The email address \"" + emailStr + "\" is not in the correct format...\n\n   Check the destination IP address";
			}
    	}
    	return "";
	}

	var domainArray=domain.match(domainPat);
	if (domainArray==null) 
	{
		return "The email address \"" + emailStr + "\" is not in the correct format...\n\n   Check the host name and/or domain";
	}

	var atomPat=new RegExp(atom,"g");
	var domArr=domain.match(atomPat);
	var len=domArr.length;
	
	if (len<2) 
	{
   		return "The email address \"" + emailStr + "\" is not in the correct format...\n\n   Check the host name and/or domain";
	}
	
	if (domArr[domArr.length-1].length < 2 || domArr[domArr.length-1].length > 4) 
	{
		return "The email address \"" + emailStr + "\" is not in the correct format...\n\n   It must end in a three-letter domain, a two letter country, 'info', or 'name'";
	}
	else if (domArr[domArr.length-1].length == 4 && 
				domArr[domArr.length-1].toLowerCase() != "info" &&
				domArr[domArr.length-1].toLowerCase() != "name") {
		return "The email address \"" + emailStr + "\" is not in the correct format...\n\n   It must end in a three-letter domain, a two letter country, 'info', or 'name'";
	}	

	return "";	

}

function validateForPhoneNumber(theField, displayName)
{
	if(isEmpty(theField.value))
		return true;
		
	var phoneNumber = theField.value;
	var pattern = /^\(?\d{3}\)?\s*?-?\s*?\d{3}\s*-?\s*\d{4}\s*$/;

	if(!pattern.test(phoneNumber))
	{
		alertError("Please re-enter the number for the " + displayName +" field in the format XXX-XXX-XXXX.");
		return false;
	}
	return true;

}

function validateForMoney(theField, displayName)
{
	if(isEmpty(theField.value))
		return true;
		
	var money = theField.value;
	var pattern = /^(\$)?(\d+)?(\.)?(\d+)?$/;

	if(!pattern.test(money))
	{
		alertError("Please enter a valid currency amount in the " + displayName +" field");
		return false;
	}
	return true;

}

function isValidDayMonthYear(theDay, theMonth, theYear, theField, displayName)
{
	if(theMonth < 1 || theMonth > 12)
	{
		alertError("Please enter a month between 1 and 12 in the " + displayName + " field.");
		return false;		
	}
	
	if(theDay < 1 || theDay > 31)
	{
		alertError("Please enter a day between 1 and 31 in the " + displayName + " field.");
		return false;	
	}	


	//javascript counts months starting at 0 and days starting at 1
	var objDate = new Date(theYear, theMonth - 1, theDay);
	
	if(objDate.getDate() != theDay)
	{
		alertError("Please enter a valid date in the " + displayName + " field.");
		return false;	
	}

	return true;

}

function isValidHourMintueSecond(theField, displayName)
{
	var temp = null;
	var theHour = null;
	var theMintue = null;
	var theSecond = null;
	temp = theField.split(" ")[1];
	if (temp != null && temp != undefined)
	{
		temp = temp.split(":");
		theHour = temp[0];
		theMintue = temp[1];
		theSecond = temp[2];
	
		if (theHour != null && theHour != undefined && (theHour < 0 || theHour > 23))
		{
			return false;
		}
		if (theMintue != null && theMintue != undefined && (theMintue < 0 || theMintue > 59))
		{
			return false;
		}
		if (theSecond != null && theSecond != undefined && (theSecond < 0 || theSecond > 59))
		{
			return false;
		}
	}
	
	return true;
}

function validateForDate(theField, displayName)
{
	if(isEmpty(theField.value))
		return true;
		
	var theDate 	= theField.value;
	var aboveMinDate= false;
	var theYear = null;
	var theMonth = null;
	var theDay = null;
	
	var datePattern = getDatePattern(theDate);
	if (datePattern == 99)
	{
		alertError("Please enter a date in one of following formats:\n\n 1) mm/dd/yyyy\n\n 2) mm-dd-yyyy\n\n 3) mm.dd.yyyy\n\n 4) yyyy-mm-dd\n\n 5) mmddyyyy\n\n 6) yyyymmdd\n\n in " + displayName + " field.");
		return false;
	}

	theField.value = formatDate(theField.value, theField, datePattern);

	if(!isAboveDateMin(theField.value))
	{
		alertError("Please enter a date later than 01/01/1900 in the " + displayName +" field.");
		aboveMinDate = false;		
	} else {
		aboveMinDate = true;
	}
	
	if(!isValidHourMintueSecond(theField.value, displayName))
	{
		alertError("Please enter a time between 00:00:00 and 23:59:59 in the " + displayName +" field.");
		aboveMinDate = false;		
	} else {
		aboveMinDate = true;
	}
	theDate = new Date(theField.value);
	theYear = theDate.getFullYear();
	theMonth= theDate.getMonth()+1;
	theDay	= theDate.getDate();
	return ((aboveMinDate) && (isValidDayMonthYear(theDay, theMonth, theYear, theField, displayName)));		
}

//This function was created for FogBugz: 6045 to use to validate the new iPro broker DOB in mm/dd/yyyy format only.
function isValidBrokerDOB(theDOBField, displayName)
{		
    if (theDOBField.value != "")
    {
        //var daysInMonth = daysArray(12)
		var datePattern = getDatePattern(theDOBField.value);
		
	    //Only pattern 1 is allowed mm/dd/yyyy
		if (datePattern != 1)
		{
		  	alertError("Please enter a broker DOB in the following format mm/dd/yyyy in the " + displayName + " field.");
		  	theDOBField.focus();
			theDOBField.style.background = '#FFD9D9';
			return false;
		}
		
		if(isFutureDate(theDOBField.value))
		{
			alertError("Please enter a valid date of birth in the " + displayName +" field.");
			return false;		
		}
	
		formatDate(theDOBField.value, theDOBField, 1);	
		
	}
	
      return true;	
}

function getDatePattern(theDate)
{

	var pattern1 	= /^\d{1,2}(\/)\d{1,2}(\/)(\d{2,4})$/;
	var pattern2 	= /^\d{2,4}(\-)\d{1,2}(\-)(\d{1,2})$/;
	var pattern3 	= /^\d{1,2}(\.)\d{1,2}(\.)(\d{2,4})$/;
	var pattern4 	= /^\d{1,2}(\-)\d{1,2}(\-)(\d{2,4})$/;
	var pattern6 	= /^\d{1,2}(\/)\d{1,2}(\/)(\d{2,4}) \d{1,2}:\d{1,2}:\d{1,2}$/;
	var pattern7 	= /^\d{2,4}(\-)\d{1,2}(\-)(\d{1,2}) \d{1,2}:\d{1,2}:\d{1,2}$/;
	var pattern8 	= /^\d{1,2}(\.)\d{1,2}(\.)(\d{2,4}) \d{1,2}:\d{1,2}:\d{1,2}$/;
	var pattern9 	= /^\d{1,2}(\-)\d{1,2}(\-)(\d{2,4}) \d{1,2}:\d{1,2}:\d{1,2}$/;


	if(pattern1.test(theDate))
	{
		return 1;
	}
	else if(pattern2.test(theDate))
	{
		return 2;
	}
	else if(pattern3.test(theDate))
	{
		return 3;
	}
	else if(pattern4.test(theDate))
	{
		return 4;
	}
	else if(pattern6.test(theDate))
	{
		return 6;
	}
	else if(pattern7.test(theDate))
	{
		return 7;
	}
	else if(pattern8.test(theDate))
	{
		return 8;
	}
	else if(pattern9.test(theDate))
	{
		return 9;
	}
	else if(theDate.length == 8)
	{
		return 5;		
	}
	else
	{
		return 99;
	}
}
function validateForDateLenient(theField, displayName)
{
	if(isEmpty(theField.value))
		return true;
		
	var theDate = theField.value;
	var pattern = /^\d{1,2}(\/|\-)\d{1,2}(\/|\-)(\d{4}|\d{2})$/;

	theField.value = formatDate(theField.value, theField, 0);
	if(!pattern.test(theDate))
	{
		alertError("Please enter a date with the form mm/dd/yyyy in the " + displayName +" field.");
		return false;
	}
	
	if(!isAboveDateMin(theField.value))
	{
		alertError("Please enter a date later than 01/01/1900 in the " + displayName +" field.");
		return false;		
	}
	return true;

}

function validateForDateOfBirth(theField, displayName)
{
	if(isEmpty(theField.value))
		return true;		

	if(!validateForDate(theField, displayName))
		return false;

	if(isFutureDate(theField.value))
	{
		alertError("Please enter a valid date of birth in the " + displayName +" field.");
		return false;		
	}

	if(!isAboveDateMin(theField.value))
	{
		alertError("Please enter a date later than 01/01/1900 in the " + displayName +" field.");
		return false;		
	}


	return true;

}


function validateForFutureDate(theField, displayName, customError)
{
	if(isEmpty(theField.value))
		return true;
		
	if(!validateForDate(theField, displayName))
		return false;
		
	//date of birth checks for date <= today
	if(!isFutureDate(theField.value))
	{
		if (customError && customError.message) {
			alertError(customError.message + " in the " + displayName +" field.");
		
		} else {
			alertError("Please enter a future date in the " + displayName +" field.");
		}
		return false;		
	}
	
	return true
		
}

function validateForPastDate(theField, displayName)
{
	if(isEmpty(theField.value))
		return true;
		
	if(!validateForDate(theField, displayName))
		return false;
			
	if(isFutureDate(theField.value))
	{
		alertError("Please enter a past date in the " + displayName +" field.");
		return false;		
	}
	
	if(!isAboveDateMin(theField.value))
	{
		alertError("Please enter a date later than 01/01/1900 in the " + displayName +" field.");
		return false;		
	}
	
	return true
		
}

function validateForAddress(theField, displayName)
{
	if(isEmpty(theField.value))
		return true;
		
	var address = theField.value;
	var pattern = /^\d+\s+\w+/;
	//var patternPOBox = /(^(p[\s|\.|,]*| ^post[\s|\.]*)(o[\s|\.|,]*| office[\s|\.]*))| (^box[.|\s]*\d+)/;
	var patternPOBox = /\b([P|p](OST|ost)?\.?\s?[O|o|0](ffice|FFICE)?\.?\s)?([B|b][O|o|0][X|x])\s(\d+)/;
	
	if(!pattern.test(address) && !patternPOBox.test(address))
	{
		alertError("Please enter a valid street address or P.O. Box in the " + displayName +" field.");
		return false;
	}
	return true;

}


function validateForSSNumber(theField, displayName)
{
	if(isEmpty(theField.value))
		return true;
		
	var ssNumber = theField.value;
	var pattern = /^\d{3}(-|\s)?\d{2}(-|\s)?\d{4}$/;

	if(!pattern.test(ssNumber))
	{
		alertError("Please enter a valid social security number in the " + displayName +" field.");
		return false;
	}
	return true;

}

function validateForContainsLetter(theField, displayName)
{
	if(isEmpty(theField.value))
		return true;
		
	var theValue = theField.value;
	var pattern = /.*[a-zA-Z].*/;

	if(!pattern.test(theValue))
	{
		alertError("Please enter at least one letter in the " + displayName +" field.");
		return false;
	}
	return true;

}

function validateForInitial(theField, displayName)
{
	if(isEmpty(theField.value))
		return true;
		
	if(theField.value.length > 1)
	{
		alertError("Please only enter one letter in the " + displayName +" field.");
		return false;
	}
	return true;

}

function validateForMonthYear(theField, displayName)
{
	if(isEmpty(theField.value))
		return true;
		
	if(!IsMMYYYY(theField.value))
	{
		alertError("Please enter a valid month and year in the format: MM/YYYY in the " + displayName +" field.");
		return false;
	}
	
	return true;
}

function validateForPastMonthYear(theField, displayName)
{
	if(isEmpty(theField.value))
		return true;
		
	if(!validateForMonthYear(theField, displayName))
	{
		return false;
	}
		
	if(!MonthYearIsPast(theField.value))
	{
		alertError("Please enter a past month and year in the " + displayName +" field.");
		return false;	
	}
	
	return true;
}

function validateForFutureMonthYear(theField, displayName)
{
	if(isEmpty(theField.value))
		return true;

	if(!validateForMonthYear(theField, displayName))
	{
		return false;
	}
		
	if(!MonthYearIsFuture(theField.value))
	{
		alertError("Please enter a future month and year in the " + displayName +" field.");
		return false;	
	}		
	
	return true;
}


function MonthYearIsFutureOrPast(monthYear, isFuture)
{
	var monthYearArray = monthYear.replace(/\-/,"/").split("/");
	var month = monthYearArray[0];
	var year = monthYearArray[1];
	
	var todayMonth = baseDateForValidationOfFuture.getMonth() + 1;
	var todayYear = baseDateForValidationOfFuture.getFullYear();

	if(isFuture)
	{
		return year > todayYear || (year == todayYear && month >= todayMonth);
	}
	else
	{
		return year < todayYear || (year == todayYear && month <= todayMonth);
	}
}

function MonthYearIsFuture(monthYear)
{
	return MonthYearIsFutureOrPast(monthYear, true);
}

function MonthYearIsPast(monthYear)
{
	return MonthYearIsFutureOrPast(monthYear, false);
}

function IsMMYYYY(theValue)
{	
	var pattern = /^\d{1,2}(\-|\/)\d{4}$/;

	if(!pattern.test(theValue))
	{
		return false;
	}
	
	var monthYearArray = theValue.replace(/\-/,"/").split("/");
	var month = monthYearArray[0];
	var year = monthYearArray[1];
	
	return month >= 1 && month <= 12;
}

//validate for common printable charachters only (space/letters/digits/special characters) 
function validateForSingleLine(theField, displayName)
{
	var theValue	= theField.value;
	var pattern =/^[ a-zA-Z0-9\`\~\!\@\#\$%\^\&\*\(\)\_\+\-\=\{\}\|\]\[\:\"\;\'\<\>\?\,\.\\\/]*$/;

	if(!pattern.test(theValue))
	{
		alertError(displayName + " field contains one or more invalid characters (it may look like a space character).");
		return false;
	}
	return true;
}

//validate for printable charachters (space/letters/digits/special characters/common symbols) plus white space
function validateForMultiLine(theField, displayName)
{
	var theValue	= theField.value;
	var pattern =/^[\sa-zA-Z0-9\`\~\!\@\#\$%\^\&\*\(\)\_\+\-\=\{\}\|\]\[\:\"\;\'\<\>\?\,\.\\\/]*$/;
//TODO: add common symbols to the pattern and uncomment the test
/*
	if(!pattern.test(theValue))
	{
		alertError(displayName + "field contains one or more invalid characters (it may look like a space character).");
		return false;
	}
*/
	return true;
}

function validateForSmallInt(theField, displayName)
{
	var theValue	= theField.value;

	if(isEmpty(theValue))
		return true;

	var pattern =/^[-+]?[1-9]+[0-9]*$/;

	if(!pattern.test(theValue))
	{
		alertError("Please enter a valid non decimal number with no leading zeros in the " + displayName + " field.");
		return false;
	}
	
	if(theValue < -32768 || theValue > 32767)
	{
		alertError("Please enter a small integer number in " + displayName);
		return false;
	}

	return true;
}

function validateForWeight(theField, displayName)
{
	var theValue	= theField.value;
	if(isEmpty(theValue))
		return true;

	var pattern =/^[1-9]+[0-9]*$/;

	if(!pattern.test(theValue))
	{
		alertError("Please enter a positive non decimal number with no leading zeros in the " + displayName + " field.");
		return false;
	}
	
	if(theValue > 1000)
	{
		alertError("Please enter a valid weight in scale of lbs in " + displayName);
		return false;
	}

	return true;
}
function validateForHeight(theField, displayName) 
{
    var theValue = theField.value;
    if (isEmpty(theValue))
        return true;

    var pattern = /^[0-9]+[0-9]*$/;

    if (!pattern.test(theValue)) {
        alertError("Please enter a positive non decimal number in the " + displayName + " field.");
        return false;
    }

    if (theValue > 1000) {
        alertError("Please enter a valid height in scale of ft(in) in " + displayName);
        return false;
    }

    return true;
}
 
//validate only letter, digit, whitespace and \".,()\" characters
function validateForCharacter(theField, displayName)
{
	var theValue	= theField.value;
	var pattern =/^[ a-zA-Z0-9\,\.\(\)\t\r\n\f]*$/;
	if(!pattern.test(theValue))
	{
		alertError( "Please enter only letter, digit, whitespace and \".,()\" characters in the " + displayName + " field.");
		return false;
	}
	return true;
}

//validate only letter and \"-\" characters
function validateForContactName(theField, displayName) {
	var theValue = theField.value;
	var pattern = /^[a-zA-Z\-\t\r\n\f]*$/;
	if (!pattern.test(theValue)) {
		alertError("Please enter only letter and \"-\" characters in the " + displayName + " field.");
		return false;
	}
	return true;
}

//validate only letter and digit characters
function validateForLetterAndDigit(theField, displayName)
{
	var theValue	= theField.value;
	var pattern =/^[a-zA-Z0-9]*$/;

	if(!pattern.test(theValue))
	{
		alertError( "Please enter only letter and digit characters in the  " + displayName + " field.");
		return false;
	}
	return true;
}

function getDisplayName(theName)
{


	var displayName = "";
	for(var i = 0; i < theName.length; ++i)
	{
		if(i == 0)
			displayName += theName.charAt(0).toUpperCase();
		else if(!isNaN(theName.charAt(i)))
			displayName += " " + theName.charAt(i);
		else if(isUpperCase(theName.charAt(i)))
			displayName += " " + theName.charAt(i);
		else
			displayName += theName.charAt(i);
	
	}
  
	return displayName;
}

function isEmpty(theValue)
{
	return theValue == "";
}

function isUpperCase(theChar)
{
	var pattern = /[A-Z]/;
	return pattern.test(theChar);

}

function getComparisonExpression(theValue, theVariable)
{
	var stringPieces = theValue.split(" ");
	var theSentence = "";
	var evalString = theVariable + " ";
	for(var i = 0; i < stringPieces.length; ++i)
	{
		
		evalString += stringPieces[i]; + " ";
		if(isConditional(stringPieces[i]))
			evalString += " " + theVariable + " ";
		 
		theSentence += " " + codeToWords(stringPieces[i]);
	}
	theSentence += ".";
	return {eval: evalString, sentence: theSentence};
}

function isConditional(theValue)
{
 	return (theValue == "&&" || theValue == "||");
}

function codeToWords(theCode)
{
	switch(theCode)
	{
		case "&&": 	return "and";
		case "||": 	return "or";
		case ">": 	return "greater than"; 
		case "<": 	return "less than"; 
		case ">=": 	return "greater than or equal to"; 
		case "<=": 	return "less than or equal to"; 
		case "==": 	return "equal to"; 
		default:	return theCode; 
	}

}


function isFutureDate(theDate)
{

	var pattern1 	= /^\d{1,2}(\/)\d{1,2}(\/)(\d{4})$/;
	var pattern2 	= /^\d{4}(\-)\d{1,2}(\-)(\d{1,2})$/;
	var pattern3 	= /^\d{1,2}(\.)\d{1,2}(\.)(\d{4})$/;
	var pattern6 	= /^\d{1,2}(\/)\d{1,2}(\/)(\d{4}) \d{1,2}:\d{1,2}:\d{1,2}$/;
	var pattern7 	= /^\d{4}(\-)\d{1,2}(\-)(\d{1,2}) \d{1,2}:\d{1,2}:\d{1,2}$/;
	var pattern8 	= /^\d{1,2}(\.)\d{1,2}(\.)(\d{4}) \d{1,2}:\d{1,2}:\d{1,2}$/;
	
	var dateArray	= null;
	var theDay 		= null;
	var theMonth 	= null;
	var theYear 	= null;
	
	if(pattern1.test(theDate))
	{
		dateArray 	= theDate.split("/");
		theMonth 	= dateArray[0];
		theDay 		= dateArray[1];
		theYear 	= dateArray[2];
	}
	else if(pattern2.test(theDate))
	{
		dateArray 	= theDate.split("-");		
		theYear 	= dateArray[0];
		theMonth 	= dateArray[1];
		theDay 		= dateArray[2];
	}
	else if(pattern3.test(theDate))
	{
		dateArray 	= theDate.split(".");		
		theMonth 	= dateArray[0];
		theDay 		= dateArray[1];
		theYear 	= dateArray[2];
	}
	else if(theDate.length == 8)
	{
		theMonth = theDate.substring(0,2);
		theDay = theDate.substring(2,4);
		theYear = theDate.substring(4,8);
	}
	else if (pattern6.test(theDate))
	{
		dateArray 	= theDate.split(" ")[0].split("/");		
		theMonth 	= dateArray[0];
		theDay 		= dateArray[1];
		theYear 	= dateArray[2];
	}
	else if (pattern7.test(theDate))
	{
		dateArray 	= theDate.split(" ")[0].split("-");		
		theMonth 	= dateArray[0];
		theDay 		= dateArray[1];
		theYear 	= dateArray[2];
	}
	else if (pattern8.test(theDate))
	{
		dateArray 	= theDate.split(" ")[0].split(".");		
		theMonth 	= dateArray[0];
		theDay 		= dateArray[1];
		theYear 	= dateArray[2];
	}


	var objDate = new Date(theYear, theMonth - 1, theDay);
	return (objDate > baseDateForValidationOfFuture);

}

function isAboveDateMin(theDate)
{

	var pattern1 	= /^\d{1,2}(\/)\d{1,2}(\/)(\d{4})$/;
	var pattern2 	= /^\d{4}(\-)\d{1,2}(\-)(\d{1,2})$/;
	var pattern3 	= /^\d{1,2}(\.)\d{1,2}(\.)(\d{4})$/;
	var dateArray	= null;
	var theDay 		= null;
	var theMonth 	= null;
	var theYear 	= null;
	
	if(pattern1.test(theDate))
	{
		dateArray 	= theDate.split("/");
		theMonth 	= dateArray[0];
		theDay 		= dateArray[1];
		theYear 	= eval(dateArray[2]);
	}
	else if(pattern2.test(theDate))
	{
		dateArray 	= theDate.split("-");		
		theYear 	= eval(dateArray[0]);
		theMonth 	= dateArray[1];
		theDay 		= dateArray[2];
	}
	else if(pattern3.test(theDate))
	{
		dateArray 	= theDate.split(".");		
		theMonth 	= dateArray[0];
		theDay 		= dateArray[1];
		theYear 	= eval(dateArray[2]);
	}
	else if(theDate.length == 8)
	{
		theMonth = theDate.substring(0,2);
		theDay = theDate.substring(2,4);
		theYear = theDate.substring(4,8);
	}

	if(theYear <= 50)
		theYear += 2000;
	
	var objDate = new Date(1900, 0, 1);
	var compDate = new Date(theYear, theMonth - 1, theDay)
	
	return (objDate < compDate);

}


function trim(strText) { 
   return strText.replace(/^\s*|\s*$/g,"");
}


//Element Value Matches the Test Value when:
// 1: the element has some value
// 2: and that value matches any of the specified test values separated by || 
//    or the test value is empty
function NonEmptyValueMatchesOptionalTestValue(theForm, domElement, theFieldTestValue)
{
	var splitValues		= theFieldTestValue.split("||");
	var valueMatchesTestValue	= false;
	if(domElement)
	{
		if(!domElement.IsEmpty())
		{
			valueMatchesTestValue	= isEmpty(theFieldTestValue);
			var fieldValue = ForceArray(domElement.GetValue())[0];
			var fieldFullValue = ForceArray(domElement.GetValue()).join(",");

			for(var j = 0; j < splitValues.length; ++j)
			{
				if(ForceArray(domElement.element)[0].type == 'checkbox')
					valueMatchesTestValue	=	valueMatchesTestValue || ("," + fieldFullValue + ",").indexOf("," + splitValues[j] + ",") != -1;
				else
					valueMatchesTestValue	=	valueMatchesTestValue || fieldValue == splitValues[j];
				if (valueMatchesTestValue)	
					return true;
			}
		}
	}
	
	return valueMatchesTestValue;
}


function enableDependency(domElement, childDisablesWithParent)
{
	if(domElement && childDisablesWithParent)
	{
		if(!domElement.IsEnabled())
		{
			var pageElement = findPageElement(domElement.GetName())
			domElement.SetEnabled(true, pageElement.restoreValue);
		}
	}
}	

function disableDependency(domElement, childDisablesWithParent)
{
	if(domElement && childDisablesWithParent)
	{
		domElement.HighlightField(true);
		var pageElement = findPageElement(domElement.GetName());
		domElement.SetEnabled(false, pageElement.restoreValue);
	}		
}

function setFieldEnabled(domElement, isEnabled, changeBackground, uncheck, clearValue)
{
	var domElement = ForceArray(domElement.element);
	var length = domElement.length;
	
	if(isEnabled)
	{
		for(var i = 0; i < length; ++i)
		{
			domElement[i].readOnly = false;			
			domElement[i].disabled = false;	
			if(changeBackground)
			{		
				domElement[i].style.backgroundColor = "";						
			}
			
		}
	}
	else
	{
		for(var i = 0; i < length; ++i)
		{
			if(clearValue)
			{
				domElement[i].value = "";
			}
			domElement[i].readOnly = true;
			domElement[i].disabled = true;			
			if(changeBackground)
			{		
				domElement[i].style.backgroundColor = "#D6D3CE";
			}
			if(uncheck)
			{
				domElement[i].checked = false;
			}
		}
	}	
}

function onLoadDisableDependencies(theForm)
{
	InitDomObjectsAndDependencies();
	var start = new Date();
	if(!theForm)
	{
		theForm = document.forms[0];
	}

	var currNode;

	nodeTable.moveFirst();		
	while(nodeTable.next())
 	{
 		currNode = nodeTable.getValue();
 		
 		if(currNode)
 		{
 			HandleDependenciesAndAssociatedElements(theForm, currNode);
		}

	}

	var end = new Date();
	
	if(debugTiming)
	{
		alert("onLoadDisableDependencies: " + (end - start));
	}	
}

// This function will calculate the age by the DOB againts the effective.
function getAge(dateOfBirth, dateEntered)
{
	if(dateOfBirth == "" || dateOfBirth == undefined)
		return "";

	var dateArray =  dateOfBirth.split(/\//);
	if(dateArray[2])
	{
		var month = parseInt(dateArray[0]) - 1;
		var day   = parseInt(dateArray[1]);
		var year  = parseInt(dateArray[2]);
	}
	else
	{
		dateArray = dateOfBirth.split(/-/);
		var month = parseInt(dateArray[0]) - 1;
		var day   = parseInt(dateArray[1]);
		var year  = parseInt(dateArray[2]);
	}
	//var today = dateEntered ? new Date(dateEntered) : new Date();
	if (dateEntered)
	{
		if (dateEntered == null) { 
			dateEntered = new Date(); 
		} else {
			if (typeof dateEntered == "string") {
				dateEntered = new Date(dateEntered);
			}
		}
	} else {
		dateEntered = new Date(); 
	}
	
	var age = dateEntered.getFullYear() - year;
	if (age > 0) {
		if (dateEntered.getMonth() < month || (dateEntered.getMonth() == month && dateEntered.getDate() < day))
			age--;
	}
	return age;
}


// should return true if AllDependenciesOk Or NoDependencies 
function AllDependenciesOk(pageElement, theForm)
{
	for(var i = 0; i < pageElement.dependencies.length; ++i)
	{		
		var splitArray = pageElement.dependencies[i].split(";");

		var	theFieldTestValue = splitArray.length > 1 ? splitArray[1] : "";
		
		if(!NonEmptyValueMatchesOptionalTestValue(theForm, nodeTable.get(splitArray[0]).domElement, theFieldTestValue))
		{
			return false;
		}			
	}
	
	return true;
}

//Takes in a child page element and a dependency to a parent element
function handleDependency(theForm, pageElement, dependencyText)
{
	var childDisablesWithParent = disableDependencies && ChildDisablesWithParent(GetDependencyBehaviour(dependencyText));
	
	if(childDisablesWithParent)
	{
		var domElement = pageElement.domElement;	
		if(AllDependenciesOk(pageElement, theForm))
		{
			enableDependency(domElement, childDisablesWithParent);
		}
		else
		{
			disableDependency(domElement, childDisablesWithParent);	
		}
	}
}

function addEvent(element, evType, func) {

	if (element.addEventListener) {
		element.addEventListener(evType, func, false);
		return true;
	}
	else if (element.attachEvent) {
		var r = element.attachEvent('on' + evType, func);
		return r;
	}
	else {
		element['on' + evType] = func;
	}
	
}

function removeEvent(element, evType, func) {

	if (element.removeEventListener) {
		element.removeEventListener(evType, func, false);
		return true;
	}
	else if (element.detachEvent) {
		var r = element.detachEvent('on' + evType, func);
		return r;
	}
	else {
		element['on' + evType] = "";
	}
	
}

function addOnClickEvent(element, func) 
{
	
  var oldOnClick = element.onclick;
  
  if (typeof oldOnClick != 'function') 
  {
    element.onclick = func;
  } 
  else 
  {
    element.onclick = function() 
    {
      oldOnClick ();
      func();
    }
  }
  
}

function addOnChangeEvent(element, func) 
{
	
  var oldOnChange = element.onchange;
  
  if (typeof oldOnChange != 'function') 
  {
    element.onchange= func;
  } 
  else 
  {
    element.onchange= function() 
    {
      oldOnChange();
      func();
    }
  }
  
}

function GetDomElement(theNode, theForm)
{
	var formField = null;
	
	if(theNode)
	{
		if(theNode.formField)
		{
			formField = theNode.formField;		
		}
		else
		{
			formField = eval("theForm." + theNode.name);
		}
	}
		
	return formField;
}

function ForceArray(element)
{
	var returnValue = null;
	
	if(Object.prototype.toString.apply(element) === '[object Array]' || (typeof element === "object" && element[0]))
	{
		returnValue = element;
	}
	else
	{
		returnValue = new Array();
		returnValue.push(element);
	}
	
	return returnValue;
}



/*******************************************************************************************
 * Object: Hashtable
 * Description: Implementation of hashtable
 * Author: Uzi Refaeli
 *******************************************************************************************/

//======================================= Properties ========================================
Hashtable.prototype.hash	 	= null;
Hashtable.prototype.keys		= null;
Hashtable.prototype.location	= null;

/**
 * Hashtable - Constructor
 * Create a new Hashtable object.
 */
function Hashtable() {
    try {
        this.hash = new Array();
        this.keys = new Array();
    } 
    catch (e) { }
	this.location = 0;
}

/**
 * put
 * Add new key
 * param: key - String, key name
 * param: value - Object, the object to insert
 */
Hashtable.prototype.put = function (key, value){
	if (value == null)
		return;

	if (this.hash[key] == null)
		this.keys[this.keys.length] = key;

	this.hash[key] = value;
}

/**
 * get
 * Return an element
 * param: key - String, key name
 * Return: object - The requested object
 */
Hashtable.prototype.get = function (key){
		return this.hash[key];
}

/**
 * remove
 * Remove an element
 * param: key - String, key name
 */
Hashtable.prototype.remove = function (key){
	for (var i = 0; i < this.keys.length; i++){
		//did we found our key?
		if (key == this.keys[i]){
			//remove it from the hash
			this.hash[this.keys[i]] = null;
			//and throw away the key...
			this.keys.splice(i ,1);
			return;
		}
	}
}

/**
 * size
 * Return: Number of elements in the hashtable
 */
Hashtable.prototype.size = function (){
    return this.keys.length;
}

/**
 * populateItems
 * Deprecated
 */
Hashtable.prototype.populateItems = function (){}

/**
 * next
 * Return: true if theres more items
 */
Hashtable.prototype.next = function (){
	if (++this.location < this.keys.length)
		return true;
	else
		return false;
}

/**
 * moveFirst
 * Move to the first item.
 */
Hashtable.prototype.moveFirst = function (){
	try {
		this.location = -1;
	} catch(e) {/*//do nothing here :-)*/}
}

/**
 * moveLast
 * Move to the last item.
 */
Hashtable.prototype.moveLast = function (){
	try {
		this.location = this.keys.length - 1;
	} catch(e) {/*//do nothing here :-)*/}
}

/**
 * getKey
 * Return: The value of item in the hash
 */
Hashtable.prototype.getKey = function (){
	try {
		return this.keys[this.location];
	} catch(e) {
		return null;
	}
}

/**
 * getValue
 * Return: The value of item in the hash
 */
Hashtable.prototype.getValue = function (){
	try {
		return this.hash[this.keys[this.location]];
	} catch(e) {
		return null;
	}
}

/**
 * getKey
 * Return: The first key contains the given value, or null if not found
 */
Hashtable.prototype.getKeyOfValue = function (value){
	for (var i = 0; i < this.keys.length; i++)
		if (this.hash[this.keys[i]] == value)
			return this.keys[i]
	return null;
}


/**
 * toString
 * Returns a string representation of this Hashtable object in the form of a set of entries,
 * enclosed in braces and separated by the ASCII characters ", " (comma and space).
 * Each entry is rendered as the key, an equals sign =, and the associated element,
 * where the toString method is used to convert the key and element to strings.
 * Return: a string representation of this hashtable.
 */
Hashtable.prototype.toString = function (){

	try {
		var s = new Array(this.keys.length);
		s[s.length] = "{";

		for (var i = 0; i < this.keys.length; i++){
			s[s.length] = this.keys[i];
			s[s.length] = "=";
			var v = this.hash[this.keys[i]];
			if (v)
				s[s.length] = v.toString();
			else
				s[s.length] = "null";

			if (i != this.keys.length-1)
				s[s.length] = ", ";
		}
	} catch(e) {
		//do nothing here :-)
	}finally{
		s[s.length] = "}";
	}

	return s.join("");
}

/**
 * add
 * Concatanates hashtable to another hashtable.
 */
Hashtable.prototype.add = function(ht){
	try {
		ht.moveFirst();
		while(ht.next()){
			var key = ht.getKey();
			//put the new value in both cases (exists or not).
			this.hash[key] = ht.getValue();
			//but if it is a new key also increase the key set
			if (this.get(key) != null){
				this.keys[this.keys.length] = key;
			}
		}
	} catch(e) {
		//do nothing here :-)
	} finally {
		return this;
	}
};


//-----------------------------------------------------------------------------
// DomElementType
//-----------------------------------------------------------------------------
function DomElementType(name) {
    this.name = name;
}
	
DomElementType.prototype.ToString = function () {
    return this.name;    
};
	
DomElementType.TextBox    		= new DomElementType('textbox');
DomElementType.CheckBoxList 	= new DomElementType('checkboxlist');
DomElementType.RadioButtonList  = new DomElementType('radiobuttonlist');
DomElementType.DropDown   		= new DomElementType('dropdown');


//-----------------------------------------------------------------------------
// DomElementFactory
//-----------------------------------------------------------------------------
function DomElementFactory()
{
}

DomElementFactory.Create = function(domElement)
{
	if(domElement)
	{	
		var type = null;
		
		if(domElement.type)
		{
			type = domElement.type
		}
		else if(domElement[0])
		{
			if(domElement[0].type)
			{
				type = domElement[0].type
			}
		}

		if(type == 'text' || type == 'password')
		{
			return new TextBox(domElement);
		}
		else if(type == 'checkbox')
		{		
			return new CheckBoxList(domElement);
		}
		else if(type == 'radio')
		{		
			return new RadioButtonList(domElement);
		}
		else if(type == 'select-one' || type == 'select-multiple')
		{		
			return new DropDownList(domElement);
		}
		else if(type == 'textarea')
		{		
			return new TextArea(domElement);
		}
		else if(type == 'hidden')
		{	
			return new Hidden(domElement);
		}
		else
		{
			return new DomElement(domElement);
		}
	}	
}

//-----------------------------------------------------------------------------
// DomElement
//-----------------------------------------------------------------------------

function DomElement(domElement)
{
	if ( arguments.length > 0 )
	{
		this.Init(domElement);	
	}
}

DomElement.prototype.Init = function(domElement)
{
	this.element = domElement;
	this.savedValue = null;
}

DomElement.prototype.GetValue = function()
{
}

DomElement.prototype.SetValue = function(value)
{
}

DomElement.prototype.IsEmpty = function()
{
}

DomElement.prototype.HighlightField = function(isValid)
{
	var domElement = ForceArray(this.element);
	
	if(!domElement[0].disabled && !domElement[0].readOnly)
	{
		if(isValid)
		{
			domElement[0].style.backgroundColor = "";
		}
		else
		{
			domElement[0].style.backgroundColor = invalidFieldColor;
		}
	}
}

DomElement.prototype.GetName = function()
{	
	var domElement = this.element;	
	return domElement.name;	
}

DomElement.prototype.SetEnabled = function(isEnabled, restoreValue)
{
	this.SaveRestoreValue(isEnabled, restoreValue);
	setFieldEnabled(this, isEnabled, true, false, true);
}

DomElement.prototype.IsEnabled = function()
{
	return !this.element.disabled;
}

DomElement.prototype.SetVisible = function(isVisible)
{
	if(isVisible)
	{
		ForceArray(this.element)[0].style.display = "";
	}
	else
	{
		ForceArray(this.element)[0].style.display = "none";
	}
}

DomElement.prototype.IsVisible = function()
{
	return !(ForceArray(this.element)[0].style.display == "none");
}

DomElement.prototype.SaveRestoreValue = function(isEnabled, restoreValue)
{
	if(restoreValue)
	{
		if(isEnabled && this.savedValue)
		{
			this.SetValue(this.savedValue);
			this.savedValue = null;
		}
		else
		{
			if(this.IsEnabled())
			{
				this.savedValue = this.GetValue();
			}
		}
	}		
}

DomElement.prototype.IsEnabled = function()
{
	return !this.element.disabled;	
}

//-----------------------------------------------------------------------------
// Textbox
//-----------------------------------------------------------------------------
TextBox.prototype = new DomElement();
TextBox.prototype.constructor = DomElement;
TextBox.superclass = DomElement.prototype;

function TextBox(domElement)
{
	TextBox.superclass.Init.call(this, domElement);
}

TextBox.prototype.GetValue = function()
{
	return this.element.value;
}

TextBox.prototype.SetValue = function(value)
{
	this.element.value = value;
}

TextBox.prototype.IsEmpty = function()
{
	return this.element.value == "";
}


//-----------------------------------------------------------------------------
// TextArea
//-----------------------------------------------------------------------------
TextArea.prototype = new DomElement();
TextArea.prototype.constructor = DomElement;
TextArea.superclass = DomElement.prototype;

function TextArea(domElement)
{
	TextArea.superclass.Init.call(this, domElement);
}

TextArea.prototype.GetValue = function()
{
	return this.element.value;
}

TextArea.prototype.SetValue = function(value)
{
	this.element.value = value;
}

TextArea.prototype.IsEmpty = function()
{
	return this.GetValue() == "";
}


//-----------------------------------------------------------------------------
// CheckBoxList
//-----------------------------------------------------------------------------
CheckBoxList.prototype = new DomElement();
CheckBoxList.prototype.constructor = DomElement;
CheckBoxList.superclass = DomElement.prototype;

function CheckBoxList(domElement)
{
	CheckBoxList.superclass.Init.call(this, domElement);
}

CheckBoxList.prototype.GetValue = function()
{
	var domElement = ForceArray(this.element);
	var returnArray = new Array();
	var currentBox = null;
	var length = domElement.length;
	
	for(var i = 0; i < length; ++i)
	{
		currentBox = domElement[i];
		
		if(currentBox.checked)
		{
			returnArray.push(currentBox.value);
		}
	}

	return returnArray;
}

CheckBoxList.prototype.SetValue = function(value)
{
	var values = "," + value + ",";		
	var domElement = ForceArray(this.element);	

	for(var i = 0; i < domElement.length; ++i)
	{		
		domElement[i].checked = values.indexOf(","+domElement[i].value+",") != -1;
	}
}

CheckBoxList.prototype.GetName = function()
{	
	var domElement = ForceArray(this.element)[0];	
	return domElement.name;	
}

CheckBoxList.prototype.IsEmpty = function()
{
	var domElement = ForceArray(this.element);
	var bFound;

	for(var i = 0; i < domElement.length; ++i)
	{
		if(domElement[i].checked)
		{
			return false;
		}
	}
	
	return true;
}

CheckBoxList.prototype.HighlightField = function(isValid)
{
	var domElement = ForceArray(this.element);
	
	if(isValid)
	{
		domElement[0].style.backgroundColor = "";
	}
	else
	{
		domElement[0].style.backgroundColor = invalidFieldColor;
	}
}

CheckBoxList.prototype.SetEnabled = function(isEnabled, restoreValue)
{
	this.SaveRestoreValue(isEnabled, restoreValue);
	setFieldEnabled(this, isEnabled, false, true, false);
}

CheckBoxList.prototype.IsEnabled = function()
{
	return !ForceArray(this.element)[0].disabled;
}

//-----------------------------------------------------------------------------
// RadioButtonList
//-----------------------------------------------------------------------------
RadioButtonList.prototype = new DomElement();
RadioButtonList.prototype.constructor = DomElement;
RadioButtonList.superclass = DomElement.prototype;

function RadioButtonList(domElement)
{
	RadioButtonList.superclass.Init.call(this, domElement);
}

RadioButtonList.prototype.GetValue = function()
{
	var domElement = ForceArray(this.element);
	var returnArray = new Array();
	var currentBox = null;
	var length = domElement.length;
	
	for(var i = 0; i < length; ++i)
	{
		currentBox = domElement[i];
		
		if(currentBox.checked)
		{
			returnArray.push(currentBox.value);
		}
	}

	return returnArray;
}

RadioButtonList.prototype.SetValue = function(value)
{
	var values = "," + value + ",";		
	var domElement = ForceArray(this.element);	

	for(var i = 0; i < domElement.length; ++i)
	{		
		domElement[i].checked = values.indexOf(","+domElement[i].value+",") != -1;
	}
}

RadioButtonList.prototype.GetName = function()
{	
	var domElement = ForceArray(this.element)[0];	
	return domElement.name;	
}

RadioButtonList.prototype.IsEmpty = function()
{
	var domElement = ForceArray(this.element);
	var bFound;

	for(var i = 0; i < domElement.length; ++i)
	{
		if(domElement[i].checked)
		{
			return false;
		}
	}
	
	return true;
}


RadioButtonList.prototype.HighlightField = function(isValid)
{
	var domElement = ForceArray(this.element);
	if(isValid)
	{
		domElement[0].style.backgroundColor = ""
	}
	else
	{
		domElement[0].style.backgroundColor = invalidFieldColor;
	}
}

RadioButtonList.prototype.SetEnabled = function(isEnabled, restoreValue)
{
	this.SaveRestoreValue(isEnabled, restoreValue);
	setFieldEnabled(this, isEnabled, false, true, false);
}

RadioButtonList.prototype.IsEnabled = function()
{
	return !ForceArray(this.element)[0].disabled;
}


//-----------------------------------------------------------------------------
// DropDownList
//-----------------------------------------------------------------------------
DropDownList.prototype = new DomElement();
DropDownList.prototype.constructor = DomElement;
DropDownList.superclass = DomElement.prototype;

function DropDownList(domElement)
{
	DropDownList.superclass.Init.call(this, domElement);
}

DropDownList.prototype.GetValue = function()
{
	var options = this.element.options;
	
	if(!options)
	{
		return null;
	}
	
	var returnArray = new Array();
	var currentOption = null;
	var length = options.length;
	
	for(var i = 0; i < length; ++i)
	{
		currentOption = options[i];
		
		if(currentOption.selected)
		{
			returnArray.push(currentOption.value);
		}
	}

	return returnArray;
}

DropDownList.prototype.SetValue = function(value)
{				
	var values = "," + value + ",";		
	var options = this.element.options;
	var currentOption = null;
	

	for(var i = 0; i < options.length; ++i)
	{
		currentOption = options[i];		
		currentOption.selected = values.indexOf(","+currentOption.value+",") != -1;;
	}
}

DropDownList.prototype.IsEmpty = function()
{
	var value = this.GetValue()[0];
	return value == "" || value == undefined;
}

DropDownList.prototype.SetEnabled = function(isEnabled, restoreValue)
{
	this.SaveRestoreValue(isEnabled, restoreValue);
	
	var domElement = this.element;
	
	if(isEnabled)
	{
		domElement.disabled = false;
	}
	else
	{
		if(domElement.options && domElement.options[0])
		{
			domElement.options[0].selected = true;
		}
		domElement.disabled = true;
	}
}

function TrimWhiteSpace(field, maxlimit) 
  {
     if (field.value.length > maxlimit) 
         field.value = field.value.substring(0, maxlimit);
}

//-----------------------------------------------------------------------------
// Hidden
//-----------------------------------------------------------------------------
Hidden.prototype = new DomElement();
Hidden.prototype.constructor = DomElement;
Hidden.superclass = DomElement.prototype;

function Hidden(domElement)
{
	Hidden.superclass.Init.call(this, domElement);
}

Hidden.prototype.GetValue = function()
{
	return this.element.value;
}

Hidden.prototype.SetValue = function(value)
{
	this.element.value = value;
}

Hidden.prototype.IsEmpty = function()
{
	return this.element.value == "";
}


Hidden.prototype.SetEnabled = function(isEnabled, restoreValue)
{
}

function getFirstDateOfMonth(strDate)
{
	var aDate = new Date(strDate);
	var aValue;
	aValue = (aDate.getMonth()+1) + "/1/" + aDate.getFullYear();
	return aValue;
}
function formatDate(theDate, theDateField, patternNum)
{
	var dateArray;
	var theYear, theMonth, theDay, theHour, theMintue, theSecond;

	if (patternNum == null || patternNum == 0) 
	{
		patternNum = getDatePattern(theDate);
	}

	switch (patternNum)
	{
		case 1:
			dateArray 	= theDate.split("/");
			theMonth 	= dateArray[0];
			theDay 		= dateArray[1];
			theYear 	= dateArray[2];
			break;
		case 2:
			dateArray 	= theDate.split("-");		
			theYear 	= dateArray[0];
			theMonth 	= dateArray[1];
			theDay 		= dateArray[2];
			break;
		case 3:
			dateArray 	= theDate.split(".");		
			theMonth 	= dateArray[0];
			theDay 		= dateArray[1];
			theYear 	= dateArray[2];
			break;
		case 4:
			dateArray 	= theDate.split("-");
			theMonth 	= dateArray[0];
			theDay 		= dateArray[1];
			theYear 	= dateArray[2];
			break;
		case 5:
			theMonth = theDate.substring(0,2);
			theDay = theDate.substring(2,4);
			theYear = theDate.substring(4,8);
			
			if (parseInt(theMonth) > 12) {
				theYear = theDate.substring(0,4);
				theMonth = theDate.substring(4,6);
				theDay = theDate.substring(6,8);		
			}
			break;
		case 6:
			dateArray 	= theDate.split(" ")[0].split("/");
			theMonth 	= dateArray[0];
			theDay 		= dateArray[1];
			theYear 	= dateArray[2];
			dateArray	= theDate.split(" ")[1].split(":");
			theHour		= dateArray[0];
			theMintue	= dateArray[1];
			theSecond	= dateArray[2];
			break;
		case 7:
			dateArray 	= theDate.split(" ")[0].split("-");		
			theYear 	= dateArray[0];
			theMonth 	= dateArray[1];
			theDay 		= dateArray[2];
			dateArray	= theDate.split(" ")[1].split(":");
			theHour		= dateArray[0];
			theMintue	= dateArray[1];
			theSecond	= dateArray[2];
			break;
		case 8:
			dateArray 	= theDate.split(" ")[0].split(".");		
			theMonth 	= dateArray[0];
			theDay 		= dateArray[1];
			theYear 	= dateArray[2];
			dateArray	= theDate.split(" ")[1].split(":");
			theHour		= dateArray[0];
			theMintue	= dateArray[1];
			theSecond	= dateArray[2];
		case 9:
			dateArray 	= theDate.split(" ")[0].split("-");
			theMonth 	= dateArray[0];
			theDay 		= dateArray[1];
			theYear 	= dateArray[2];
			dateArray	= theDate.split(" ")[1].split(":");
			theHour		= dateArray[0];
			theMintue	= dateArray[1];
			theSecond	= dateArray[2];
			break;
		default:
			alertError("Please enter a date in one of following formats:\n\n 1) mm/dd/yyyy\n\n 2) mm-dd-yyyy\n\n 3) mm.dd.yyyy\n\n 4) yyyy-mm-dd\n\n 5) mmddyyyy\n\n 6) yyyymmdd");
			theDateField.focus();
			return theDate;	
	}
	
	//alert(theYear);

	//logic to read user's mind and guess the full year on 2 digit years 
	if( theYear.length == 2) {
		var today = new Date()
		var currentYY = today.getFullYear() - 2000
		if (parseInt(theYear) > currentYY + 1) {
			theYear = "19" + theYear;
		} else {
			theYear = "20" + theYear;
		}
	}

	if( parseInt(theYear) < 1900 )
	{
		alertError("Please enter a date later than 01/01/1900.");
		theDateField.focus();
		return theDate;		
	}

	var aValue = [theMonth, theDay, theYear];
	
	
	aValue = new Date(aValue.join("/"))

	if ((parseInt(theMonth,10) != aValue.getMonth()+1) || parseInt(theDay,10) != aValue.getDate() || parseInt(theYear) != aValue.getFullYear()) 
	{
		alertError(theDate + " is not a valid Date: ");
		theDateField.focus();
		return theDate;		
	}
	
	//alert(aValue);
	
	aValue = (aValue.getMonth()+1) + "/" + aValue.getDate() + "/" + aValue.getFullYear();

	if (theHour != null && theHour != undefined && theMintue != null && theMintue != undefined && theSecond != null && theSecond != undefined)
	{
		aValue += " " + theHour + ":" + theMintue + ":" + theSecond;
	}
	if(!isAboveDateMin(aValue))
	{
		alertError("Please enter a date later than 01/01/1900.");
		theDateField.focus();
		return aValue;		
	} 	
	return aValue ;
}

