/*
* this script is used to validate javascript forms
* the var defaultLocation is not only to translate messages. but to translate date formats too.
* use "datatype" to set the type of the data. Datatypes allowed are:
* email|integer|url|date|time|float|string. check if the method you need is already implemented, because not all is done yet
* use "required" to display a popup window with the message or
* use "errorobj" to turn a obj described on errorobj who should be displayed visible
* use "condition" giving a group of conditions separated by | containing one operator and one rightSide statement Eg:
* condition="eq #password|ne 1234" mean that this field should be equals to #password field (field with id="password") and must not be "1234"
* for the condition below, must especify that the datatype is integer|float
* condition="lte x" must be less than or equal to x
* allowed operators: eq|ne
*
* futurely we'll be able to use ajaxcheck="checknickname.php"
* and ajaxmessage="This email is already in use"
*/
var defaultLocation = "USA";	// "USA|BR";
var dtCh= "/";
var minYear=1900;
var maxYear=2100;

var ajaxValidation;
var ajaxResponse = false;
//var publicObjectIdValidation;

function formatInteger(input){
	var re = /[^0-9]/g
	input = input.replace(re,"");
	return(input);
}

function formatFloat(input){
	if (defaultLocation.toUpperCase() == 'USA'){
		var re1 = /[,]/g
		//var re2 = /[^0-9\.]/g
		var re2 = /[\.]/g 
		var replaceTo = ".";
	} else if (defaultLocation.toUpperCase() == 'BR'){
		var re1 = /[\.]/g
		//var re2 = /[^0-9,]/g
		var re2 = /[,]/g 
		var replaceTo = ",";
	}

	//input = input.replace(re2,"");
	input = input.replace(re1,replaceTo);
	input = input.replace(/[^\d\.,]+/g,'');

	return(input);
}

function strToDate(str,separator){

	var date = str.split("/");
	if (!separator) separator = '';

	if (defaultLocation.toUpperCase() == 'USA'){
		var year = date[2];
		var month = date[0];
		var day = date[1];
	} else if (defaultLocation.toUpperCase() == 'BR'){
		var year = date[2];
		var month = date[1];
		var day = date[0];
	}

	if (month.length < 2) month = "0"+month;
	if (day.length < 2) day = "0"+day;
	
	return year+separator+month+separator+day;
	
	alert("Default location not identified");
	return false;
}

function generateFormError(message,errorObj,node){
	
	/*if (defaultLocation.toUpperCase() == 'USA'){
		if (message == '') message = 'Requited Field';
	} else if (defaultLocation.toUpperCase() == 'BR'){
		if (message == '') message = 'Campo Obrigatorio';
	}
	*/

	if (errorObj){
		document.getElementById(errorObj).style.visibility="visible";
	} else if (message) {
		alert(message);	
	} else {
		if (defaultLocation.toUpperCase() == 'USA'){
			alert("Required Field");	
		} else if (defaultLocation.toUpperCase() == 'BR'){
			alert("Campo Obrigatorio");
		}
	}

	node.focus();
	return false;
}


function isInteger(s){
	var i;
	for (i = 0; i < s.length; i++){
		// Check that current character is number.
		var c = s.charAt(i);
		if (((c < "0") || (c > "9"))) return false;
	}
	// All characters are numbers.
	return true;
}

function stripCharsInBag(s, bag){
	var i;
	var returnString = "";
	// Search through string's characters one by one.
	// If character is not in bag, append to returnString.
	for (i = 0; i < s.length; i++){
		var c = s.charAt(i);
		if (bag.indexOf(c) == -1) returnString += c;
	}
	return returnString;
}

function daysInFebruary (year){
	// February has 29 days in any year evenly divisible by four,
	// EXCEPT for centurial years which are not also divisible by 400.
	return (((year % 4 == 0) && ( (!(year % 100 == 0)) || (year % 400 == 0))) ? 29 : 28 );
}

function DaysArray(n) {
	for (var i = 1; i <= n; i++) {
		this[i] = 31
		if (i==4 || i==6 || i==9 || i==11) {this[i] = 30}
		if (i==2) {this[i] = 29}
   }
   return this
}

function isDateEn(dtStr){
	var daysInMonth = DaysArray(12)
	var pos1=dtStr.indexOf(dtCh)
	var pos2=dtStr.indexOf(dtCh,pos1+1)
	var strMonth=dtStr.substring(0,pos1)
	var strDay=dtStr.substring(pos1+1,pos2)
	var strYear=dtStr.substring(pos2+1)
	strYr=strYear
	if (strDay.charAt(0)=="0" && strDay.length>1) strDay=strDay.substring(1)
	if (strMonth.charAt(0)=="0" && strMonth.length>1) strMonth=strMonth.substring(1)
	for (var i = 1; i <= 3; i++) {
		if (strYr.charAt(0)=="0" && strYr.length>1) strYr=strYr.substring(1)
	}
	month=parseInt(strMonth)
	day=parseInt(strDay)
	year=parseInt(strYr)
	if (pos1==-1 || pos2==-1){
		//alert("The date format should be : mm/dd/yyyy")
		return false
	}
	if (strMonth.length<1 || month<1 || month>12){
		//alert("Please enter a valid month")
		return false
	}
	if (strDay.length<1 || day<1 || day>31 || (month==2 && day>daysInFebruary(year)) || day > daysInMonth[month]){
		//alert("Please enter a valid day")
		return false
	}
	if (strYear.length != 4 || year==0 || year<minYear || year>maxYear){
		//alert("Please enter a valid 4 digit year between "+minYear+" and "+maxYear)
		return false
	}
	if (dtStr.indexOf(dtCh,pos2+1)!=-1 || isInteger(stripCharsInBag(dtStr, dtCh))==false){
		//alert("Please enter a valid date")
		return false
	}
	return true
}

function isDate(data) {
	if (defaultLocation.toUpperCase() == 'USA'){
		return isDateEn(data);
	} else if (defaultLocation.toUpperCase() == 'BR'){
		return data.match(/^((0?[1-9]|[12]\d)\/(0?[1-9]|1[0-2])|30\/(0?[13-9]|1[0-2])|31\/(0?[13578]|1[02]))\/(19|20)\d{2}$/);
	} else {
		alert("Location not defined");
		return false;
	}
}

function emailIsValid(entrada){
	return(/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{1,3})+$/.test(entrada));
}

function validaURL(obj){
	var url = obj.value;
	//var RegExp = /^(([\w]+:)?\/\/)?(([\d\w]|%[a-fA-f\d]{2,2})+(:([\d\w]|%[a-fA-f\d]{2,2})+)?@)?([\d\w][-\d\w]{0,253}[\d\w]\.)+[\w]{2,4}(:[\d]+)?(\/([-+_~.\d\w]|%[a-fA-f\d]{2,2})*)*(\?(&?([-+_~.\d\w]|%[a-fA-f\d]{2,2})=?)*)?(#([-+_~.\d\w]|%[a-fA-f\d]{2,2})*)?$/;
	var RegExp = /^(http:\/\/)(([\d\w]|%[a-fA-f\d]{2,2})+(:([\d\w]|%[a-fA-f\d]{2,2})+)?@)?([\d\w][-\d\w]{0,253}[\d\w]\.)+[\w]{2,4}(:[\d]+)?(\/([-+_~.\d\w]|%[a-fA-f\d]{2,2})*)*(\?(&?([-+_~.\d\w]|%[a-fA-f\d]{2,2})=?)*)?(#([-+_~.\d\w]|%[a-fA-f\d]{2,2})*)?$/;
	return RegExp.test(url);

	//var RegExp = /^http:\/\/(([\w]+:)?\/\/)?(([\d\w]|%[a-fA-f\d]{2,2})+(:([\d\w]|%[a-fA-f\d]{2,2})+)?@)?([\d\w][-\d\w]{0,253}[\d\w]\.)+[\w]{2,4}(:[\d]+)?(\/([-+_~.\d\w]|%[a-fA-f\d]{2,2})*)*(\?(&?([-+_~.\d\w]|%[a-fA-f\d]{2,2})=?)*)?(#([-+_~.\d\w]|%[a-fA-f\d]{2,2})*)?$/;
	//return RegExp.test(url);
}

// work on a function to consider mandatory conditional field
// work on a function to consider a xor mandatory field, where it's mandatory just one of both. not either and not neither (like exclusive or (xor) 

function pause(millis){
	
	if (millis){
		setTimeout("pause(false)",millis);
	}
	/*
	var date = new Date();
	var curDate = null;
	do { curDate = new Date(); }
	while(curDate-date < millis);
	*/
}


function ajaxCheckValidation(ajaxPage,data){
	
	if (window.ActiveXObject){
		ajaxValidation = new ActiveXObject("Microsoft.XMLHTTP");
	} else if (window.XMLHttpRequest){
		ajaxValidation = new XMLHttpRequest();
	}
	
	ajaxValidation.onreadystatechange = handleAjaxStateValidation;
	if (ajaxPage.indexOf("?") !== -1){
		ajaxPage += "&data="+data;
	} else {
		ajaxPage += "?data="+data;
	}
	
	//alert(ajaxPage);
	ajaxValidation.open("GET",ajaxPage,true);
	ajaxValidation.send(null);
	
	// wait response
	while (!ajaxResponse) {
		pause(1000);
		//alert(ajaxResponse);
		document.getElementById('feedback').innerHTML = document.getElementById('feedback').innerHTML + "|";
	}
	
	switch(ajaxResponse.toUpperCase()){
		case "OK": case "TRUE": case "1": case "YES":
			return true;
		case "ERROR": case "FALSE": case "0": case "NO":
			return false;
	}
	
	return false;
}

function handleAjaxStateValidation(){
	switch (ajaxValidation.readyState){
		case 1: // loading
		case 2: // loaded
		case 3: // interactive
		case 4: // done
			//alert("done");
			if (ajaxValidation.status == 200){
				ajaxResponse = ajaxValidation.responseText;
			} else {
				ajaxResponse = "error:"+ajaxValidation.status;
			}
		break;
	}
}


function formIsValid(form){
	var dataTypes = Array("integer","string","email","date","time","float","phone");
	var datatype;
	var elem;
	// require
	// datatype

	for (var cont = 0; cont < form.elements.length; cont++){
		elem = form.elements[cont];

		//datatype = form.fields[cont].datatype;
		datatype = elem.getAttribute('datatype');
		//message = form.fields[cont].required;
		message = elem.getAttribute('required');
		errorObj = elem.getAttribute('errorobj');
		condition = elem.getAttribute('condition');
		ajaxcheck = elem.getAttribute('ajaxcheck');
		ajaxmessage = elem.getAttribute('ajaxmessage');
		ereg = elem.getAttribute('ereg');
		//alert(cont+" "+form.elements[cont].name+" "+message);

		if ((message == '' || !message) && (errorObj == '' || !errorObj)) continue;
		
		if (errorObj) {
			document.getElementById(errorObj).style.visibility="hidden";
		}
		
		// regular expressions validation
		if (ereg) if (!elem.value.match(ereg))	return generateFormError(message,errorObj,elem);
		
		//alert(message);
		// special conditions
		if (condition) {
			var conditions = condition.split("|");
			for (cont2 = 0; cont2 < conditions.length; cont2++){
				var currentCondition = conditions[cont2];
				currentCondition = currentCondition.split(" ");
				var operator = currentCondition[0];
				var rightSide = currentCondition[1];
				
				if (rightSide.charAt(0) == "#") {
					rightSide = rightSide.substr(1);
					rightSide = document.getElementById(rightSide).value;
				}

				switch(operator){
					// eq = equal | ne = not equal
					case "eq":
						if (elem.value !== rightSide) {
							return generateFormError(message,errorObj,elem);
						}
					break;
					case "ne":
						if (elem.value == rightSide) {
							return generateFormError(message,errorObj,elem);
						}
					break;
					case "lte" :
						if ( datatype == 'integer' || datatype == 'float' ) {
							elem.value = elem.value*1;
							rightSide = rightSide*1;
						}
						if ( elem.value > rightSide ) {
							return generateFormError(message,errorObj,elem);
						} 
					break;
				}
			}
		} 

		// specific data types
		switch(datatype){
			case 'url':	if (!validaURL(elem)) return generateFormError(message,errorObj,elem);	break;
			case 'integer': elem.value = formatInteger(elem.value); if (elem.value == '') return generateFormError(message,errorObj,elem); break;
			case 'email':	if (!emailIsValid(elem.value)) return generateFormError(message,errorObj,elem); break;
			case 'date':	if (!isDate(elem.value)) return generateFormError(message,errorObj,elem); break;
			case 'time':
			case 'float':	elem.value = formatFloat(elem.value); if (elem.value == '') return generateFormError(message,errorObj,elem); break;
			case 'phone':
			case 'string':	default: if (elem.value == '') return generateFormError(message,errorObj,elem);
		}
		
		// dinamic data type
		/*
		if (ajaxcheck) {
			if (!ajaxCheckValidation(ajaxcheck,elem.value)) 
			
			if (ajaxmessage) message = ajaxmessage;
			return generateFormError(message,errorObj,elem);
		}
		*/

	}
	
	return true;
}

function blockEnter(evt) {
	evt = (evt) ? evt : event;
	var charCode = (evt.charCode) ? evt.charCode :
		  ((evt.which) ? evt.which : evt.keyCode);
	if (charCode == 13) {
		return false;
	} else {
		return true;
	}
}
