$.validator.addMethod("exactlenght", function(value, element, param) {
    return this.optional(element) || (value != "" ? (value.length == param) : true);
});

$.validator.addMethod("alpha", function(value, element) {
    return this.optional(element) || value.search(/[^a-z]/i) == -1;
});

$.validator.addMethod("alphaNumeric", function(value, element) {
    return this.optional(element) || value.search(/[^a-z0-9]/i) == -1;
});

$.validator.addMethod("alphaDash", function(value, element) {
    return this.optional(element) || value.search(/[^\w-]/i) == -1;
});

$.validator.addMethod("integer", function(value, element) {
    return this.optional(element) || !(isNaN(value) || value.indexOf(".") > -1)
});

$.validator.addMethod("isNatural", function(value, element) {
    return this.optional(element) || (!isNaN(value) && value >= 0)
});

$.validator.addMethod("isNaturalNoZero", function(value, element) {
    return this.optional(element) || (!isNaN(value) && value > 0)
});

$.validator.addMethod("ip", function(value, element) {
    if (this.optional(element))
        return "dependency-mismatch";

    var segs = value.split(".");
    for (var i in segs)
        if(segs[i].length>3 || segs[i]>255 || segs[i].search(/\D/)>-1)
            return false;
    return true;
});

$.validator.addMethod("base64", function(value, element) {
    return this.optional(element) || value.search(/[^a-zA-Z0-9\/\+=]/) == -1;
});

$.validator.addMethod("callback", function(value, element, param) {
    if (this.optional(element))
        return "dependency-mismatch";

    //Busca o elemento anterior
    var previous = this.previousValue(element);

    //Verifica se o valor foi trocado
    if (previous.old !== value) {

        //Monta os dados
        var data = {};
        if(param.data) {
            //Verifica se foi passado algum id de campo
            if($("#"+param.data))
                data[param.data] = $("#"+param.data).val();
            else
                data = param.data;
        }
        //Monta a str, o flag ajax_in_use e seta o flag para não salvar a url
        data["str"]         = value;
        data["ajax_in_use"] = true;
        data["noSaveUrl"]   = true;

        previous.old = value;
        var validator = this;
        this.startRequest(element);
        //Executa a chamada a página passada no param
        $.ajax({
            url: param.url,
            type: "post",
            dataType: "json",
            data: data,
            success: function(response) {
                if (!response) {
                    //Em caso de false, exibe os erros
                    var errors = {};
                    errors[element.name] =  response || validator.defaultMessage(element, "callback");
                    validator.showErrors(errors);
                } else {
                    var submitted = validator.formSubmitted;
                    validator.prepareElement(element);
                    validator.formSubmitted = submitted;
                    validator.successList.push(element);
                    validator.showErrors();
                }
                previous.valid = response;
                validator.stopRequest(element, response);
            }
        });
        //Segura o validator
        return "pending";
    }
    else if(this.pending[element.name])
       //Segura o validator
       return "pending";

    //Retorna a validação
    return previous.valid;

});
