	var defaultLocation = "USA";	// "USA|BR";
	var dtCh= "/";
	var minYear=1900;
	var maxYear=2100;

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

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

		entrada = entrada.replace(re1,replaceTo);
		entrada = entrada.replace(re2,"");

		return(entrada);
	}


	function generateFormError(message,node){
		if (defaultLocation.toUpperCase() == 'USA'){
			if (message == '') message = 'Requited Field';
		} else if (defaultLocation.toUpperCase() == 'BR'){
			if (message == '') message = 'Campo Obrigatório';
		}

		alert(message);
		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 atLeastOne(){
	    elements = document.getElementsByTagName('input');

        for(var i=0 ; elm=elements.item(i++); ) {
			if (elm.type == "checkbox"){
				if (elm.checked==true){
					return true;
				}
			}
		}

		return false;
	}

	function validaInteger(elem){
		var valmin = parseInt(elem.getAttribute('valmin'));	// try to get the valmin and valmax
		var valmax = parseInt(elem.getAttribute('valmax'));

		elem.value = formatInteger(elem.value); // remove undesired chars
		var intValue = parseInt(elem.value);

		if (valmin && valmax){
			if (intValue < valmin || intValue > valmax) return false;
		} else if (valmin) {
			if (intValue < valmin) return false;
		} else if (valmax){
			if (intValue > valmax) return false;
		} else {
			if (elem.value == '') return false;
		}

		return true;
	}

	function validaFloat(elem){
		var valmin = parseFloat(elem.getAttribute('valmin'));	// try to get the valmin and valmax
		var valmax = parseFloat(elem.getAttribute('valmax'));

		elem.value = formatFloat(elem.value); // remove undesired chars
		var intValue = parseFloat(elem.value);

		if (valmin && valmax){
			if (intValue < valmin || intValue > valmax) return false;
		} else if (valmin) {
			if (intValue < valmin) return false;
		} else if (valmax){
			if (intValue > valmax) return false;
		} else {
			if (elem.value == '') return false;
		}

		return true;
	}

	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})*)?$/;
		if(RegExp.test(url)){
			return true;
		}else{
			return false;
		}


//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);
	}

	// E NO CASO DE CAMPO OBRIGATORIO CONDICIONAL?
	// E NO CASO DE SER OBRIGATÓRIO OU UM OU OUTRO? NÃO OS DOIS AAO MESMO TEMPO
	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');

			if (message == '' || !message) continue; // if have no message, skip this node and go to the next

			// check if it is a required checkbox and
			//if (elem.type=='ckeckbox'){ // parei aqui atLeastOne(elem) }

			switch(datatype){
				case 'url':		if (!validaURL(elem)) return generateFormError(message,elem);				break;
				case 'integer':	if (!validaInteger(elem)) return generateFormError(message,elem); 			break;
				case 'email':	if (!emailIsValid(elem.value)) return generateFormError(message,elem); 		break;
				case 'date':	if (!isDate(elem.value)) return generateFormError(message,elem); 			break;
				case 'time':	alert('time validation not implemented yet. please, use integer datatype setting valmax and valmin attributes'); break;
				case 'float':	if (!validaFloate(elem)) return generateFormError(message,elem); 			break;
				case 'phone':	alert('phone validation not implemented yet.'); 							break;
				case 'string':
				default:
					if (!datatype){
						if (elem.value == '') return generateFormError(message,elem);
					} else { // try regexp
						//alert (datatype);
						if (!elem.value.match(datatype)) return generateFormError(message,elem); break;
					}
			}
		}

		//alert("form ok"); return false;
		return true;
	}


	/*
	HOW TO USE

	to make a required field, set the attribute 'require' and the message as the value
	eg.: <input type="text" name="name" require="please enter your name" >

	to specify a specific data type, use the attribute 'datatype' the values would be [integer|email|date|time|float|phone|string|REGEXP]
	eg.: <input type="text" name="email" require="please enter your e-mail address" datatype="email">

	in case of integer type, you can set the 'valmin' and 'valmax' attribute or not

	to require at lest one checkbox checked or textfield filled, use 'onerequired'


	SOON
	- conditional validation
	- require at least one
	- regexp


	*/
