/*
	Usage Examples:
	
	// required field validates as a date (mm/dd/yyyy)
	<input value="" maxlength="10" size="10" 
		required="true" validate="date" 
		id="txt_end_date" name="txt_end_date" />
	*Note: It is optional to have a message attribute like message="End date should be of the form mm/dd/yyyy"
	       validate attribute can also contain reg ex. e.g. validate="^\d{13}$"
	// field validates as a date, required when the value of the field is non-empty
	<input value="" maxlength="10" size="10" 
		validate="date" id="txt_end_date" name="txt_end_date" />
	
	
	UPDATES:
	Date		Dev			Descrip
	8/15/2006	Jin Park	Changed background color to orange instead of red for 
							usability/visibility.
							Remove background color once validation is complete.
							Added error message to page where userMessage element is.
							When userMessage is not found, alert message is displayed.
	8/30/2006	Jin Park	Updated setBackground color to skip button, reset, and submit
							Added return statement to validate function
							Added support for radio buttons to show only one message per group
	9/28/2006   KAlagu		Corrected validation for types int and integer and added new validation function
							for validation types number, numeric and float.
	4/5/2007	Jin Park	Added setMessage() function to handle setting page message
	9/18/2007	Jin Park	Added try catch within entire function body of requiredFormElem for tabbed content
							Also added try/catch on formElement.focus() b/c IE barfs when focusing on hidden elements
							Cleaned up whitespace before curly braces
							Modified showMessage function to put the message in the userMessage div, if found
*/
var focusSet = false;
var err = '';
var invalid = '';
var REQUIRED_COLOR = 'orange';
var INVALID_COLOR = 'yellow';

function validate(elem) {
	if(elem.tagName.toLowerCase() == 'form') {
		return checkForm(elem);
		} else {
		return checkElement(elem);
	}
}
// adding basicMsgOnly displays basic message only when selected
function checkForm(theForm) {
	var theReturn = true;
	for(var i = 0; i < theForm.elements.length; i++) {
		if(!checkElement(theForm.elements[i])) {theReturn = false;};
	}
	
	if(!theReturn) {
		//var strMsg = 'Fields in orange are required.\nFields in yellow are not valid values.';
		var strMsg = '';
		if(err != '') {
			strMsg = strMsg + 'The following fields in ' + REQUIRED_COLOR + ' are required - ' + err;
		}
		if(invalid != '') {
			strMsg = strMsg + 'The following fields in ' + INVALID_COLOR + ' are invalid - ' + invalid;
			
		}
		//alert('Fields in Orange are required.\nFields in Yellow are not valid values.');	// 8/15/2006 - jp - changed color to orange
		setMessage(strMsg,'error');
	}
	// reset the error message...
	err = '';
	invalid = '';
	strMsg = '';
	
	return theReturn;
}

// sets the page message to the str value passed in 
/*
	String str - message to be displayed in pagemessage
	String type - mesesage type, expects: success, info, or error
	
	Example: setMessage('Set the page message here','info');
*/
function setMessage(str,type) {
	var um = document.getElementById('userMessage');
	if(um) {
		str = str.replace(/:/gi,'\n');
		um.className = type;
		um.innerHTML = str;
		if (document.all) {
		} else {
			um.style.height = 'auto';
		}
	} else {
		str = str.replace(/<\/li>/gi,'\n');
		str = str.replace(/<li[^>]*>/gi,'');
		str = str.replace(/<\/?div[^>]*>/gi,'');
		str = str.replace(/:/gi,'');
		str = str.replace(/ - /gi,' - \n');	// at end of message
		alert(str);
	}
}

function checkElement(formElem) {
	var validationReturn = true, requiredReturn = true;
 	setBackGround(formElem,'');
	if(formElem.getAttribute("validate") != null || formElem.getAttribute("validation") != null) {
		validationReturn = validateFormElem(formElem);
	} 
	
	if(formElem.getAttribute("required") != null) {
		requiredReturn = requiredFormElem(formElem);
	}
	if(!validationReturn || !requiredReturn) {
		return false;
		} else {
		return true;
	}
}

function validateFormElem(formElem) {
 	//setBackGround(formElem,'');
	if(formElem.getAttribute("validate") != null) {
		var validation = formElem.getAttribute("validate").replace(/this/ig,"formElem");
	}
 	if(formElem.getAttribute("validation") != null) {
		var validation = formElem.getAttribute("validation").replace(/this/ig,"formElem");
	}
 	var theReturn = true;
 	var result = true;
 	//log.trace('1. Validation currently = '+ validation);
 	if(formElem.value != '') {
		//setBackGround(formElem,'');
			//we try to evaluate the validation
			//
			try{validation = eval(validation)} catch(e) {}
			switch(typeof(validation)) {
				case 'function':
					//log.trace('function')
					result = validation.apply(formElem,[formElem]);
					break;
				case 'boolean':
					//log.trace('boolean')
					result = validation
					break;
				case 'string':
				default:
					switch (validation.toLowerCase()) {
						case "date":
							result = isDate(formElem.value);
							break;
						case "time":
							result = isTime(formElem.value);
							break;
						case "int":
						case "integer":
							result = isInteger(formElem.value);
							break;
						case "numeric":
						case "number":
						case "float":
							result = isFloat(formElem.value);
							break;
						case "numberrange":
						case "range":
							var minValue = formElem.getAttribute("min");
							var maxValue = formElem.getAttribute("max");
							result = checkRange(formElem.value,minValue,maxValue);
							break;
						case "ofage":
						case "of_age":
						case "of age":
							result = isDate(formElem.value);
							if(result) {
								var age = formElem.getAttribute("age");
								var opr = formElem.getAttribute("opr");
								result = validateDateYear(formElem.value,age,opr);
							}
							break;			
						default:
							result = RegExp(validation).test(formElem.value);
							break;
					}
					break;
			}
		if(!result) {
			theReturn = false;
			setBackGround(formElem,INVALID_COLOR);
			showMessage(formElem,'validation');
			if(!focusSet) {
				try {
					formElem.focus();
				} catch(e) {}
				focusSet = true;
			}
		} else {
			setBackGround(formElem,'');				// 8/15/2006 - jp - reset color to white if it's filled in
		}
	}
	return theReturn;
}
function requiredFormElem(formElem) {
	try {
		//setBackGround(formElem,'');
		var req = formElem.getAttribute("required").replace(/this/ig,"formElem");
		try {
			req = eval(req);
			if (req == undefined) {
				req = formElem.getAttribute("required").replace(/this/ig,"formElem");
				throw "req undefined";
			}
		} catch(e) {
			try {
				req = eval(req+"{true}else{false}")
				if (req == undefined) {
					req = formElem.getAttribute("required").replace(/this/ig,"formElem");
				}
			} catch(e) {/*log.trace('Required eval failed');*/}
		}
		switch(typeof(req)) {
			case 'function':
				req = req.apply(formElem,[formElem]);
				break;
			case 'boolean':
				req = req
				break;
		}
		if(req) {
			if(!hasValue(formElem)) {
				setBackGround(formElem,REQUIRED_COLOR);		// 8/15/2006 - jp - changed color from red to orange
				showMessage(formElem,'required');
				if(!focusSet) {
					try {
						formElem.focus();
					} catch(e) {}
					focusSet = true;
				}	
				return false;					
			} else {
				return true;
			}
		} else {
			return true;
		}
	} catch(e) {
		return true;
	}
}
function hasValue(input) {
	var reg = /[a-zA-Z0-9]+/;
	switch(input.type) {
		//special cases
		case 'radio':
			for(var i = 0; i < input.form[input.name].length ; i++) {
				if(input.form[input.name][i].checked == true)
					return true;
			}
			return false;
		default:
			return reg.test(input.value);
	}
}

function setBackGround(input,color) {
	//log.trace(input.name + ' changed to' + color);
	switch(input.type) {
		//special cases
		case 'radio':
			input.parentNode.style.background = color;
		// 08/30/2006 - jp - leave buttons alone in IE which changes colors to white...
		case 'button':
		case 'submit':
		case 'reset':
			break;
		
		default:
			input.style.background = color;
	}
	if(color != '') {
		addToErrorMsg(input,color);
	}
}

function addToErrorMsg(input,color) {			
	// find the text within the label of the associated input...
	var lbls = document.getElementsByTagName('label');
	var thisLbl = input.name;
	for(var j=0;j<lbls.length;j++) {
		if(lbls[j].getAttribute('for') == input.name
			|| lbls[j].getAttribute('htmlFor') == input.name) {	// IE uses htmlFor whereas FF uses for
			// found it
			thisLbl = lbls[j].innerHTML;
			break;
		}
	}
	if(color == REQUIRED_COLOR) {
		// if the label isn't in there, add to the message (adds radio button message only once)
		var strCheck = '<li>' + thisLbl + '</li>';
		if(err.indexOf(strCheck) < 0) {
			err =  err + '<li>' + thisLbl + '</li>';
		}
	}
	if(color == INVALID_COLOR) {
		// if the label isn't in there, add to the message (adds radio button message only once)
		var strCheck = '<li>' + thisLbl + '</li>';
		if(invalid.indexOf(strCheck) < 0) {
			invalid = invalid + '<li>' + thisLbl + '</li>';
		}
	}
}

function showMessage(inputElm,msgType) {
	var message = inputElm.getAttribute('message');
	if(message) {
	try {
			eval("message = {" + message + "}");
			if(typeof(message[msgType]) != 'undefined') {
				message = message[msgType];
			} else {
				message = null;
			}
		} catch(e) {}
		if(message) {
			if(document.getElementById('userMessage')) {
				err =  err + '<ul><li>' + message + '</li></ul>';	// 9/26/2007 jp - adding to error message instead of pop-up
			}
			} else {
			alert(message);
		}
	}
}
function formatDateInput(input,e) {
	//log.trace('hit this spot');
	var whichCode = (window.Event) ? e.which : e.keyCode;
	var dateValue =input.value;
	var dateLen = dateValue.length;
	var dateArray = dateValue.split("/");
	if(dateValue.right(2) == "//") {	
		input.value = input.value.left(dateLen-1);
		return true;
	}
	if(dateValue.right(1) == "/")
		return true;	
	if(dateArray.length == 3) {
		dateValue = dateArray[0].left(2);
		if(dateArray[0].length > 2) {
			dateArray[1] = dateArray[0].substring(2).toString() + dateArray[1].toString();
		}
		dateValue += "/"+ dateArray[1].left(2);
		if(dateArray[1].length > 2) {
			dateArray[2] = dateArray[1].substring(2).toString() + dateArray[2].toString();
		}
		dateValue += "/" + dateArray[2].left(4);
		input.value = dateValue;
		return true;
	}
	if(whichCode != 8) {
		if(dateLen == 2 || dateLen == 5)
			input.value += "/";
		if(dateLen == 3 && dateValue.right(1) != '/')
			input.value = dateValue.substring(0,2) + "/" + dateValue.right(1);
		if(dateLen == 6 && dateValue.right(1) != '/')
			input.value = dateValue.substring(0,5) + "/" + dateValue.right(1);
	}
}



/*----------------------- Expanded 'Built-in' Validation -------------------------*/

function isDate(checkDate) {
	var parsedDate = new Date(checkDate);
	var month = (parsedDate.getMonth() + 1).toString();
	//month = month.toString();
	var date = parsedDate.getDate().toString(); //date is the day of the month
	var year = parsedDate.getFullYear().toString();
	if(year < 1753) {
		return false;
	}
	parsedDate = month + '/' + date + '/' + year;
	// 5/27/2008 allow dates of m/d/yyyy
	// check for m/d/yyyy format
	if(parsedDate == checkDate)
		return true;
	
	if(month.length == 1)
		month = '0' + month;
	if(date.length == 1)
		date = '0' + date.toString();
	parsedDate = month + '/' + date + '/' + year;
	// check for mm/dd/yyyy format
	if(parsedDate == checkDate)
		return true;
	else
		return false;
}

function isTime(checkTime) {
	/* does this even look like a time?   not the most stringent of checks, but at least all the right characters ... */
	var re = /^[0-9apm :]{2,}$/i;
	if (!re.test(checkTime)) {
		return false;
	}
	/* and at least h:mm */
	re = /\d:\d{2}/;
	if (!re.test(checkTime)) {
		return false;
	}

    var t = Date.parse('1/1/1970 ' + checkTime );
    if ( isNaN( t ) ) {
        return false;
    }
	else
	{
		return true;
	}
}
function isInteger(formValue) {
	return RegExp('^[+|-]?\\d+$').test(formValue);
}
function isFloat(formValue) {
	return !isNaN(formValue);
}
function checkRange(formValue,min,max) {
	if(isInteger(formValue)) {
		if(formValue > min & formValue < max)
			return true;	
	}
	return false;
}
function validateDateYear(obj,year,opr) {
  var objField=obj;
  var objDateArr=objField.split('/');
  var objMonth=objDateArr[0]-1;
  var objDay=objDateArr[1];
  var objYear=objDateArr[2];
  var dateObj=new Date(objYear,objMonth,objDay);
  var todaysDate=new Date();
  var todaysYear=todaysDate.getYear();
  var adjYear=todaysYear-year;
  todaysDate.setYear(adjYear);
  var dateObjMilli=Date.parse(dateObj);
  var adjDateMilli=Date.parse(todaysDate);
  var operator=opr.toUpperCase()
  switch(operator) {
   case "GT":
    if (dateObjMilli > adjDateMilli) {
     return true;
    }
    return false;
    
   case "GTE":
    if (dateObjMilli >= adjDateMilli) {
      return true;
    }
    return false;
    
   case "LT":
    if (dateObjMilli < adjDateMilli) {
     return true;
    }
    return false;
    
   case "LTE":
    if (dateObjMilli <= adjDateMilli) {
      return true;
    }
    return false;
   
   case "EQ":
    if (dateObjMilli == adjDateMilli) {
      return true;
    }
    return false;
   
   case "NEQ":
    if (dateObjMilli != adjDateMilli) {
     return true;
    }
    return false;
   
   default:
   return false;
  } 
      
 }

/*-----------------------STRING FUNCTIONS COPIED FRO STRING.JS -------------------*/
function strRight(l,c) {
	var s = this;
	if ( c ) {
        c = c.substr(0,1);
        var i = new Number;
        var pad = new String;
        for (i = 0; i < l; i++) {
            pad += c;
        }
        s = pad + s;
    }
    return(s.substr( s.length - l ));
}
String.prototype.right = strRight;

function strLeft(l,c) {
	var s = this;
	if ( c ) {
        c = c.substr(0,1);
        var i = new Number;
        var pad = new String;
        for (i = 0; i < l; i++) {
            pad += c;
        }
        s =  s + pad;
    }
    return(s.substr( 0, l ));
}
String.prototype.left = strLeft;

function strLTrim() {
	return this.replace(/^\s+/g, "");
}
String.prototype.ltrim = strLTrim;

function strRTrim() {
	return this.replace(/\s+$/g,"");
}
String.prototype.rtrim = strRTrim;

function strTrim() {
	return this.ltrim().rtrim();
}
String.prototype.trim = strTrim;
