(function() {
	
    function stripHtml(value) {
        // remove html tags and space chars
        return value.replace(/<.[^<>]*?>/g, ' ').replace(/&nbsp;|&#160;/gi, ' ')
        // remove numbers and punctuation
        .replace(/[0-9.(),;:!?%#$'"_+=\/-]*/g,'');
    }
    jQuery.validator.addMethod("maxWords", function(value, element, params) {
        return this.optional(element) || stripHtml(value).match(/\b\w+\b/g).length < params;
    }, jQuery.validator.format("Please enter {0} words or less."));
	 
    jQuery.validator.addMethod("minWords", function(value, element, params) {
        return this.optional(element) || stripHtml(value).match(/\b\w+\b/g).length >= params;
    }, jQuery.validator.format("Please enter at least {0} words."));
	 
    jQuery.validator.addMethod("rangeWords", function(value, element, params) {
        return this.optional(element) || stripHtml(value).match(/\b\w+\b/g).length >= params[0] && value.match(/bw+b/g).length < params[1];
    }, jQuery.validator.format("Please enter between {0} and {1} words."));

})();

jQuery.validator.addMethod("letterswithbasicpunc", function(value, element) {
    return this.optional(element) || /^[a-z-.,()'\"\sñáéíóúÁÉÍÓÚñ]+$/i.test(value);
}, "Por favor solamente letras o signos de puntuación.");

jQuery.validator.addMethod("alphanumeric", function(value, element) {
    return this.optional(element) || (!/[_]+/i.test(value) && /^[\w]+$/i.test(value));
}, "Por favor solamente letras y/o numeros.");

jQuery.validator.addMethod("lettersonly", function(value, element) {
    return this.optional(element) || /^[a-zsñáéíóúÁÉÍÓÚñ]+$/i.test(value);
}, "Por favor solamente letras.");

jQuery.validator.addMethod("nowhitespace", function(value, element) {
    return this.optional(element) || /^\S+$/i.test(value);
}, "Por favor no espacios en blanco.");

jQuery.validator.addMethod("integer", function(value, element) {
    return this.optional(element) || /^-?\d+$/.test(value);
}, "Por favor solo numeros enteros.");

jQuery.validator.addMethod("digit", function(value, element) {
    return this.optional(element) || /^\d+$/.test(value);
}, "Por favor solo digitos.");

jQuery.validator.addMethod("youtube", function(value, element) {
    return this.optional(element) || /^http:\/\/www\.youtube\.com\/watch\?v=/.test(value);
}, "Por favor escribe un video valido de Youtube.");
/**
  * Return true, if the value is a valid date, also making this formal check dd/mm/yyyy.
  *
  * @example jQuery.validator.methods.date("01/01/1900")
  * @result true
  *
  * @example jQuery.validator.methods.date("01/13/1990")
  * @result false
  *
  * @example jQuery.validator.methods.date("01.01.1900")
  * @result false
  *
  * @example <input name="pippo" class="{dateITA:true}" />
  * @desc Declares an optional input element whose value must be a valid date.
  *
  * @name jQuery.validator.methods.dateITA
  * @type Boolean
  * @cat Plugins/Validate/Methods
  */
jQuery.validator.addMethod(
    "fecha",
    function(value, element) {
        var check = false;
        var re = /^\d{1,2}\/\d{1,2}\/\d{4}$/;
        if( re.test(value)){
            var adata = value.split('/');
            var gg = parseInt(adata[0],10);
            var mm = parseInt(adata[1],10);
            var aaaa = parseInt(adata[2],10);
            var xdata = new Date(aaaa,mm-1,gg);
            if ( ( xdata.getFullYear() == aaaa ) && ( xdata.getMonth () == mm - 1 ) && ( xdata.getDate() == gg ) )
                check = true;
            else
                check = false;
        } else
            check = false;
        return this.optional(element) || check;
    },
    "Por favor, escribe una fecha valida.");

jQuery.validator.addMethod(
    "rut",
    function(value, element) {
        var check = true;
        var sRut = value.toLowerCase();

        var pattern = /[\s\.-]/g;
        sRut = sRut.replace(pattern, "");

        if (sRut == "")
            check = false;

        var tmp = sRut.slice(0, -1);

        var T=tmp;
        var M=0,S=1;
        for(;T;T=Math.floor(T/10))
            S=(S+T%10*(9-M++%6))%11;
        var dvdr = S?S-1:'k';

        if(dvdr != sRut.slice(-1))
            check = false;

        return this.optional(element) || check;
    },
    "Por favor, escribe un RUT valido.");


jQuery.validator.addMethod("hora", function(value, element) {
    return this.optional(element) || /^([01][0-9])|(2[0123]):([0-5])([0-9])$/.test(value);
}, "Por favor, escribe una hora valida, entre 00:00 y 23:59");

jQuery.validator.addMethod('fax', function(value, element) {
    return this.optional(element) || value.length > 9 &&
    value.match(/^[0-9]{2}\-[0-9]{1,}\-[0-9]{1,}$/);
}, 'Por favor ingresa un numero de fax valido. Ej. 56-2-6567300');

jQuery.validator.addMethod('telefono', function(value, element) {
    return this.optional(element) || value.length > 9 &&
    value.match(/^[0-9]{2}\-[0-9]{1,}\-[0-9]{1,}$/);
}, 'Por favor ingresa un numero telefónico valido. Ej. 56-2-6567300');

// TODO check if value starts with <, otherwise don't try stripping anything
jQuery.validator.addMethod("strippedminlength", function(value, element, param) {
    return jQuery(value).text().length >= param;
}, jQuery.validator.format("Please enter at least {0} characters"));


// NOTICE: Modified version of Castle.Components.Validator.CreditCardValidator
// Redistributed under the the Apache License 2.0 at http://www.apache.org/licenses/LICENSE-2.0
// Valid Types: mastercard, visa, amex, dinersclub, enroute, discover, jcb, unknown, all (overrides all other settings)
jQuery.validator.addMethod("creditcardtypes", function(value, element, param) {

    if (/[^0-9-]+/.test(value))
        return false;
	
    value = value.replace(/\D/g, "");
	
    var validTypes = 0x0000;
	
    if (param.mastercard)
        validTypes |= 0x0001;
    if (param.visa)
        validTypes |= 0x0002;
    if (param.amex)
        validTypes |= 0x0004;
    if (param.dinersclub)
        validTypes |= 0x0008;
    if (param.enroute)
        validTypes |= 0x0010;
    if (param.discover)
        validTypes |= 0x0020;
    if (param.jcb)
        validTypes |= 0x0040;
    if (param.unknown)
        validTypes |= 0x0080;
    if (param.all)
        validTypes = 0x0001 | 0x0002 | 0x0004 | 0x0008 | 0x0010 | 0x0020 | 0x0040 | 0x0080;
	
    if (validTypes & 0x0001 && /^(51|52|53|54|55)/.test(value)) { //mastercard
        return value.length == 16;
    }
    if (validTypes & 0x0002 && /^(4)/.test(value)) { //visa
        return value.length == 16;
    }
    if (validTypes & 0x0004 && /^(34|37)/.test(value)) { //amex
        return value.length == 15;
    }
    if (validTypes & 0x0008 && /^(300|301|302|303|304|305|36|38)/.test(value)) { //dinersclub
        return value.length == 14;
    }
    if (validTypes & 0x0010 && /^(2014|2149)/.test(value)) { //enroute
        return value.length == 15;
    }
    if (validTypes & 0x0020 && /^(6011)/.test(value)) { //discover
        return value.length == 16;
    }
    if (validTypes & 0x0040 && /^(3)/.test(value)) { //jcb
        return value.length == 16;
    }
    if (validTypes & 0x0040 && /^(2131|1800)/.test(value)) { //jcb
        return value.length == 15;
    }
    if (validTypes & 0x0080) { //unknown
        return true;
    }
    return false;
}, "Por favor un numero de tarjeta de credito valido.");

jQuery.validator.addMethod("requireddefault", function(value, element, param) {	
	return $.trim(value).length > 0 && value != param ;	
}, "Este campo es obligatorio.");

jQuery.validator.addMethod("requiredtextoenriquesido", function(value, element, param) {	
	var content = $(element).html();
	return $.trim(content).length > 0;	
}, "Este campo es obligatorio.");

