
(function($){
    /*
     * String extensions to handle creditcard validations * * * * * * * * * * * * *
     */
    String.prototype.testLuhn = function(){
        var number = this.replace(/\D/g, '');
        var number_length = number.length;
        var parity = number_length % 2;
        var total = 0;
        
        for (i = 0; i < number_length; i++) {
            var digit = number.charAt(i);
            if (i % 2 == parity) {
                digit = digit * 2;
                if (digit > 9) {
                    digit = digit - 9;
                }
            }
            total = total + parseInt(digit);
        }
        if (total % 10 == 0) {
            return true;
        }
        else {
            return false;
        }
    }
    String.prototype.test_visa = function(){
        var cardNumber = this.replace(/(\d)([\s\-])(\d)/g, '$1$3');
        return /^4\d{12}(\d{3})?$/.test(cardNumber) && cardNumber.testLuhn();
    }
    String.prototype.test_mastercard = function(){
        var cardNumber = this.replace(/(\d)([\s\-])(\d)/g, '$1$3');
        return /^5[1-5]\d{14}$/.test(cardNumber) && cardNumber.testLuhn();
    }
    String.prototype.test_americanexpress = function(){
        var cardNumber = this.replace(/(\d)([\s\-])(\d)/g, '$1$3');
        return /^3[47]\d{13}$/.test(cardNumber) && cardNumber.testLuhn();
    }
    
    //Retorna: 1 = NIF ok, 2 = CIF ok, -1 = NIF error, -2 = CIF error, 0 = ??? error
    function valida_nif_cif(a){
    
        var temp = a.toUpperCase();
        var cadenadni = 'TRWAGMYFPDXBNJZSQVHLCKE';
        var suma, letra, posicion, letradni, temp, temp1, temp2;
        if (temp !== '') {
        
            //si no tiene un formato valido devuelve error
            if ((!/^[A-Z]{1}[0-9]{7}[A-Z0-9]{1}$/.test(temp) && !/^[T]{1}[A-Z0-9]{8}$/.test(temp)) && !/^[0-9]{8}[A-Z]{1}$/.test(temp)) {
                return 0;
            }
            
            //comprobacion de NIFs estandar
            if (/^[0-9]{8}[A-Z]{1}$/.test(temp)) {
                posicion = a.substring(8, 0) % 23;
                letra = cadenadni.charAt(posicion);
                letradni = temp.charAt(8);
                if (letra == letradni) {
                    return 1;
                }
                else {
                    return -1;
                }
            }
            
            //algoritmo para comprobacion de codigos tipo CIF
            suma = parseInt(a.charAt(2)) + parseInt(a.charAt(4)) + parseInt(a.charAt(6));
            
            for (i = 1; i < 8; i += 2) {
                temp1 = 2 * parseInt(a.charAt(i));
                temp1 += '';
                temp1 = temp1.substring(0, 1);
                temp2 = 2 * parseInt(a.charAt(i));
                temp2 += '';
                temp2 = temp2.substring(1, 2);
                if (temp2 == '') {
                    temp2 = '0';
                }
                
                suma += (parseInt(temp1) + parseInt(temp2));
            }
            suma += '';
            n = 10 - parseInt(suma.substring(suma.length - 1, suma.length));
            
            //comprobacion de NIFs especiales (se calculan como CIFs)
            if (/^[KLM]{1}/.test(temp)) {
                if (a.charAt(8) == String.fromCharCode(64 + n)) {
                    return 1;
                }
                else {
                    return -1;
                }
            }
            //comprobacion de CIFs
            if (/^[ABCDEFGHJNPQRSUVW]{1}/.test(temp)) {
                temp = n + '';
                if (a.charAt(8) == String.fromCharCode(64 + n) || a.charAt(8) == parseInt(temp.substring(temp.length - 1, temp.length))) {
                    return 2;
                }
                else {
                    return -2;
                }
            }
        }
        return 0;
    }
    
    
    // custom methods
    // letters and spaces
    jQuery.validator.addMethod("wordsonly", function(value, element){
        return this.optional(element) || /^[a-zá-úà-ùä-üâ-ûñç·\s]+$/i.test(value);
    }, $.validator.messages.valid);
	
    // numbers and spaces
    jQuery.validator.addMethod("numbersonly", function(value, element){
        return this.optional(element) || /^[\d\s]+$/i.test(value);
    }, $.validator.messages.valid);
    
    // nif/cif
    jQuery.validator.addMethod("nifcif", function(value, element){
        var validationCode = valida_nif_cif(value);
        return this.optional(element) || validationCode === 1 || validationCode === 2;
    }, $.validator.messages.valid);
    
    // credit card expiry date year (we validate this one because it is the last of the two
    $.validator.addMethod('cardExpiryYear', function(value, element, param){
        //var bool = new Date(value, parseInt($(param).val(), 10)) > new Date();
        // JSL (25/01/2012)
        var bool = new Date(element.options[element.selectedIndex].text, parseInt($(param).val(), 10)) > new Date();
	
	$(param)[bool ? 'removeClass' : 'addClass']('error');
        return bool;
    }, $.validator.messages.date);
    
    
    // later date than...
    $.validator.addMethod('laterThan', function(value, element, param){
        var sooner = false, later = false;
        try {
            sooner = $.datepicker.parseDate($.datepicker._defaults.dateFormat, $(param).val());
            later = $.datepicker.parseDate($.datepicker._defaults.dateFormat, value);
        } 
        catch (e) {
        };
        return !value || !sooner || (sooner && later && later > sooner);
    }, $.validator.messages.date);
    
    // credit card depending on another value
    $.validator.addMethod('conditionalCreditCard', function(value, element, param){
        // el parametro debe ser un input o select del cual dependera el tipo de validacion
        var creditcardtype = $(param).val().toLowerCase();
        return value[['test_', creditcardtype].join('')]();
    }, $.validator.messages.creditcard);
    
    // extension
    HttpCom.extensions.genericFormValidation = function(scope){
        $("#footer-nav form", scope).validate();
    }
    
})(jQuery);

