var formValidationMessages = {
	hasErrors: '<big>Erro ao enviar o formulário</big><br /><p>Corrija os erros que ocorreram ao tentar enviar seu formulário e tente novamente.</p><p><strong>Atenção:</strong> Os erros estão marcados próximos aos campos que o originaram.</p>',
	remain: '<strong>[n]</strong> caracteres restantes.',
	email: 'O campo "[label]" deve ter um e-mail válido.',
	fill: 'O campo "[label]" deve ser [end].',
	filled: 'preenchido',
	selected: 'selecionado',
	max: 'O campo "[label]" deve ser preenchido com no máximo "[max]" caracteres.'

}
var formValidation = function(target) {
	this.errors = false;
	this.validations = [];
	this.otherValidations = [];
	this.target = $(target);
	this.formName = this.target.attributes["id"].value; /* getAttribute buga no ie qdo tem um campo com o nome do atributo */
	this.addedEvts = false;
	this.m = formValidationMessages;
	this.name = target;
	this.nameLength = target.toString().length;
}

formValidation.prototype.addError = function(target, message, type) {
	this.errors++;
	if($(this.makeErrorId(target, type))) return;

	var dId, objF, errorFeedback;

	this.setWrongStyle(target);

	dId = this.makeErrorId(target);
	objF = $(dId);

	if(target[0])
		var nt = $(this.name +'_'+ target[0].name +'0').parentNode.parentNode;
	else if( target.getAttribute.type=='radio' )
		var nt = target.parentNode.parentNode;
	else
		nt = target;

	errorFeedback = objF ? objF :
		cE('div',nt.parentNode, dId, null, nt.nextSibling );

	errorFeedback.className = 'formValidationError';

	var actual = cE('span', errorFeedback, this.makeErrorId(target, type));
	actual.className = 'formValidation' + type;
	actual.innerHTML = message;
};

formValidation.prototype.makeErrorId = function(target/*, comp*/) {
	var comp = arguments[1] ? arguments[1] : 'error' ;

	if( !target[0] ){
		if( target.getAttribute("type")=='radio' ) target = this.target[target.name];
	}
	var id = ( target[0] ) ? this.name +'_'+ target[0].name : target.getAttribute('id');
	return id + comp;
};

formValidation.prototype.subError = function(field, type) {
	var pId, cId;
	pId = $(this.makeErrorId(field));
	cId = $(this.makeErrorId(field, type));
	if(!pId || !cId) return;
	this.errors--;
	pId.removeChild(cId);
	if(pId.hasChildNodes()==false) pId.parentNode.removeChild(pId);
	this.setRightStyle(field);
};

formValidation.prototype.addValidation = function(target, type, label/*, params*/) {
	var t = [];
	if(!DOM.isChildOf($(target) , this.target)) {
		var nt = this.target[target.substring(this.nameLength+1)];
		if( typeof nt == 'undefined' ) return false;
		if(! nt.length) return false;
		target = nt;
		type = "FillRadio";
	}
	t['target'] = target;
	t['type'] = type;
	t['label'] = label;
	t['params'] = argumentsToArray(arguments, 3);
	this.validations.push(t);
};

formValidation.prototype.addOtherValidation = function(_str) {
	this.otherValidations.push(_str);
};

formValidation.prototype.getLabel = function(field, label) {
	if(label) {
		field.label = label;
		return label;
	} return field.label;
}
formValidation.prototype.setWrongStyle = function(t) {
	if(!t.style) return;
	if(t.getAttribute("type")=='radio') return;
	t.style.backgroundColor = '#FFCCCC';
	t.style.border = '1px solid red';
	t.style.color = '#000000';
}

formValidation.prototype.setRightStyle = function(t) {
	if(!t.style) return;
	if(t.getAttribute("type")=='radio') return;
	t.style.backgroundColor = '#CCFFCC';
	t.style.border = '1px solid green';
}

formValidation.prototype.addEvent = function(field, type, fn) {
	if(this.addedEvts) return;
	var o=this;
	Evt.add(field, type, function() { o['validate'+fn](field, false, false); } );
}

formValidation.prototype.validate = function() {

	$t('input[type=submit]', this.target).forEach(disableSubmit);

	this.addedEvts = false;
	this.errors = 0;
	var i, v=this.validations, t, other;
	for( i=0; i<v.length; i++ )
	{
		t = $(v[i]['target']);
		if(t) this['validate' + v[i]['type']](t, v[i]['label'], v[i]['params']);
	}

	this.addedEvts = true;

	other = this.otherValidations;
	for( i=0; i<other.length; i++ )
		if(!other[i].call(this)) return false;

	if(this.errors) {
		this.hasErrors(true);
		return false;
	}

	return true;
}



formValidation.prototype.hasErrors = function(has) {

	$t('input[type=submit]', this.target).forEach(enableSubmit);

	var target, cName, child, cTemp;
	cName = this.formName + 'divHasError';
	target = this.target.$t('fieldset')[0];
	cTemp = $(cName);
	child = (cTemp) ? cTemp :
		cE('div', target, cName, null, target.firstChild);


	child.className = 'divHasError';
	if(has) {
		addClass(this.target, 'hasError');
		child.innerHTML = this.m.hasErrors;
	}
	else target.removeChild(child);
}

formValidation.prototype.parse = function()
{
	var o = this;
	var old = (this.target.onsubmit) ? this.target.onsubmit : function(){ return true;} ;

	this.target.onsubmit = function() {
		if(!o.validate()) {
			location.hash = o.formName;
			return false;
		}
		return old();
	}
}


/* enable submits */
var enableSubmit = function(e) {
	e.disabled = false;
}

/*  disable submits */
var disableSubmit = function(e) {
	e.disabled = true;
}

function remainInnerHTML(n) {
	return formValidationMessages.remain.replace( /\[n\]/gi, n );
}
var max = formValidation.prototype.max = function(txtarea){
	var qtd = txtarea.getAttribute('maxlength');
	if(!qtd) return;
	var tam = txtarea.value.length;

	var nId = txtarea.getAttribute('id') + 'remain';
	var r = $(nId);
	if(!r) {

		var r = cE('div', txtarea.parentNode, nId, null, txtarea.nextSibling);
		r.className = 'remain';

		Evt.add(txtarea, 'keydown,keyup', function(){ max(txtarea); });
	}
	r.innerHTML = remainInnerHTML(qtd - tam)

	if (tam > qtd){
		aux = txtarea.value;
		txtarea.value = aux.substring(0,qtd);
		r.innerHTML = remainInnerHTML(0);
	}
}

bodyLoad.add(
	function() {
		$t('textArea').forEach(function(e){
			max(e);
		});
	}
);

/* VALIDACOES */
formValidation.prototype.validateMail = function(field, label){
	if(field.value.toString()=="") return true;
	label = this.getLabel(field, label);
	if(!validateMail(field)) {
		this.addError(field, this.m.email.replace( /\[label\]/gi, label ), 'Mail');
		var o=this;
		this.addEvent(field, "keydown,keyup,blur", 'Mail');
		return false;
	}
	this.subError(field, 'Mail');
	return true;
}

var validateMail = function(e) {
	var erMail= /^([\w-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$/i;
	return erMail.test(e.value.toString());
}

formValidation.prototype.validateFill = function(field, label){
	label = this.getLabel(field, label);
	var ant = $(field.id + '_ANT'), m;
	if(!validateFill(field) && !validateFill(ant)) {

		var o=this, end, evtType;
		var $tag = field.tagName; $tag = $tag ? $tag.toLowerCase() : false;
		var $radio = field[0] ? field[0].getAttribute('type') : false;

		if($tag=='select'||$radio=='radio') {
			end=this.m.selected; evtType='change';
		} else {
			end=this.m.filled; evtType='keydown,keyup,blur';
		}

		m = this.m.fill.replace( /\[label\]/gi, label );
		m = m.replace( /\[end\]/gi, end );

		this.addError(field, m, 'Fill');
		this.addEvent(field, evtType, 'Fill');
		return false;

	}

	this.subError(field, 'Fill');
	return true;
}
var validateFill = function(e) {
	if(!e) return false;
	var $tag = e.tagName;
	if (typeof $tag == 'undefined') return true;
	if( $tag.toLowerCase()=='select' ) {
			return e.options[e.selectedIndex].value.toString().length != 0;
	}
	return e.value.toString().length != 0;
}

formValidation.prototype.validateFillRadio = function(field, label)
{

	label = this.getLabel(field, label);

	if(!validateFillRadio(field)) {

		var o=this, end, evtType;
		end=this.m.selected;

		m = this.m.fill.replace( /\[label\]/gi, label );
		m = m.replace( /\[end\]/gi, end );

		this.addError(field, m, 'FillRadio');

		for( var i=0, n=field.length; i<n; i++ ) {
			this.addEvent(field[i], 'click', 'FillRadio');
		}

		return false;

	}

	this.subError(field, 'FillRadio');
	return true;
}

var validateFillRadio = function(e) {

	if( e.form ) e = $t('input[name='+e.name+']', e.parentNode.parentNode);


	var l = e.length, i;
	for (var i=0; i<l; i++) {
		if (e[i].checked==true)
			return true;
	}
	return false;

}


formValidation.prototype.validateMax = function(field, label, max){
	var m = '';
	label = this.getLabel(field, label);
	if(!validateMax(field, max)) {
		m = this.m.max.replace( /\[label\]/gi, label );
		m = m.replace( /\[max\]/gi, max );
		this.addError(field, m, 'max');
		var o=this;
		this.addEvent(field, "keydown,keyup,blur", 'Max');
		return false;
	}
	return true;
}
var validateMax = function(e, max) {
	return e.value.toString().length <= max;
}

/* mascaras */
var mask = function (o,f){
    v_obj = o;
    v_fun = window['mask' + f];
    setTimeout("execMask()",1)
}

var execMask = function (){
    v_obj.value = v_fun(v_obj.value);
}

var maskNumbers = function(v){
	return v.replace(/\D/g,"");
}

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

var maskPhone = function(v){
	v=v.replace(/\D/g,"");
	v=v.replace(/^(\d\d)(\d)/g,"($1) $2");
	v=v.replace(/(\d{4})(\d)/,"$1-$2");
	return v;
}

var maskCpf = function(v){
	v=v.replace(/\D/g,"");
	v=v.replace(/(\d{3})(\d)/,"$1.$2");
	v=v.replace(/(\d{3})(\d)/,"$1.$2");
	v=v.replace(/(\d{3})(\d{1,2})$/,"$1-$2");
	return v;
}

var maskCep = function(v){
	v=v.replace(/\D/g,"");
	v=v.replace(/^(\d{5})(\d)/,"$1-$2");
	return v;
}

var maskCnpj = function(v){
	v=v.replace(/\D/g,"");
	v=v.replace(/^(\d{2})(\d)/,"$1.$2");
	v=v.replace(/^(\d{2})\.(\d{3})(\d)/,"$1.$2.$3");
	v=v.replace(/\.(\d{3})(\d)/,".$1/$2");
	v=v.replace(/(\d{4})(\d)/,"$1-$2");
	return v;
}

var maskSite = function(v){
	v=v.replace(/^http:\/\/?/,"");
	var dominio=v;
	var caminho="";
	if(v.indexOf("/")>-1);
		dominio=v.split("/")[0];
	caminho=v.replace(/[^\/]*/,"");
	dominio=dominio.replace(/[^\w\.\+-:@]/g,"");
	caminho=caminho.replace(/[^\w\d\+-@:\?&=%\(\)\.]/g,"");
	caminho=caminho.replace(/([\?&])=/,"$1");
	if(caminho!="")dominio=dominio.replace(/\.+$/,"");
	v="http://"+dominio+caminho;
	return v;
};

var maskEmail = function(v) {
	return v.replace(/[^\w\d\+-:@\.]/g, '');
};

var maskDate = function(v) {
	v=v.replace(/\D/g,"");
	v=v.replace(/^(\d{2})(\d)/,"$1/$2");
	v=v.replace(/\/(\d{2})(\d)/,"/$1/$2");
	return v;
}

var maskHours = function(v) {
	v=v.replace(/\D/g,"");
	v=v.replace(/^(\d{2})(\d)/,"$1:$2");
	v=v.replace(/:(\d{2})(\d)/,":$1:$2");
	return v;
}