// acrescenta as funções do form no onLoad da página //
$(document).ready(function() {
	$('form').formSubmit();
	$('input').inputMask();
	$('textarea').limited();
});

// acrescenta validação de formulário no onSubmit //
$.fn.formSubmit = function() {
	inputFocus(this);
	this.submit(function() {
		return formValid(this);
	});
}

function inputFocus(form) {
	setFocus = false;
	if($(form).attr('focus') != 'no') {
		$(form).find('input,select,textarea').filter(':enabled').each(function() {
			if(!setFocus) {
				switch(this.getAttribute('type')) {
					case 'hidden':
					case 'submit':
						break;
					default:
						setFocus = true;
						this.focus();
						return;
				}
			}
		});
	}
}

// acrescenta máscara nos campos dos formulário //
$.fn.inputMask = function() {
	this.keypress(function(event) {
		switch(this.getAttribute('param')) {
			case 'date':
				return maskDate(event, this);
				break
			case 'numb':
				return maskNumber(event, this, this.getAttribute('mask'));
				break
			case 'deci':
				return maskFloat(event, this);
				break
		}
	});
}

// acrescenta limite nos campos textarea //
$.fn.limited = function() {
	this.keyup(function() {
		if(this.getAttribute('param') == 'limited')
			textLimit(this, this.getAttribute('maxlength'), this.getAttribute('target'));
	});
	this.change(function() {
		if(this.getAttribute('param') == 'limited')
			textLimit(this, this.getAttribute('maxlength'), this.getAttribute('target'));
	});
}

// valida um formulário //
function formValid(form) {
	valida = true;
	$(form).find('input,select,textarea').filter(':enabled').each(function() {
		if(valida) {
			if(this.getAttribute('required')) {
				if(this.getAttribute('type') == 'radio' || this.getAttribute('type') == 'checkbox') {
					if(!isChecked($(this.form).find('input[@name="' + this.name + '"]'), this.getAttribute('validationmsg'))) {
						valida = false;
						this.focus();
						return;
					}
				}
				else if(isEmpty(this.value, this.getAttribute('validationmsg'))) {
					valida = false;
					this.focus();
					return;
				}
			}
			if(field1 = this.getAttribute('compare')) {
				if(!compareStr($(form).find('input[@name="' + field1 + '"]')[0].value, this.value, this.getAttribute('validationmsg'))) {
					valida = false;
					this.focus();
					return;
				}
			}
			switch(this.getAttribute('param')) {
				case 'date':
					if(!isDate(this.value)) {
						alert('Data Inválida!');
						valida = false;
						this.focus();
					}
					break;
				case 'email':
					if(!isMail(this.value)) {
						alert('E-mail Inválido!');
						valida = false;
						this.focus();
					}
					break;
				case 'cpf':
					if(!isCPF(this.value)) {
						alert('CPF Inválido!');
						valida = false;
						this.focus();
					}
					break;
				case 'cnpj':
					if(!isCNPJ(this.value)) {
						alert('CNPJ Inválido!');
						valida = false;
						this.focus();
					}
					break;
				case 'cpfcnpj':
					if(!isCPF(this.value) && !isCNPJ(this.value)) {
						alert('CPF / CNPJ Inválido!');
						valida = false;
						this.focus();
					}
					break;
			}
		}
	});
	return valida;
}

// verifica se uma string está vazia ou só com espaços //
function isEmpty(str, msg) {
	if($.trim(str) != '')
		return false;
	if(msg != '')
		alert(msg);
	return true;
}

// verifica se um campo tipo checkbox ou radio de um formulário foi marcado //
function isChecked(field, msg) {
	if(field.length) {
		for(i = 0; i < field.length; i++) {
			if(field[i].checked)
				return true;
		}
	}
	else if(field.checked)
		return true;
	if(msg != '')
		alert(msg);
	return false;
}

// verifica se uma string é uma data (dd/mm/aaaa) //
function isDate(str) {
	if(str.length >= 10) {
		dia = parseInt(str.substr(0, 2), 10);
		mes = parseInt(str.substr(3, 2), 10);
		ano = parseInt(str.substr(6, 4), 10);
		if(dia > 0 && dia < 32 && mes > 0 && mes < 13 && ano > 999 && ano < 10000) {
			if(mes == 2 && dia > 28) {
				if(ano % 4)
					return false;
				else if(dia > 29)
					return false;
			}
			switch(mes) {
				case 4:
				case 6:
				case 9:
				case 11:
					if(dia > 30)
						return false;
					break;
			}
		}
		else
			return false;
	}
	else if(str.length)
		return false;
	return true;
}

// verifica se uma string é um e-mail válido //
function isMail(str) {
	if(str.length)
		return(/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/.test(str));
	return true;
}

// verifica se uma string é um CPF válido //
function isCPF(str) {
	var i, j, soma;
	if(str.length) {
		if(str.length != 11)
			return false;
		j = true;
		for(i = 0; i < 9; i++) {
			if(parseInt(str.charAt(i), 10) != parseInt(str.charAt(i + 1), 10)) {
				j = false;
				break;
			}
		}
		if(j)
			return false;
		for(j = 0; j < 2; j++) {
			soma = 0;
			for(i = 0; i < 9 + j; i++)
				soma += parseInt(str.charAt(i), 10) * (10 + j - i);
			soma = 11 - (soma % 11);
			if(soma > 9)
				soma = 0;
			if(soma != parseInt(str.charAt(9 + j), 10))
				return false;
		}
	}
	return true;
}

// verifica se uma string é um CNPJ válido //
function isCNPJ(str) {
	var i, j, k, soma;
	if(str.length) {
		if(str.length != 14)
			return false;
		for(k = 0; k < 2; k++) {
			soma = 0;
			j = 5 + k;
			for(i = 0; i < 12 + k; i++) {
				soma += parseInt(str.charAt(i), 10) * j;
				if(j > 2)
					j--;
				else
					j = 9;
			}
			soma = 11 - soma % 11;
			if(soma > 9)
				soma = 0;
			if(soma != parseInt(str.charAt(12 + k), 10))
				return false;
		}
	}
	return true;
}

// compara duas strings //
function compareStr(str1, str2, msg) {
	if(str1 != str2) {
		if(msg != '')
			alert(msg);
		return false;
	}
	return true;
}

// substitui todas as ocorrências de um char por replace numa string //
function substitui(chr, rpl, str) {
	txt = str.replace(chr, rpl);
	while(txt != str) {
		str = txt;
		txt = str.replace(chr, rpl);
	}
	return str;
}

// cria data a partir de uma string (dd/mm/aaaa) //
function toDate(data) {
	if(isDate(data)) {
		dia = parseInt(data.substr(0, 2), 10);
		mes = parseInt(data.substr(3, 2), 10);
		ano = parseInt(data.substr(6, 4), 10);
		return new Date(ano, mes - 1, dia);
	}
	else
		return new Date();
}

// completa com zeros à esquerda //
function Zeros(texto, tamanho) {
	while(texto.length < tamanho)
		texto = '0' + texto;
	return texto;
}

// convert data para string (dd/mm/aaaa) //
function toDateStr(data) {
	dia = Zeros(data.getDate().toString(10), 2);
	mes = Zeros((data.getMonth() + 1).toString(10), 2);
	ano = data.getFullYear();
	return dia + '/' + mes + '/' + ano;
}

// retorna tamanho do mes //
function monthLen(mes, ano) {
	switch(mes) {
		// meses com 30 dias //
		case 4:
		case 6:
		case 9:
		case 11:
			return 30;
			break;
		// fevereiro //
		case 2:
			// se ano não for bisexto //
			if(ano % 4)
				return 28;
			else
				return 29;
			break;
		// meses com 31 dias //
		default:
			return 31;
	}
}

// adiciona em uma parte da data um número //
function dateAdd(parte, numero, data) {
	dia = data.getDate();
	mes = data.getMonth() + 1;
	ano = data.getFullYear();
	switch(parte) {
		// acrescenta dias na data //
		case 'd':
			dia += numero;
			while(dia > monthLen(mes, ano)) {
				dia -= monthLen(mes, ano);
				mes += 1;
				if(mes > 12) {
					mes = 1;
					ano += 1;
				}
			}
			break;
		// acrescenta meses na data //
		case 'm':
			mes += numero;
			while(mes > 12) {
				mes -= 12;
				ano += 1;
			}
			if(dia > monthLen(mes, ano))
				dia = monthLen(mes, ano);
			break;
		// acrescenta anos na data //
		case 'y':
			ano += numero;
			if(mes == 2 && dia == 29 && ano % 4)
				dia = 28;
			break;
		default:
			// erro de parâmetro (retorna a mesma data) //
	}
	return new Date(ano, mes - 1, dia)
}

// compara duas datas //
function compareDate(data1, data2) {
	if(data1 < data2)
		return -1;
	else if(data1 > data2)
		return 1;
	else
		return 0;
}

// compara duas datas como string (dd/mm/aaaa) //
function compareDateStr(data1, data2) {
	d1 = toDate(data1);
	d2 = toDate(data2);
	return compareDate(d1, d2);
}

// converte texto para valor numerico
function toNumber(valor) {
	return parseFloat(valor.replace(',', '.').replace('.', ''));
}

// aceita a digitação somente de números com ou sem máscara (keypress) //
function maskNumber(ev, campo, mask) {
	if(jQuery.browser.msie) {
		if((ev.keyCode < 48 || ev.keyCode > 57) && ev.keyCode != 13) {
			ev.returnValue = false;
			return false;
		}
	}
	else if(!ev.keyCode && (ev.charCode < 48 || ev.charCode > 57)) {
		ev.preventDefault(false);
		ev.stopPropagation();
		return false;
	}
	if(campo && mask) {
		i = campo.value.length;
		if(i < mask.length && i < campo.maxLength) {
			c = mask.charAt(i);
			if(c != '9')
				campo.value += c;
		}
	}
}

// coloca mascara em campo data (dd/mm/aaaa) [keypress] //
function maskDate(ev, campo) {
	return maskNumber(ev, campo, '99/99/9999 99:99:99');
}

// coloca mascara em campo float [keypress] //
function maskFloat(ev, campo) {
	if(jQuery.browser.msie) {
		if(ev.keyCode == 46)
			campo.value = substitui('.', '', campo.value);
		else
			return maskNumber(ev);
	}
	else {
		if(ev.charCode == 46)
			campo.value = substitui('.', '', campo.value);
		else
			return maskNumber(ev);
	}
}

// calcula módulo //
function modulo(numero, mod, x) {
	total = 0;
	for(i = 0; i < numero.length; i++)
		total += parseInt(numero.substr(numero.length - (i + 1), 1), 10) * ((i % 8) + 2);
	digito = mod - (total % mod);
	return (digito > 9) ? x : digito;
}

// copia itens de um select para outro //
function copySel(origem, destino) {
	tam = origem.options.length;
	for(i = 0; i < tam; i++) {
		if(origem.options[i].selected) {
			var Opt = new Option();
			Opt.text = origem.options[i].text;
			Opt.value = origem.options[i].value;
			for(j = 0; j < destino.options.length; j++)
				if(Opt.text < destino.options[j].text)
					break;
			if(j < destino.options.length)
				destino.options.add(Opt, j);
			else
				destino.options.add(Opt);
			origem.remove(i);
			tam--;
			i--;
		}
	}
}

// limita campo textarea [change][keyup]
function textLimit(campo, tam, count) {
	if(campo.value.length >= tam)
		campo.value = campo.value.substr(0, tam);
	$('#' + count).html(campo.value.length + '');
}