﻿/*
 * Global vars
 */
var error                 = false;
var errors                = '';
var subValidationError    = false;
var checkedFields         = new Array();
var radioButtonLists      = new Array();
var idsToValidate         = new Array();
var matchValue, requiredOnes, validationTypesLabels;

/*
 * On blur action event, validates the field
 */
function validate(element,elementValidationType,elementLabel) {
    error = false;
    errors = '';
    matchValue = new Object();
    requiredOnes = new Object();

    var i, tuple, validationType,
        validated = {},
        present = false;

    for (i = 0; i < checkedFields.length; ++i) {
        if (checkedFields[i].id in validated)
            continue;
        else
            validated[checkedFields[i].id] = true;
        if (element && checkedFields[i].id == element.id) {
            // update the element (fixes AJAX updating issues)
            checkedFields[i] = element;
            present = true;
        }
        tuple = getValidationTypeLabel(checkedFields[i]);
        for (validationType in tuple[1])
            val(validationType, getValue(checkedFields[i]), tuple[0]);
    }
    //Adding it to the array, so it will rechecked again
    if (!present && element) {
        checkedFields.push(element);
        if (elementValidationType && elementLabel){
            if (!(element.id in validationTypesLabels))
                validationTypesLabels[element.id] = [elementLabel, {}];
            validationTypesLabels[element.id][1][elementValidationType] = true;
        }
        tuple = getValidationTypeLabel(checkedFields[i]);
        for (validationType in tuple[1])
            val(validationType, getValue(checkedFields[i]), tuple[0]);
    }

    switchMessageBox();
}

/*
 * Try to find alternative value when element.value is undefined (e.g. for radioButtonLists)
 */
function getValue(element) {
    var inputs, value = '';
    if (element.value == undefined && (inputs = element.getElementsByTagName('input'))) {
        for (var j = 0; j < inputs.length && value == ''; ++j)
            if (inputs[j].checked)
                value = inputs[j].value;
    } else if (element.type == 'checkbox') {
        value = element.checked ? 'true' : '';
    } else {
        value = element.value;
    }
    return value;
}

/*
* Validates all fields that need it (called on submit)
*/
function validateAll() {
    var i, id, field, tuple, inChecked = {}, goodtogo = true;
    for (i = 0; i < checkedFields.length; ++i) {
        inChecked[checkedFields[i].id] = true;
    }
    for (i in idsToValidate) {
        id = idsToValidate[i];
        if (!(id in inChecked)) 
            checkedFields.push(document.getElementById(id));
    }
    for (i in radioButtonLists)
        checkedFields.push(document.getElementById(radioButtonLists[i]));
    validate();
    return !error && !subValidationError;
}

/*
* Validates the fields belonging to the provided ids
*/
function validateSome() {
    var i, id, field, tuple, inChecked = {}, goodtogo = true;
    for (i = 0; i < arguments.length; ++i) {
        inChecked[arguments[i]] = true;
    }
    checkedFields = [];
    for (i in idsToValidate) {
        id = idsToValidate[i];
        if (id in inChecked)
            checkedFields.push(document.getElementById(id));
    }
    for (i in radioButtonLists)
        checkedFields.push(document.getElementById(radioButtonLists[i]));
    validate();
    return !error && !subValidationError;
}

/*
* Get and return array containing the field's validation type and label
*/
function getValidationTypeLabel(fieldElement) {
    if (fieldElement.id in validationTypesLabels)
        return validationTypesLabels[fieldElement.id];
    // for supporting legacy code
    return [fieldElement.getAttribute('validationType'),fieldElement.getAttribute('label')];
}

/*
 * Refresh the list of form elements with validation errors (called after AJAX page reloads)
 */
function refreshErrorElements() {
    if (!document) return;
    for (var i in checkedFields) {
        checkedFields[i] = document.getElementById(checkedFields[i].id);
    }
}

/*
* Validates the value on the given type
*/
function val(validationType,value,fieldLabel){
    switch (validationType) {
        case 'required':
            if (!valRequired(value))
                addError(resources.VAL01, fieldLabel);
            break;
        case 'phoneNumber':
            if (!valPhoneNumber(value))
                addError(resources.VAL02, fieldLabel);
            break;
        case 'number':
            if (!valNumber(value))
                addError(resources.VAL02, fieldLabel);
            break;
        case 'decimalnumber':
            if (!valDecimalNumber(value))
                addError(resources.VAL02, fieldLabel);
            break;
        case 'email':
            if (!valEmail(value))
                addError(resources.VAL02, fieldLabel);
            break;
        case 'multipleEmail':
            if (!valMultipleEmail(value))
                addError(resources.VAL02, fieldLabel);
            break;
        case 'bankAccountNL':
            if (!valBankAccountNL(value))
                addError(resources.VAL02, fieldLabel);
            break;
        case 'kvk':
            if (!valKVKNumberNaive(value))
                addError(resources.VAL02, fieldLabel);
            break;
        case 'btw':
            if (!valBTWNumber(value))
                addError(resources.VAL02, fieldLabel);
            break;
        case 'date':
            if (!valDate(value))
                addError(resources.VAL02, fieldLabel);
            break;
        case 'imageUpload':
            if (!valImageUpload(value))
                addError(resources.VAL02, fieldLabel);
            break;
        case 'docUpload':
            if (!validateDocUpload(value))
                addError(resources.VAL02, fieldLabel);
            break;
        case 'mobileNumber':
            if (!valMobileNumber(value))
                addError(resources.VAL02, fieldLabel);
            break;
        case 'money':
            if (!valMoney(value))
                addError(resources.VAL02, fieldLabel);
            break;
        case 'BSN':
            if (!valBSN(value))
                addError(resources.VAL02, fieldLabel);
            break;
        case 'validateHTML':
            if (!valvalidateHTML(value))
                addError(resources.VAL02, fieldLabel);
            break;
        case 'requiredNumber':  // Deprecated. Use separate validators instead
            if (!valRequired(value)) {
                addError(resources.VAL01, fieldLabel);
            } else {
                if (!valNumber(value))
                    addError(resources.VAL02, fieldLabel);
            }
            break;
        case 'requiredEmail':  // Deprecated. Use separate validators instead
            if (!valRequired(value)) {
                addError(resources.VAL01, fieldLabel);
            } else {
                if (!valEmail(value))
                    addError(resources.VAL02, fieldLabel);
            }
            break;
        case 'requiredDate':  // Deprecated. Use separate validators instead
            if (!valRequired(value)) {
                addError(resources.VAL01, fieldLabel);
            } else {
                if (!valDate(value))
                    addError(resources.VAL02, fieldLabel);
            }
            break;
        case 'requiredMobileNumber':  // Deprecated. Use separate validators instead
            if (!valRequired(value)) {
                addError(resources.VAL01, fieldLabel);
            } else {
                if (!valMobileNumber(value))
                    addError(resources.VAL02, fieldLabel);
            }
            break;
        default:
            if (validationType.match('charlimit_')) {
                if (value.length > parseInt(validationType.slice(10), 10))
                    // too long
                    addError(resources.VAL04, fieldLabel);
            } else if (validationType.match('charminimum_')){
                var parsedInt;
                if (value.length != 0 && value.length < (parsedInt = parseInt(validationType.slice(12),10)))
                    // too short
                    addError(resources.VAL08.replace('{0}',parsedInt),fieldLabel);
            } else if (validationType.match('match_')) {
                if (!valMatching(value, validationType))
                    // not equal
                    addError(resources.VAL05, '');
            } else if (validationType.match('requiredOne_')) {
                if (!valRequiredOnes(value, validationType, fieldLabel))
                    // both fields are null or empty and have passed this point
                    addErrorMultipleFields(resources.VAL07, [requiredOnes['fieldlabel_0'], fieldLabel]);
            } else if (validationType.match('email_match')) {
                if (!valMatching(value, validationType))
                // both fields are null or empty and have passed this point
                    addError(resources.VAL09, '');
            } else {
                addError(resources.VAL02, '?');
            }
    }
}

/*
* Checks if values are equal
*/
function valMatching(value, validationType) {
    if (validationType in matchValue) {
        if (value == matchValue[validationType])
            return true;
        return false;
    }
    matchValue[validationType] = value;
    return true;
}

/*
* Checks if at least one value is set
*/
function valRequiredOnes(value, validationType, fieldLabel) {
    if (valRequired(value))
        return true;
    if (validationType in requiredOnes) {
        if (valRequired(requiredOnes[validationType]))
            return true;
        return false;
    }
    requiredOnes[validationType] = value;
    requiredOnes['fieldlabel_0'] = fieldLabel;
    return true;
}

/*
* Validates image file
*/
function valImageUpload(value){
    if(value.trim() === '')
        return true;
    
    var isoDateRe   = /\.(jpe?g|gif|png)$/i;
    
    return !!isoDateRe.exec(value);
}

/*
* Validates document file
*/
function validateDocUpload(value){
    if(value.trim() === '')
        return true;

    var strRegex = /\.(docx?|rtf)$/i;

    return !!strRegex.exec(value);
}

/*
* Returns false if the given value is empty or not
*/
function valRequired(value) {
    return !(value === undefined || value === null || value.toString().trim() === '');
    //return !!(value && value.trim() != '');
}

/*
* Checks if the given value is a valid BSN (using the "elfproef")
*/
function valBSN(value) {
    if (!valRequired(value))
        return true;
    value = (value + '').trim().replace(/[^0-9]/,'');
    if (value in {111111110:1,999999990:1,000000000:1})  // exceptions
        return false;
    if (!valNumber(value) || value.length != 9)
        return false;
    var i, result = 0;
    for (i = 0; i < 8; ++i)
        result += (parseInt(value[i],10) * (9 - i));
    return (result - parseInt(value[8],10)) % 11 == 0;
}

/*
* Checks if the given value is a valid BTW number (using the "elfproef")
*/
function valBTWNumber(value) {
    if (!valRequired(value))
        return true;
    value = value.replace(/[^NLB0-9]/ig, '');
    var match = value.match(/NL([0-9.]*?)B[0-9]+$/i);
    if (!match)
        return false;
    return valBSN(match[1]);
}

/*
* Checks if the given value is roughly a valid KVK number
*/
function valKVKNumberNaive(value) {
    return !valRequired(value) || /^\s*?[0-9]{6,9}\s*?$/.test(value);
}

function valvalidateHTML(value) {
    if (!valRequired(value))
        return true;
    return value.match(/^[^<^>]*$/) ? true : false;
}

/*
* Check if the value is a number
*/
function valNumber(value) {
    if (!valRequired(value))
        return true;
    return value.match(/^[0-9]+$/) ? true : false;
}

function valDecimalNumber(value) {
    if (!valRequired(value))
        return true;
   // return value.match(/[0-9][,][0-9]{2}$/) ? true : false;
    return value.match(/^([1-9]{1}[\d]{0,2}(\.[\d]{3})*(\,[\d]{0,2})?|[1-9]{1}[\d]{0,}(\,[\d]{0,2})?|0(\,[\d]{0,2})?|(\,[\d]{1,2})?)$/) ? true : false;
}

function valMoney(value) {
    if (!valRequired(value))
        return true;

    var moneyReg = new RegExp('^\$?[0-9]+(,[0-9]{3})*(\.[0-9]{2})?$');
    var matches = moneyReg.exec(value);

    return matches;
}

/*
* Check if the value is a number
*/
function valMobileNumber(value){
    if (!valRequired(value))
        return true;
        
    var IsoDateRe   = new RegExp('^316[1-9][0-9]{7}$');
    var matches     = IsoDateRe.exec(value);
    
    return matches;
}

/*
* Check if the value contains enough numerals to be a phone number
*/
function valPhoneNumber(value) {
    if (!valRequired(value))
        return true;

    return value.match(/^\+?([0-9].?){8,15}[0-9]$/);
}

/*
* Returns true if empty, or value contains exactly one e-mail address
*/
function valEmail(value) {
    return !valRequired(value) || /^[^ \t;,]+@[^ \t;,]+\.[^ \t;,]{2,4}$/.test(value);
}

/**
* Returns true if empty, or value contains at least 1 e-mail address
*/
function valMultipleEmail(value) {
    return !valRequired(value) || /\b[^ \t;,]+@[^ \t;,]+\.[^ \t;,]{2,4}\b/.test(value);
}

/*
* Validates the date
*/
function valDate(value){
    if (!valRequired(value))
        return true;
        
    var IsoDateRe   = new RegExp('^([0-9]{1,2})[-/]([0-9]{1,2})[-/]([0-9]{4})$');
    var matches     = IsoDateRe.exec(value);
    
    if (!matches)
        return false;    
  
  var composedDate = new Date(matches[3], (matches[2] - 1), matches[1]);

  return ((composedDate.getMonth() == (matches[2] - 1)) &&
          (composedDate.getDate() == matches[1]) &&
          (composedDate.getFullYear() == matches[3]));
}

/*
* Validates NL bank account numbers
*/
function valBankAccountNL(value) {
    if (!valRequired(value))
        return true;
    value = (value + '').trim().replace(/\./g, '');
    if (!valNumber(value))
        return false;
    if (value.length > 0 && value.length < 8)  // Postbank or giro
        return true;
    if (value in { 111111110: 1, 999999990: 1, 000000000: 1, 123456789: 1 })  // exceptions
        return false;
    if (!valNumber(value) || value.length != 9)
        return false;
    var i, result = 0;
    for (i = 9; i > 0; --i)
        result += i * parseInt(value[9-i], 10);
    return result % 11 == 0;
}

/*
* Add an error the list
*/
function addError(errorCode, fieldLabel) {
    error = true;
    errors += errorCode.replace('%[ITEM]%', fieldLabel) + '<br/>';
}

/*
* Add an error relating to multiple fields to the list
*/
function addErrorMultipleFields(errorCode, fieldLabelArray) {
    error = true;
    errors += errorCode.replace('%[ITEM]%', fieldLabelArray.join(', ')) + '<br/>';
}
 
/*
* show the messagebox
*/
function switchMessageBox(){
    var box     = getElementsByClassName('message_box', 'div');
    var text    = getElementsByClassName('message_error', 'td');
    var img     = getElementsByClassName('message_box_img', 'img');
    
    if(text[0] == undefined || text[0] == null){
        text = getElementsByClassName('message_info', 'td');
    }
    
    if(text[0] == undefined || text[0] == null){
        text = getElementsByClassName('message_complete','td');
    }

    if (error || subValidationError) {
        text[0].innerHTML          = '<strong>'+resources.errors+'</strong><br/>' + errors;
        box[0].style['display']    = 'block';
        img[0].src                 = '../images/icons/sign_error.png';
        text[0].className          = ' message_box_text message_error';
    }else{
        if(box[0].style['display'] != 'none'){
            text[0].innerHTML = '<strong>' + resources.validation + '</strong><br/>' + resources.noErrors + '<br/>';
            img[0].src         = '../images/icons/sign_info.png';
            text[0].className  = 'message_box_text message_info';
        }
    }    
}
 
/*
* Hide the messagebox
*/
function hideMessageBox() {
    getElementsByClassName('message_box', 'div')[0].style.display = 'none';
}
