jQuery.validar = function(formulario,regras) {
    $(formulario).unbind("submit");
    // adiciona evento onblur em todos os campos expecificados
    $.each( regras.campos, function(index, campo){
        $('#'+campo.id).unbind("blur");
        $('#'+campo.id).blur(function(){
            $.validarCampo(campo);
        });
    });
    // manipulando o evento onSubmit do formulario expecificado
    $(formulario).submit( function(event){
        $.each(regras.campos, function(index, campo){
            $.validarCampo(campo);
        });
        var valido = true;
        $.each(regras.campos,function(){
            if($('#'+this.id).attr('rel') == 'invalido'){
                valido = false;
                $(this).find('.loader').css("display","none");
            }
        });
        if(valido == true){
            $(this).find('.loader').css("display","block");
        }
        return valido;
    });

};

/**
 *Percorre todos os campos expecificados na configuracao e adiciona o evento onblur
 *para que seja validado no momento que o campo perde o foco
 *@param campos - array com todos os campos a serem verificados
 */
jQuery.verificarCamposPerdaDeFoco = function (campos){
    // removendo todos os atributos que contenham classe de erro.
    $('.campoInvalido').remove();
    $.each( campos, function(index, campo){
        $('#'+campo.id).blur(function(){
            $.validarCampo(campo);
        });
    });
}

/**
 *Funcao que varifica o modo de validacao do campo e chama determinada funcao.
 *Não chamar esta funcao diretamente.
 *@param campo - o campo a ser verificado.
 */
jQuery.validarCampo = function(campo){
    if(document.getElementById(campo.id)) {
        if(campo.tipo == "requerido" || campo.requerido == 'true')
            $.validarCampoRequerido(campo.id);
        if(campo.tipo == "tamanho")
            $.validarTamanho(campo.id, campo.min, campo.max);
        if(campo.tipo == "cpf")
            $.validarCpf(campo.id);
        if(campo.tipo == "data")
            $.validarData(campo.id);
        if(campo.tipo == "igual")
            $.validarIgualdadeDeValores(campo.igual,campo.id);
        if(campo.tipo == "email")
            $.validarEmail(campo.id);
        if(campo.tipo == "hora")
            $.validarHora(campo.id);
        if(campo.tipo == 'cpfUnico')
            $.validarCpfUnico(campo.id);
        if(campo.tipo == 'loginUnico')
            $.validarLoginUnico(campo.id);
        if(campo.tipo =="ajax")
            $.validarPorAjax(campo.id, campo.url, campo.parametros, campo.mensagem)
    }
}
/**
 * Funcao para validar campo de cpf
 * Deve ser expecificado obrigatoriamente o id do campo
 * @param campo - O id do campo do cpf
 */
jQuery.validarCpf = function (campo) {
    if(cpfValido(campo)){
        $.adicionarMensagemCampoOK(campo);
    }else{
        $.adicionarMensagemErro(campo, "CPF informado é inválido.");
    }
}

function cpfValido(campo) {
    var cpf = $('#'+campo).val();
    //Retira todos os caracteres que não sejam números
    var re = new RegExp('[^0-9]', "g");
    cpf = cpf.replace(re,'');
    if (cpf.length != 11 || (cpf % 11111111111) == 0)
        return false;
    add = 0;
    for (i=0; i < 9; i ++)
        add += parseInt(cpf.charAt(i)) * (10 - i);
    rev = 11 - (add % 11);
    if (rev == 10 || rev == 11)
        rev = 0;
    if (rev != parseInt(cpf.charAt(9)))
        return false;
    add = 0;
    for (i = 0; i < 10; i ++)
        add += parseInt(cpf.charAt(i)) * (11 - i);
    rev = 11 - (add % 11);
    if (rev == 10 || rev == 11)
        rev = 0;
    if (rev != parseInt(cpf.charAt(10)))
        return false;
    return true;
}

jQuery.validarCpfUnico = function(campo) {
    if(cpfValido(campo)) {
        var cpf = $('#'+campo).val();
        var regExp = new RegExp('[^0-9]', "g");
        cpf = cpf.replace(regExp,'');
        $.post('ajax', {
            tipo:'validarCpf',
            'cpf': cpf
        }, function(data){
            if(data == 'false')
                $.adicionarMensagemCampoOK(campo);
            if(data == 'true')
                $.adicionarMensagemErro(campo, 'CPF já existe.')
        });
    } else {
        $.adicionarMensagemErro(campo, "CPF informado é inválido.");
    }
}

jQuery.validarLoginUnico = function(campo) {
    if($.jqURL.get("editar") != 'true'){
        var login = $('#'+campo).val();
        $.post("ajax", {
            tipo:"verificarUsuarioCadastrado",
            'login': login
        }, function(data){
            if(data == "tamanhoInvalido"){
                $.adicionarMensagemErro(campo, 'O campo deve conter entre 6 e 10 caracteres.');
                return;
            }
            if(data =='formatoInvalido'){
                $.adicionarMensagemErro(campo, 'Caracteres inválidos. Apenas letras,números,\"@\", e \".\" ');
            }else{
                if(data == 'true') {
                    $.adicionarMensagemErro(campo, 'Usuário existente.');
                } else {
                    $.adicionarMensagemCampoOK(campo);
                }
            }
        });
    }
}
/**
 * Valida tamanho do campo
 * @param campo - Id do campo
 * @param min - tamanho minimo
 * @param max - tamanho maximo
 */
jQuery.validarTamanho = function(campo,min,max){
    if($('#'+campo).val().length < min || $('#'+campo).val().length > max){
        $.adicionarMensagemErro(campo, "O campo deve conter entre "+min+" e "+max+" caracteres.");
    }else{
        $.adicionarMensagemCampoOK(campo);
    }
}
/**
 * Valida campo como sendo obrigat&oacute;rio
 * @param campo - Id do campo a ser validado
 */
jQuery.validarCampoRequerido = function(campo){
    if($.trim($('#'+campo).val()).length < 1 ){
        $.adicionarMensagemErro(campo, "Este campo é obrigatório");
    }else{
        $.adicionarMensagemCampoOK(campo);
    }
}

jQuery.validarData = function (campo){
    if(!$('#'+campo).val().match(/^((((0?[1-9]|[12]\d|3[01])[\.\-\/](0?[13578]|1[02])[\.\-\/]((1[6-9]|[2-9]\d)?\d{2}))|((0?[1-9]|[12]\d|30)[\.\-\/](0?[13456789]|1[012])[\.\-\/]((1[6-9]|[2-9]\d)?\d{2}))|((0?[1-9]|1\d|2[0-8])[\.\-\/]0?2[\.\-\/]((1[6-9]|[2-9]\d)?\d{2}))|(29[\.\-\/]0?2[\.\-\/]((1[6-9]|[2-9]\d)?(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00)|00)))|(((0[1-9]|[12]\d|3[01])(0[13578]|1[02])((1[6-9]|[2-9]\d)?\d{2}))|((0[1-9]|[12]\d|30)(0[13456789]|1[012])((1[6-9]|[2-9]\d)?\d{2}))|((0[1-9]|1\d|2[0-8])02((1[6-9]|[2-9]\d)?\d{2}))|(2902((1[6-9]|[2-9]\d)?(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00)|00))))$/)){
        $.adicionarMensagemErro(campo,"Data inv&aacute;lida formato dd/mm/aaaa.");
    }else{
        $.adicionarMensagemCampoOK(campo);
    }
}
/**
  * Funcao quer verifica se dois campos possuem o mesmo valor
  * @param campo1 - O campo com o valor inicial valido
  * @param campo2 - O campo a ser comparado com o campo1
  */
jQuery.validarIgualdadeDeValores = function (campo1,campo2){
    if($('#'+campo2).val() == $('#'+campo1).val()){
        $.adicionarMensagemCampoOK(campo2);
    }else{
        $.adicionarMensagemErro(campo2,"Valor não corresponde.");
    }
}
/**
  * Funcao para validar email
  * @param campo - Campo a ser verificado o email
  */
jQuery.validarEmail = function(campo){
    var mail = $('#'+campo).val();
    var emailRegEx = new RegExp(/^[a-zA-Z][\w\.-]*[a-zA-Z0-9]@[a-zA-Z0-9][\w\.-]*[a-zA-Z0-9]\.[a-zA-Z][a-zA-Z\.]*[a-zA-Z]$/);
    if(emailRegEx.test(mail)){
        $.adicionarMensagemCampoOK(campo);
    }else{
        $.adicionarMensagemErro(campo,"Email inválido.");
    }
}

/**
 *@example Exemplo: 24:40 data válida 23/50 data inválida
 *@param campo - campo a ser validado a hora
 **/
jQuery.validarHora = function(campo){
    var hora = $('#'+campo).val();
    var regExp = new RegExp(/[0-9][0-9]:[0-9][0-9]$/);
    if(regExp.test(hora)){
        var hr = hora.substring(0, 2);
        var min = hora.substr(3, 5);
        if(hr > 23 || hr < 0 || min > 59 || min < 0)
            $.adicionarMensagemErro(campo,"Hora inválida." );
        else
            $.adicionarMensagemCampoOK(campo);
    }else{
        $.adicionarMensagemErro(campo,"Hora inválida." );
    }
}

/**
 *Valida se o valor do campo é composto apenas de numeros
 *@param campo - O campo a ser validado
 **/
jQuery.verificarCampoNumerico = function (campo){
    var valor = $('#'+campo).val();
    var regExp = new RegExp(/[0-9]+$/);
    if(regExp.test(valor))
        $.adicionarMensagemCampoOK(campo);
    else{
        $.adicionarMensagemErro(campo,"O campo deve conter apenas números." );
    }
}

jQuery.verificarCampoCaracteres = function (campo){
    var valor = $('#'+campo).val();
    var regExp = new RegExp(/[a-zA-Z]+$/);
    if(regExp.test(valor))
        $.adicionarMensagemCampoOK(campo);
    else{
        $.adicionarMensagemErro(campo,"O campo deve conter apenas letras." );
    }
}

/**
  * Funcao para validacao remota
  * @param campo - O campo a ser validado
  * @param url   - Url que será invocada
  * @param parametros - parametros que serão enviados na requisicao ( formato JSON )
  **/
jQuery.validarPorAjax = function(campo,url,parametros,mensagem){
    $.post(url, parametros, function(data){
        if(data == "true" || data.toString() == "true")
            $.adicionarMensagemCampoOK(campo);
        else {
            $.adicionarMensagemErro(campo,mensagem);
        }
    }, "json");
}
/**
 * Adiciona uma mensagem de erro pré definida ao campo expecificado
 * @param campo    -   Id do campo a ser marcado como inválido
 * @param mensagem -   mensagem de erro no formato HTML
 */
jQuery.adicionarMensagemErro = function(campo,mensagem){
    $.removerMensagem(campo);
    $('#'+campo).after("<em class=\"campoInvalido\">"+mensagem+"</em>");
    $.atribuirErro(campo);
}
/**
  * Notifica usuario sobre o correto preenchimento do campo
  * @param campo - Campo a ser removido mensagem
  */
jQuery.adicionarMensagemCampoOK = function(campo){
    $.removerMensagem(campo);
    $('#'+campo).removeClass('invalido');
    $('#'+campo).after("<em class=\"campoValido\"></em>");
    $('#'+campo).removeAttr('rel');
}

/**
  * Remove todas as mensagens de um campo expecífico
  * @param campo - Campo a ser removido mensagem
  */
jQuery.removerMensagem = function(campo){
    $('#'+campo).parent().find(".campoInvalido,.campoValido").remove();
}

jQuery.atribuirErro = function(campo){
    $('#'+campo).addClass('invalido');
    $('#'+campo).attr('rel','invalido');
}
