/*
*******************************************
*      	   Validate Class v2.6            *
*   by rodrigolr - rodrigolr@uol.com.br   *
*******************************************
*/
var Validate = function(col){
	this.colorize = col;
	this.isRegistered = false;
	this.restrictChars = false;
	this.min = {}; this.max = {};
}
Validate.prototype.form = null;
Validate.prototype.field = {};
Validate.prototype.prefix = null;
Validate.prototype.sortFields = false;
Validate.prototype.doRestriction = function(chr, keyCode){
	var o = this;
	if(o.restrictChars !== false){
		var chars;
		if(!o.isRegistered){
			var onlyNumber = "0123456789";
			var onlyChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
			var onlyLowerCase = "abcdefghijklmnopqrstuvwxyz";
			var onlyUpperCase = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
			var onlySymbols = "\\'\\\"!@#$%¨&*()-_=+´`[{~^]}\\|,<.>;:/? ";
			var onlyAccents = "àáãäâèéëêìíïîòóõöôùúûüçñÀÁÃÄÂÈÉËÊÌÍÏÎÒÓÕÖÔÙÚÛÜÇÑ";
			var _type = function(_char){
				if(_char === 1) return onlyNumber;
				else if(_char === 2) return onlyChars;
				else if(_char === 3) return onlyLowerCase;
				else if(_char === 4) return onlyUpperCase;
				else if(_char === 5) return onlySymbols;
				else if(_char === 6) return onlyAccents;
			}
			var _i = 0;
 			for(var i in o.field){
				var user_pattern = function(){
					var found = null;
					if((/\x7C.+\x7C/).test(chr[_i])) found = String(chr[_i].match((/\x7C(\d\x2C?\d?)+\x7C/g))).replace(/\x7C/g, "").split(",");
					var padrao = "";
					if(found !== null){
						for(var f in found)
							padrao += _type(found[f] = (!isNaN(found[f])) ? parseInt(found[f]) : found[f]);
						chr[_i] = chr[_i].replace(/\x7C{1}(\d{1}\x2C?\d?)\x7C{1}/g, "");
						return(chr[_i] + padrao);
					}else return(chr[_i]);
				}
				if(chr[_i] !== 0){
					chars = ((typeof(chr[_i])).toLowerCase() != "string") ? _type(chr[_i]) : user_pattern();
					var keypress_function = ((navigator.appName).toLowerCase().indexOf("netscape") > -1) ? 
					"(function(){return o.doRestriction(\"" + chars + "\", e.which)}).apply()" : 
					"(function(){return o.doRestriction(\"" + chars + "\")}).apply();";
					var obj_ref = document.forms[this.form][i];
					try{
						if((obj_ref.type === "text") || (obj_ref.type === "textarea")){
							var old_onkeypress = (obj_ref.getAttribute("onkeypress")) ? ("(" + obj_ref.getAttribute("onkeypress") + ").apply()") : null;
							var __onkeypress__ = "function(e){" + old_onkeypress + "; return " + keypress_function + "}"
							eval("document.forms[" + this.form + "]." + i + ".onkeypress = " + __onkeypress__);
						}
					}catch(e){}
				}
				_i++;
			}
			this.isRegistered = true;
		}else{
			try{
				var inRange = function(){
					if(chr.indexOf("^") == 0)
						if(chr.indexOf(String.fromCharCode(charCode)) == -1) return true;
						else return false;
					else
						if(chr.indexOf(String.fromCharCode(charCode)) != -1) return true;
						else return false;
				}
				var charCode = ((navigator.appName).toLowerCase().indexOf("netscape") > -1) ? keyCode : window.event.keyCode;
				return ((charCode < 30) || (!chr) || (inRange())) ? true : false;
			}catch(e){};
		}
	}
}

Validate.prototype.restrict = function(){
	var o = this, args = arguments;
	o.restrictChars = true;
	var __onload__ = (window.onload) ? window.onload : function(){};
	window.onload = function(){
		o.doRestriction(args); __onload__();
		if(o.colors){
			var __onsubmit__ = (document.forms[o.form].onsubmit) ? document.forms[o.form].onsubmit : function(){}
			document.forms[o.form].onsubmit = function(){__onsubmit__(); return o.start(o.colors[0], o.colors[1])};
		}
	}
}

Validate.prototype.start = function(right_color, wrong_color){
	var o = this;
	right_color = right_color || o.colors[0];
	wrong_color = wrong_color || o.colors[1];
	var all_ok = [];
	o._wrong = [];
	o._right = [];
	var wrg = 0; rgt = 0;
	var txtval, val, pt, len, ok, tipo;
	var rightFields;
	var paint = function(ok){
		if(o.colorize){
			if(document.getElementById(txtval)){
				if(ok) document.getElementById(txtval).style.color = right_color;
				else document.getElementById(txtval).style.color = wrong_color;
			}
		}
	}
	var wrong = function(fields){
		all_ok[j] = false;
		o._wrong[wrg] = j;
		paint(false); ++wrg;
		if(o.onFieldError) o.onFieldError(j, fields);
	}
	var right = function(){
		all_ok[j] = true;
		o._right[rgt] = j;
		paint(true); ++rgt;
		if(o.onFieldComplete) o.onFieldComplete(j);
	}
	for(var j in o.field){
		val = document.forms[o.form][j];
		tipo = val.type;
		txtval = o.prefix + j;
		pt = (o.field[j] instanceof RegExp) ? o.field[j] : {test : o.field[j]};
		len = val.length;
		rightFields = 0;
		if(len > 0){
			var field_min_limit = o.min[j] ? o.min[j] : 1;
			var field_max_limit = o.max[j] ? o.max[j] : undefined;				
			if(field_min_limit == undefined) field_min_limit = 1;
			if((tipo == "select-one") || (tipo == "select-multiple")){
				var selection_len = val.options.length;
				if(field_max_limit == undefined) field_max_limit = selection_len;
				while(selection_len--){
					if(val.options[selection_len].selected)
						if(pt.test(val.options[selection_len].value, j)) ++rightFields;
					if(rightFields > field_max_limit) break;
				}
				if((field_min_limit <= rightFields) && (field_max_limit >= rightFields)) right();
				else wrong(rightFields);
			}else{
				if(field_max_limit == undefined) field_max_limit = len;
				while(len--){
					tipo = val[len].type;
					if(tipo == "radio" || tipo == "checkbox"){
						if(val[len].checked)
							if(pt.test(val[len].value, j)) ++rightFields;
					}else 
						if(pt.test(val[len].value, j)) ++rightFields;
					if(rightFields > field_max_limit) break;
				}
				if((field_min_limit <= rightFields) && (field_max_limit >= rightFields)) right();
				else wrong(rightFields);
			}
		}else{
			if((tipo == "radio" || tipo == "checkbox") ? val.checked : true)
				if(pt.test(val.value, j)) right();
				else wrong();
			else wrong();
		}
	}
	var send = true;
	for(var i in all_ok)
		if(!(send = all_ok[i])) break;
	if(send){ if(o.onFormComplete) o.onFormComplete();}
	else{if(o.onFormError) o.onFormError();}
	if(o.sortFields){
		o._wrong.sort(function(a, b){return (a > b) ? 1 : -1});
		o._right.sort(function(a, b){return (a > b) ? 1 : -1});
	}
	return send;
}