/*
 * $(obj).jField - Informacoes do campo
 * 
 * Cria um objeto para cada campo a ser verificado
 * Valores para type
 *					int:				[09,.]
 *					lower:			[a-z]
 *					lowers:			[a-zòàùèéì]
 *					upper:			[A-Z]
 *					uppers:			[A-Zòàùèéì]
 *					alpha:			[a-zA-Z]
 *					alphas:			[a-zA-Zòàùèéì]
 *					lowerInt:		[a-z0-9]
 *					lowersInt:		[a-z0-9òàùèéì]
 *					upperInt:		[A-Z0-9]
 *					uppersInt:		[A-Z0-9òàùèéì]
 *					alphaInt:		[a-zA-Z0-9]
 *					alphasInt:		[a-zA-Z0-9òàùèéì]
 */
jQuery.fn.jField = function(options){
	// Inicial as configuracoes
	var options = options || {};

	// Configuracoes basicas ou nao	
	options.name				= options.name;
	options.minLength			= options.minLength || 0;
	options.minLengthError	= options.minLengthError || false;
	options.type 				= options.type || 'alphasInt';
	options.typeError			= options.typeError || false;
	options.empty				= options.empty || 'yes';
	options.emptyError		= options.emptyError || false;

	// Metodos para o atributo	
	var jField = this;
	jField.options = options;
	
	// Validacao imediata
	this.keyup(function(event){
		$.jForm.checkField( jField, this.id );
	});
	
	// Formata Valores Reais
	if (options.type == 'currency')
	{
		//onkeypress="reais(this,event)" onkeydown="backspace(this,event)"
		this.keypress(function(event){
			reais(this, event);
		});
		
		this.keydown(function(event){
			backspace(this, event);
		});
	}
	
	// Valida imediata para SELECT
	if (options.type == 'select')
	{
		this.change(function(){
			$.jForm.checkField( jField, this.id );
		});
	}
	
	// Retorna o objeto jQuery + jField
	return jField;
}

/*
 * $(obj).jForm - Informacoes do formulario
 *
 * Pega os campos de $(obj).jField e, quando enviado, chama $.jForm
 */
jQuery.fn.jForm = function(jFields, messageBox){
	// Inicializa os campos
	var jForm 		= {};
	jForm.jFields	= jFields || {};
	
	// Configuracoes do jForm
	jForm.config 				= {}
	jForm.config.messageBox	= messageBox || 'msgErro';
	
	// Check inicial, eh requirido ?
	$.jForm.checkRequireds( jForm );
	
	// Form Enviado
	this.submit(function(){
		var valid = $.jForm.checkFields( jForm );
		
		if (!valid)
			return false;
		else
			$.jForm.floatlizeFields( jForm );
	});
}

/*
 * $.jForm - Checagem do formulario
 *
 * Quando o formulario e enviado, chama-se o $.jForm e faz a checagem
 */
$.jForm = {
	// Remove todas as classes de validacao e deixa apenas a que for ativada
	activeClass:
		function( jField, id, className ){
			$('label#label_' + id).removeClass('obrigatorio');
			$('label#label_' + id).removeClass('naoValida');
			$('label#label_' + id).removeClass('valida');
			
			if (className != false)
				$('label#label_' + id).addClass( className );
		}
	
	// Diz se o valor e valido ou nao, retorna a mensagem de erro
	,isValid:
		function( jField, id ){
			var minLength  		= jField.options.minLength;
			var minLengthError  	= jField.options.minLengthError;
			var type 				= jField.options.type;
			var typeError 			= jField.options.typeError;
			var value 				= jField.val();
			var empty				= jField.options.empty;
			var emptyError 		= jField.options.emptyError;
			var output 				= {valid: true, empty: false, error: false, showError: true};
			
			if (type == 'select')
			{
				if (empty == 'no' && (value == 0 || value == '0'))
				{
					output = {valid: false, empty: true, error: 'Selecione um valor em "' + jField.options.name + '"' };
				}
				else
				{
					output.valid = true;
					output.empty = true;
					output.error = false;
				}
			}
			else
			{
				// Regex Match
				if (type == 'int' && value.match(/[^\d]/))
				{
					output = {valid: false, error: 'Preencha apenas com n&uacute;meros o campo "' + jField.options.name + '"' };
				}
				else if (type == 'currency' && !value.match(/^([0-9,.]+)$/))
				{
					output = {valid: false, error: 'Coloque valores inteiros sem pontos e centavos separados por v&iacute;rgula em "' + jField.options.name + '". Exemplo 12345,67' };
				}
				else if (type == 'float' && !value.match(/^([0-9]+\,?([0-9]{0,}))$/))
				{
					output = {valid: false, error: 'As casas decimais de "' + jField.options.name + '" tem que ser separado por v&iacute;rgula. Exemplo 9,99' };
				}
				else if (type == 'email' && !value.match(/^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/))
				{
					output = {valid: false, error: 'Preencha o campo "' + jField.options.name + '" com um email v&aacute;lido' };
				}
				else if (type == 'password')
				{
					var value2 = $('#' + id + 'Confirma').val();
					
					if (value != value2)
						output = {valid: false, error: 'A senha e sua confirma&ccedil;&atilde;o devem ser iguais' };
				}
				
				output.error = typeError || output.error;
				
				// Not Empty
				if (empty == 'no' && !value)
				{
					output.error = emptyError || '&Eacute; obrigat&oacute;rio o preenchimento de "' + jField.options.name + '"';
					output.empty = true;
				}
				
				// Min Length
				if (value && value.length < minLength)
				{
					output.error = minLengthError || 'Os caracteres m&iacute;nimos para "' + jField.options.name + '" s&atilde;o ' + minLength;
					output.empty = true;
				}
				
				// Empty
				if (empty == 'yes' && !value)
				{
					output.valid = true;
					output.empty = true;
					output.error = false;
					output.showError = false;
					
					//alert('label#label_' + id + ' - ' + $('label#label_' + id).css('display'));
				}
				//alert( 'label#label_' + id + ' - ' + $('label#label_' + id).css('display') );
				
				// Nao esta visivel
				if ($('label#label_' + id).css('display') == 'none')
				{
					output.valid = true;
					output.empty = true;
					output.error = false;
					output.showError = false;
				}
			}
			
			return output;
		}
	
	// Diz se o campo eh obrigatorio ou nao
	,isRequired:
		function(jField){
			if (jField.options.empty == 'yes')
				return false;
			
			return true;
		}
	
	// Ve se o valor e valido ou nao, muda class do label
	,checkField:
		function( jField, id ){
			var output = $.jForm.isValid( jField, id );
			
			// O campo esta validado, e pode estar vazio
			if (output.showError == false)
			{
				$.jForm.activeClass( jField, id, false );
				
				return output;
			}
			
			// Ocorreu um erro na validacao
			if (output.error != false)
				$.jForm.activeClass( jField, id, 'naoValida' );
			else
				$.jForm.activeClass( jField, id, 'valida' );
			
			return output;
		}
	
	// Para cada jField ve se e valido e retorna o erro no DIV
	,checkFields:
		function( jForm ){
			var error = 'nothing';
			for (id in jForm.jFields)
			{
				var output = $.jForm.checkField( jForm.jFields[id], id );
	
				if (output.error != false && error == 'nothing')
				{
					error = output.error;
					$(jForm.jFields[id]).focus();
				}
			}
			
			if (error != 'nothing')
			{
				$('div.' + jForm.config.messageBox).html( error );
				$('div.' + jForm.config.messageBox).fadeIn('fast');
				
				if (typeof (sobeTopo) == 'function')
					sobeTopo(150);
					
				return false;
			}
			
			return true;
		}
	
	// Para cada jField ve se eh requirido ou nao ... coloca a classe
	,checkRequireds:
		function( jForm ){
			for (id in jForm.jFields)
			{
				var required = $.jForm.isRequired( jForm.jFields[id], id );
				var type = jForm.jFields[id].options.type;
				var value = jForm.jFields[id].val();
				
				if ((required && !value && type != 'select') || (type == 'select' && (value == 0 || value == '0')))
					$('label#label_' + id).addClass('obrigatorio');
			}
		}
	
	// Troca virgulas(,) por pontos(.) pro MySQL entender
	,floatlizeFields:
		function( jForm ){
			for (id in jForm.jFields)
			{
				var jField = jForm.jFields[id];
				var type = jField.options.type;
				var value = jField.val();
				
				if (type == 'float' || type == 'currency')
				{
					value = value.replace(/\./g, '');
					value = value.replace(/\,/g, '.');
				}
				
				jField.val( value );
			}
		}
};


/////// Mascaramento ////////
documentall = document.all;
/*
* função para formatação de valores monetários retirada de
* http://jonasgalvez.com/br/blog/2003-08/egocentrismo
*/

function formatamoney(c) {
	var t = this; if(c == undefined) c = 2;		
	var p, d = (t=t.split("."))[1].substr(0, c);
	for(p = (t=t[0]).length; (p-=3) >= 1;) {
		t = t.substr(0,p) + "." + t.substr(p);
	}
	return t+","+d+Array(c+1-d.length).join(0);
}

String.prototype.formatCurrency=formatamoney

function demaskvalue(valor, currency){
	/*
	* Se currency é false, retorna o valor sem apenas com os números. Se é true, os dois últimos caracteres são considerados as 
	* casas decimais
	*/
	var val2 = '';
	var strCheck = '0123456789';
	var len = valor.length;
	if (len== 0){
		return 0.00;
	}

	if (currency ==true){	
		/* Elimina os zeros à esquerda 
		* a variável  <i> passa a ser a localização do primeiro caractere após os zeros e 
		* val2 contém os caracteres (descontando os zeros à esquerda)
		*/
		
		for(var i = 0; i < len; i++)
			if ((valor.charAt(i) != '0') && (valor.charAt(i) != ',')) break;
		
		for(; i < len; i++){
			if (strCheck.indexOf(valor.charAt(i))!=-1) val2+= valor.charAt(i);
		}

		if(val2.length==0) return "0.00";
		if (val2.length==1)return "0.0" + val2;
		if (val2.length==2)return "0." + val2;
		
		var parte1 = val2.substring(0,val2.length-2);
		var parte2 = val2.substring(val2.length-2);
		var returnvalue = parte1 + "." + parte2;
		return returnvalue;
		
	}
	else{
			/* currency é false: retornamos os valores COM os zeros à esquerda, 
			* sem considerar os últimos 2 algarismos como casas decimais 
			*/
			val3 ="";
			for(var k=0; k < len; k++){
				if (strCheck.indexOf(valor.charAt(k))!=-1) val3+= valor.charAt(k);
			}			
	return val3;
	}
}

function reais(obj,event){

var whichCode = (window.Event) ? event.which : event.keyCode;
/*
Executa a formatação após o backspace nos navegadores !document.all
*/
if (whichCode == 8 && !documentall) {	
/*
Previne a ação padrão nos navegadores
*/
	if (event.preventDefault){ //standart browsers
			event.preventDefault();
		}else{ // internet explorer
			event.returnValue = false;
	}
	var valor = obj.value;
	var x = valor.substring(0,valor.length-1);
	obj.value= demaskvalue(x,true).formatCurrency();
	return false;
}
/*
Executa o Formata Reais e faz o format currency novamente após o backspace
*/
FormataReais(obj,'.',',',event);
} // end reais


function backspace(obj,event){
/*
Essa função basicamente altera o  backspace nos input com máscara reais para os navegadores IE e opera.
O IE não detecta o keycode 8 no evento keypress, por isso, tratamos no keydown.
Como o opera suporta o infame document.all, tratamos dele na mesma parte do código.
*/

var whichCode = (window.Event) ? event.which : event.keyCode;
if (whichCode == 8 && documentall) {	
	var valor = obj.value;
	var x = valor.substring(0,valor.length-1);
	var y = demaskvalue(x,true).formatCurrency();

	obj.value =""; //necessário para o opera
	obj.value += y;
	
	if (event.preventDefault){ //standart browsers
			event.preventDefault();
		}else{ // internet explorer
			event.returnValue = false;
	}
	return false;

	}// end if		
}// end backspace

function FormataReais(fld, milSep, decSep, e) {
var sep = 0;
var key = '';
var i = j = 0;
var len = len2 = 0;
var strCheck = '0123456789';
var aux = aux2 = '';
var whichCode = (window.Event) ? e.which : e.keyCode;

//if (whichCode == 8 ) return true; //backspace - estamos tratando disso em outra função no keydown
if (whichCode == 0 ) return true;
if (whichCode == 9 ) return true; //tecla tab
if (whichCode == 13) return true; //tecla enter
if (whichCode == 16) return true; //shift internet explorer
if (whichCode == 17) return true; //control no internet explorer
if (whichCode == 27 ) return true; //tecla esc
if (whichCode == 34 ) return true; //tecla end
if (whichCode == 35 ) return true;//tecla end
if (whichCode == 36 ) return true; //tecla home

/*
O trecho abaixo previne a ação padrão nos navegadores. Não estamos inserindo o caractere normalmente, mas via script
*/

if (e.preventDefault){ //standart browsers
		e.preventDefault()
	}else{ // internet explorer
		e.returnValue = false
}

var key = String.fromCharCode(whichCode);  // Valor para o código da Chave
if (strCheck.indexOf(key) == -1) return false;  // Chave inválida

/*
Concatenamos ao value o keycode de key, se esse for um número
*/
fld.value += key;

var len = fld.value.length;
var bodeaux = demaskvalue(fld.value,true).formatCurrency();
fld.value=bodeaux;

/*
Essa parte da função tão somente move o cursor para o final no opera. Atualmente não existe como movê-lo no konqueror.
*/
  if (fld.createTextRange) {
    var range = fld.createTextRange();
    range.collapse(false);
    range.select();
  }
  else if (fld.setSelectionRange) {
    fld.focus();
    var length = fld.value.length;
    fld.setSelectionRange(length, length);
  }
  return false;

}