// Using 120px for this demo.  However, we recommend using the default of 240px
cm_form_selector = 'form.cm-validate'; // Using global variable becuase we hacked stylish-select core to use our selector.

// Luhn
function cm_is_cc_number(s) {
    var i, n, c, r, t;

    // First, reverse the string and remove any non-numeric characters.    
    r = "";
    for (i = 0; i < s.length; i++) {
        c = parseInt(s.charAt(i), 10);
        if (c >= 0 && c <= 9) r = c + r;
    }
    
    // Check for a bad string.
    if (r.length <= 1) return false;
    
    // Now run through each single digit to create a new string. Even digits
    // are multiplied by two, odd digits are left alone.
    t = "";
    for (i = 0; i < r.length; i++) {
        c = parseInt(r.charAt(i), 10);
        if (i % 2 != 0) c *= 2;
        t = t + c;
    }
    
    // Finally, add up all the single digits in this string.
    n = 0;
    for (i = 0; i < t.length; i++) {
        c = parseInt(t.charAt(i), 10);
        n = n + c;
    }
    
    // If the resulting sum is an even multiple of ten (but not zero), the
    // card number is good.
    if (n != 0 && n % 10 == 0)
        return true;
    else
        return false;
}

function cm_validate_form(selector) { 
    if (!selector) return;
    // selector = '.form';

    var form = $(selector);
    var errors = '';

    // Fields:
    $(selector + ' .field').each(function(){
        var field = $(this);
        var field_input = field.find('.input');
        var field_input_id = field_input.attr('id');
        if (!field_input_id) return;
        
        // Set default only.
        if (!field.hasClass('error') && !field.hasClass('success')) { 
            if (!field.hasClass('default')) { 
                field.addClass('default');
            }
        }
        
        // Validate field:
        if (!cm_validate_form_field(selector, field_input_id)) errors++;
    });

    // No errors:
    if (!errors) { 
        // Submit:
        form.submit();
    }
}

function cm_validate_form_field(selector, field_id) { 
    var field_input = $(selector + ' #' + field_id);

    //ul contains the error from server side validation, when cm_validate_form_field is triggered hide it since we are now doing client side validation
    field_input.parent('.field').find('.tooltip ul').addClass('hide');

    var field_class = $(field_input).attr('class');
    if (!field_class) return true;

    var field_validate_class = field_class.match(/v-[^\s]+/); // Select "v- [](anything) ^(except) \s(a space) +(for one-to-many times.)"
    if (!field_validate_class) return true;

    field_validate_class = ""+field_validate_class+""; // Convert to string
    var field = field_input.parent('.field');
    
    var errors = 0;
    var validation = 0;

    // Set default only.
    if (!field.hasClass('error') && !field.hasClass('success')) { 
        if (!field.hasClass('default')) { 
            field.addClass('default');
            return;
        }
    }

    // if (field_validate_class == 'v-first-name') { alert('z'); }
    // Switch not working.
    
    switch(field_validate_class) { 
        // Validate Name(s):
        case 'v-name':
        case 'v-firstname':
        case 'v-lastname': 
        case 'v-username':
        case 'v-ccname':
        case 'v-address':
        case 'v-city':
        case 'v-country':
        case 'v-state':
        case 'v-company':
        
        case 'v-attentiveness':
        case 'v-experience':
        case 'v-courtesy': 
        case 'v-dedication':
        case 'v-marketing':
        
        case 'v-communities-served':
        case 'v-website':
        case 'v-types-of-properties':
            // Name(s) required:
            if (!field_input.val()) errors++;
            validation++;
        break;
        
        // Validate State
        case 'v-state':
        case 'v-province':
            if (!field_input.getSetSSValue()) errors++;
            validation++;
        break;

        case 'v-zip':
            // Zipcode required:
            if (!field_input.val()) errors++;

            // Canadian Zipcode(s):
            // var regex_zip = /[a-z]\d[a-z][\s-]?\d[a-z]\d/;

            // US Zipcode(s):
            var regex_zip = /\b[0-9]{5}(?:-[0-9]{4})?\b/;
            if (!regex_zip.test(field_input.val())) errors++;

            validation++;
        break;

        // Validate Email:
        case 'v-email':
            // Email required:
            if (!field_input.val()) errors++;

            // Email format:
            var regex_email = /[^@\s]+@\S+?\.\S+/;
            if (!regex_email.test(field_input.val())) errors++;
            validation++;
        break;
        
        // Validate Email - Confirm:
        case 'v-email-confirm':
            // Email required:
            if (!field_input.val()) errors++;

            // Email format:
            var regex_email = /[^@\s]+@\S+?\.\S+/;
            if (!regex_email.test(field_input.val())) errors++;

            // Email confirm:
            var field_input_email = $(selector + ' .v-email');
            if (field_input_email.val() != field_input.val()) errors++;

            validation++;
        break;
        
        // Validate Password:
        case 'v-password':
            // Password required:
            if (!field_input.val()) errors++;

            // Password format:
            var regex_pw = /[^\s]{6}/; // Allow [](anything) ^(except) \s(a space) {}(for range) 6(minimum 6 characters.)
            if (!regex_pw.test(field_input.val())) errors++;
            validation++;
        break;

        // Validate Password - Confirm:
        case 'v-password-confirm':
            // Password required:
            if (!field_input.val()) errors++;

            // Password format:
            var regex_pw = /[^\s]{6}/; // Allow [](anything) ^(except) \s(a space) {}(for range) 6(minimum 6 characters.)
            if (!regex_pw.test(field_input.val())) errors++;

            // Password confirm:
            var field_input_password = $(selector + ' .v-password');
            if (field_input_password.val() != field_input.val()) errors++;

            validation++;
        break;
        
        // Validate Phone:
        case 'v-phone':
            // Phone required:
            if (!field_input.val()) errors++;

            // Phone format:
            var regex_phone = /^\d{3}-\d{3}-\d{4}/; // Allow ###-###-####
            if (!regex_phone.test(field_input.val())) errors++;
            validation++;
        break;

        case 'v-profile-image':
            val = field_input.val();
            
            if (!field_input.val()) errors++;
            var accept = field_input.attr('accept');
            var regex_accept = new RegExp('(' + accept.replace(/,/g, '|') + ')$');
            if (!field_input.val().match(regex_accept)) errors++;
            
            validation++;
        break;
        
        // Payment fields
        // Validate CC Number:
        case 'v-ccnumber':
            // CC Number required:
            if (!field_input.val()) errors++;

            // CC Number format:
            var regex_cc = {
                visa:/^4\d{12}(\d\d\d){0,1}$/, // Visa
                mc:/^5[12345]\d{14}$/, // MasterCard
                amex:/^3[47][0-9]{13}$/ // Amex
            }

            // Check Amex - "Sorry, we don't accept American Express"
            var regex_cc_num = regex_cc.amex;
            if (regex_cc_num.test(field_input.val())) errors++;
            
            // Check Visa or Mastercard
            if (!errors) { 
                var regex_cc_visa = regex_cc.visa;
                var regex_cc_mc = regex_cc.mc;
                if (
                    !regex_cc_visa.test(field_input.val())
                    &&
                    !regex_cc_mc.test(field_input.val())
                ) errors++;
            }

            // Luhn check:
            if (!errors) { 
                // Luhn check:
                if (!cm_is_cc_number(field_input.val())) errors++;
            }

            validation++;
        break;

        // Validate CVV:
        case 'v-cccvv':
            // CVV required:
            if (!field_input.val()) errors++;

            // CVV format:
            var regex_cvv = /\d{3,4}/; // Allow [](anything) ^(except) \s(a space) {}(for range) 3(minimum 6 characters.) 4(maximum 4 characters)
            if (!regex_cvv.test(field_input.val())) errors++;
            validation++;
        break;

        // Validate Expiration:
        case 'v-ccexpyear':
            var date = new Date();
            var date_month = ""+date.getMonth()+""; // as "string" for substr() usage.
            var date_year = ""+date.getFullYear()+""; // as "string" for substr() usage.
            date_year = date_year.substr(2,4);
            var field_input_ccexpmonth = $(selector + ' .v-ccexpmonth');

            // Expired:
            if (+date_year == +field_input.getSetSSValue()) { // as "integer" (+) for math.
                if (+date_month > field_input_ccexpmonth.getSetSSValue()) errors++;
            }

            validation++;
        break;
        
        case 'v-ccexpmonth':
            // Current:
            var date = new Date();
            var date_month = ""+date.getMonth()+""; // as "string" for substr() usage.
            var date_year = ""+date.getFullYear()+""; // as "string" for substr() usage.
            date_year = date_year.substr(2,4);
            var field_input_ccexpyear = $(selector + ' .v-ccexpyear');

            // Expired:
            if (+date_year == +field_input_ccexpyear.getSetSSValue()) { // as "integer" (+) for math.
                if (+date_month > field_input.getSetSSValue()) errors++;
            }

            // Change/override field, to use "expiration year" validation tooltip.
            field_input = $(selector + ' #' + field_input_ccexpyear.attr('id'));
            field = field_input.parent('.field');

            validation++;
        break;

        case 'v-terms':
            // Current:
            if (field_input.prop('checked') == false) { 
                errors++;
            }

            validation++;
        break;

        default:
        break;
    }

    // If default, then skip validation.
    if (validation) { 
        if (field_input.val() == field_input.attr('placeholder')) errors++;
    }

    if (errors) { 
        // Styling divs.
        if (field.hasClass('default')) field.removeClass('default');
        if (field.hasClass('success')) field.removeClass('success');
        if (!field.hasClass('error')) field.addClass('error'); // Error

        return false;
    }
    else if (validation) { 
        if (field.hasClass('default')) field.removeClass('default');
        if (field.hasClass('error')) field.removeClass('error');
        if (!field.hasClass('success')) field.addClass('success'); // Success

        return true;
    }
    else {
        return true;
    }
}

function cm_initialize_form(param) { 
    if (!param.selector) return;
    var selector = param.selector;
    
     // Forms:
    $(selector).each(function() { 
        var form = $(this);
        var form_id = form.attr('id');

         // Fields:
        $('#'+form_id+' .field').each(function() { 
            var field = $(this);
            var field_label = field.find('label');
            var field_input = field.find('.input');
            if (!field_input.size()) { return; }
            var field_input_id = field_input.attr('id');
            if (!field_input_id) { alert('ERROR: Form field ('+field_input.attr('name')+') is missing ID'); }
    
            // Set default from current value.
            if (field_input.attr('placeholder') && field_input.attr('placeholder') == field_input.val()) { 
                field_input.addClass('default');
            }

            // Set mask
            if (field_input.attr('mask')) { 
                $("#"+field_input_id).mask(field_input.attr('mask')); 
            }

            // Events:
            // Select & File
            if (field_input.hasClass('select') || field_input.hasClass('file')) { 
                field_input.click(function(e) { cm_validate_form_field(selector, field_input_id); });
    
                $('#'+field_input_id).change(function(){
                    // Event:
                    cm_validate_form_field(selector, field_input_id);
                });
    
            }
            // Checkbox & Radio
            // NOTE: Change attr('type')=='checkbox' to hasClass('checkbox')
            else if (field_input.attr('type') == 'checkbox' || field_input.attr('type') == 'radio') {
               // Click:
               field_input.click(function(e) { 
                   // If value is empty, then restore default value.
                   cm_validate_form_field(selector, field_input_id); 
               });
            }
            // Other (Text, etc.)
            else { 
                // Events
    
                // Focus:
                field_input.focus(function(e) { 
                    // Replace default value with empty value, if it's a default value.
                    if (field_input.val() == field_input.attr('placeholder')) { 
                        field_input.val('');
                        field_input.removeClass('default');
                    }
    
                    cm_validate_form_field(selector, field_input_id); 
                });
    
                // Blur:
                field_input.blur(function(e) { 
                    // If value is empty, then restore default value.
    
                    cm_validate_form_field(selector, field_input_id); 
                });
    
                // Keyup
                field_input.keyup(function(e) { 
                    var code = (e.keyCode ? e.keyCode : e.which);
                    // If TAB or ENTER is pressed:
                    if (code == 9 || code == 13) return;
                    
                    cm_validate_form_field(selector, field_input_id); 
                });
            }
        });
    
        // Submit:
        $('#'+form_id+' .submit').click(function(e) { e.preventDefault(); cm_validate_form('#'+form_id); });
    });
}

$(function() { cm_initialize_form({selector:cm_form_selector}); });

