/*
Helder Internet FormValidation
31/08/07 v0.1
31/08/08 v0.2
25/07/09 v0.2.1
21/11/10 v0.3
16/05/11 v0.4: added maxlength check
*/

function formValidation_validationsObject()
{
    this.validations = {
        'required': {
            regexp: /^(.)+$/,
            defaultErrorMessage: 'required field'
        },
        'email': {
            regexp: /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9])+$/,
            defaultErrorMessage: 'invalid email address'
        },
        'zipcode': {
            regexp: /(\d{4}\s?[a-zA-Z]{2})/i,
            defaultErrorMessage: 'invalid zipcode'
        },
        'date': {
            func: function(value) {
                if (!value) {
                    return true;
                }
                var sep = value.replace(/[0-9\s]*/g, '').substring(0, 1);
                var dateArr = value.split(sep);
                if (dateArr.length != 3) {
                    return false;
                }
                var year, month, day;
                switch (sep) {
                    case '/':
                        // dd/mm/yyyy
                        year = dateArr[2];
                        month = dateArr[1];
                        day = dateArr[0];
                        break;
                    case '-':
                        // dd-mm-yyyy
                        year = dateArr[2];
                        month = dateArr[1];
                        day = dateArr[0];
                        break;
                }
                var testDate = new Date(year, month - 1, day)
                return (month == (testDate.getMonth() + 1) && day == testDate.getDate());
            },
            defaultErrorMessage: 'invalid date'
        },
        'time': {
            regexp: /^(([0-1]?[0-9])|([2][0-3])):([0-5]?[0-9])(:([0-5]?[0-9]))?$/i,
            defaultErrorMessage: 'invalid time'
        },
        'datetime': {
            func: function(value) {
                if (!value) {
                    return true;
                }
                var dateTimeArr = value.split(" ");
                if (dateTimeArr.length != 2) {
                    return false;
                }
                var validationsObject = new formValidation_validationsObject();
                if (!dateTimeArr[0] || !validationsObject.validations['date'].func(dateTimeArr[0])) {
                    return false;
                }
                if (!dateTimeArr[1] || !validationsObject.validations['time'].regexp.test(dateTimeArr[1])) {
                    return false;
                }
                return true;
            },
            defaultErrorMessage: 'invalid datetime'
        },
        'number': {
            regexp: /^[\d\.,]*$/i,
            defaultErrorMessage: 'invalid number'
        }
    }
}

function formValidation_validateOnSubmit(form, configObject)
{
    if (configObject)
    {
        var rules = configObject.getRules();
        var validationsObject = new formValidation_validationsObject();
        var errors = [];

        // remove error messages
        if (rules && rules.length > 0)
        {
            for (var x = 0; x < rules.length; x++)
            {
                var rule = rules[x];
                if (rule && rule.name && form.elements[rule.name])
                {
                    if (rule.errorElementId)
                    {
                        if (document.getElementById && document.getElementById(rule.errorElementId))
                        {
                            var elm = document.getElementById(rule.errorElementId);
                            if (typeof (elm.innerText) != 'undefined')
                            {
                                elm.innerText = '';
                            }
                            else if (typeof (elm.textContent) != 'undefined')
                            {
                                elm.textContent = '';
                            }
                        }
                    }
                }
            }
        }

        // check rules
        if (rules && rules.length > 0)
        {
            for (var x = 0; x < rules.length; x++)
            {
                var rule = rules[x];
                if (rule && rule.check)
                {
                    // check dependent of other element?
                    if (typeof (rule.depends_on) == 'string' && rule.depends_on != "")
                    {
                        var dependsOn = String(rule.depends_on);
                        dependsOnArr = dependsOn.split(",");
                        var dependendElement = "";
                        var requiredValue = "";
                        if (dependsOnArr && dependsOnArr.length == 2)
                        {
                            dependendElement = form.elements[dependsOnArr[0]];
                            requiredValue = dependsOnArr[1];
                        }
                        if (requiredValue == 'CHECKED')
                        {
                            // rule only applies when checkbox is checked
                            if (!dependendElement.checked)
                            {
                                continue;
                            }
                        }
                        else if (requiredValue == 'UNCHECKED')
                        {
                            // rule only applies when checkbox isn't checked
                            if (dependendElement.checked)
                            {
                                continue;
                            }
                        }
                        else if (formValidation_getValue(dependendElement) != requiredValue)
                        {
                            // rule only applies when value of depend object matches
                            continue;
                        }
                    }

                    var check = rule.check;
                    if (typeof (check) == 'string' && check.indexOf("(") == -1) // standaard check, geen custom functie
                    {
                        var check = validationsObject.validations[rule.check];
                        if (check)
                        {
                            if (rule.name && form.elements[rule.name])
                            {
                                var value = formValidation_getValue(form.elements[rule.name]); //form.elements[ rule.name ].value || '';
                                if (!value && rule.check != 'required')
                                {
                                    continue;
                                }
                                if ( check.regexp )
                                {
                                    if (!check.regexp.test(value))
                                    {
                                        // invalid value
                                        if (!rule.errorMessage)
                                        {
                                            if (configObject.defaultErrorMessage)
                                            {
                                                rule.errorMessage = configObject.defaultErrorMessage;
                                            }
                                            else if (check.defaultErrorMessage)
                                            {
                                                rule.errorMessage = check.defaultErrorMessage;
                                            }
                                        }
                                        errors.push(rule);
                                    }
                                }
                                else if (check.func)
                                {
                                    if (!check.func(value)) {
                                        //invalid value
                                        if (!rule.errorMessage) {
                                            if (configObject.defaultErrorMessage) {
                                                rule.errorMessage = configObject.defaultErrorMessage;
                                            }
                                            else if (check.defaultErrorMessage) {
                                                rule.errorMessage = check.defaultErrorMessage;
                                            }
                                        }
                                        errors.push(rule);
                                    }
                                }
                            }
                        }
                        else
                        {
                            systemError("formValidation config error: unknown check supplied: '" + rule.check + "'");
                        }
                    }
                    else if (typeof (check) == 'string' && check.indexOf("(") > -1)
                    {
                        try
                        {
                            if (!eval(rule.check))
                            {
                                if (!rule.errorMessage)
                                {
                                    if (configObject.defaultErrorMessage)
                                    {
                                        rule.errorMessage = configObject.defaultErrorMessage;
                                    }
                                    else
                                    {
                                        systemError("formValidation config error: missing error message for: '" + rule.check + "'");
                                    }
                                }
                                errors.push(rule);
                            }
                        }
                        catch (e)
                        {
                            if (String(e.description || '').indexOf('Object') > -1)
                            {
                                systemError("formValidation config error: unknown check supplied: '" + rule.check + "'");
                            }
                            else
                            {
                                systemError(e.description);
                            }
                        }
                    }
                    else if (typeof (check) == 'object')
                    {
                        try
                        {
                            if (!rule.check())
                            {
                                if (!rule.errorMessage)
                                {
                                    if (configObject.defaultErrorMessage)
                                    {
                                        rule.errorMessage = configObject.defaultErrorMessage;
                                    }
                                    else
                                    {
                                        systemError("formValidation config error: missing error message for: '" + rule.check + "'");
                                    }
                                }
                                errors.push(rule);
                            }
                        }
                        catch (e)
                        {
                            if (String(e.description || '').indexOf('Object') > -1)
                            {
                                systemError("formValidation config error: unknown check supplied: '" + rule.check + "'");
                            }
                            else
                            {
                                systemError(e.description);
                            }
                        }
                    }
                }
                else
                {
                    systemError("formValidation config error: no check attribute supplied");
                }
            }
        }

        // shows errors
        if (errors && errors.length > 0)
        {
            var focusElm = null;
            var alertMessage = null;
            for (var x = 0; x < errors.length; x++)
            {
                var error = errors[x];
                if (error)
                {
                    var message = error.errorMessage || '';
                    if (error.errorElementId && document.getElementById(error.errorElementId))
                    {
                        if (document.getElementById)
                        {
                            var elm = document.getElementById(error.errorElementId);
                            if (typeof (elm.innerText) != 'undefined')
                            {
                                elm.innerText = message;
                            }
                            else if (typeof (elm.textContent) != 'undefined')
                            {
                                elm.textContent = message;
                            }
                        }
                    }
                    else
                    {
                        if (!focusElm && !alertMessage)
                        {
                            // only show alert message when there's no previous object with focus and errorMessageElement
                            alertMessage = message;
                        }
                    }
                    if (error.name && form.elements[error.name] && !focusElm)
                    {
                        focusElm = form.elements[error.name];
                    }
                }
            }
            if (alertMessage)
            {
                alert(alertMessage);
            }
            if (focusElm)
            {
                try
                {
                    focusElm.focus();
                }
                catch (e)
                {
                    //
                }
            }
            return false;
        }
    }
    return true;
}

function formValidation_validateOnBlur(element, configObject)
{
    if (configObject)
    {
        var rules = configObject.getRules();
        var validationsObject = new formValidation_validationsObject();
        var errors = [];

        // remove error messages
        if (rules && rules.length > 0)
        {
            for (var x = 0; x < rules.length; x++)
            {
                var rule = rules[x];
                if (rule && rule.name && rule.name == element.name && rule.errorElementId)
                {
                    if (document.getElementById && document.getElementById(rule.errorElementId))
                    {
                        var elm = document.getElementById(rule.errorElementId);
                        // PB 5/10/2008: alleen onblur meldingen tonen als er iets is ingevuld.
                        if (typeof (elm.innerText) != 'undefined' && formValidation_getValue(element) != '')
                        {
                            elm.innerText = '';
                        }
                        else if (typeof (elm.textContent) != 'undefined' && formValidation_getValue(element) != '')
                        {
                            elm.textContent = '';
                        }
                    }
                }
            }
        }

        // check rules
        if (rules && rules.length > 0)
        {
            for (var x = 0; x < rules.length; x++)
            {
                var rule = rules[x];
                if (rule && rule.check)
                {
                    if (rule.name && rule.name == element.name)
                    {
                        var check = rule.check;
                        if (typeof (check) == 'string' && check.indexOf("(") == -1) // standaard check, geen custom functie
                        {
                            var check = validationsObject.validations[rule.check];
                            var value = formValidation_getValue(element);
                            if (!value && rule.check != 'required') {
                                continue;
                            }
                            if (check.regexp) {
                                if (check.regexp && !check.regexp.test(value))
                                {
                                    // invalid value
                                    if (!rule.errorMessage)
                                    {
                                        if (configObject.defaultErrorMessage)
                                        {
                                            rule.errorMessage = configObject.defaultErrorMessage;
                                        }
                                        else if (check.defaultErrorMessage)
                                        {
                                            rule.errorMessage = check.defaultErrorMessage;
                                        }
                                    }
                                    errors.push(rule);
                                }
                            }
                            else if (check.func)
                            {
                                if (!check.func(value))
                                {
                                    //invalid value
                                    if (!rule.errorMessage)
                                    {
                                        if (configObject.defaultErrorMessage)
                                        {
                                            rule.errorMessage = configObject.defaultErrorMessage;
                                        }
                                        else if (check.defaultErrorMessage)
                                        {
                                            rule.errorMessage = check.defaultErrorMessage;
                                        }
                                    }
                                    errors.push(rule);
                                }
                            }
                        }
                        else if (typeof (check) == 'string' && check.indexOf("(") > -1)
                        {
                            try
                            {
                                if (!eval(rule.check))
                                {
                                    if (!rule.errorMessage)
                                    {
                                        if (configObject.defaultErrorMessage)
                                        {
                                            rule.errorMessage = configObject.defaultErrorMessage;
                                        }
                                        else
                                        {
                                            systemError("formValidation config error: missing error message for: '" + rule.check + "'");
                                        }
                                    }
                                    errors.push(rule);
                                }
                            }
                            catch (e)
                            {
                                if (String(e.description || '').indexOf('Object') > -1)
                                {
                                    systemError("formValidation config error: unknown check supplied: '" + rule.check + "'");
                                }
                                else
                                {
                                    systemError(e.description);
                                }
                            }
                        }
                        else if (typeof (check) == 'object')
                        {
                            try
                            {
                                if (!rule.check())
                                {
                                    if (!rule.errorMessage)
                                    {
                                        if (configObject.defaultErrorMessage)
                                        {
                                            rule.errorMessage = configObject.defaultErrorMessage;
                                        }
                                        else
                                        {
                                            systemError("formValidation config error: missing error message for: '" + rule.check + "'");
                                        }
                                    }
                                    errors.push(rule);
                                }
                            }
                            catch (e)
                            {
                                if (String(e.description || '').indexOf('Object') > -1)
                                {
                                    systemError("formValidation config error: unknown check supplied: '" + rule.check + "'");
                                }
                                else
                                {
                                    systemError(e.description);
                                }
                            }
                        }
                    }
                }
                else
                {
                    systemError("formValidation config error: no check attribute supplied");
                }
            }
        }

        // shows errors
        if (errors && errors.length > 0)
        {
            var focusElm = null;
            var alertMessage = null;
            for (var x = 0; x < errors.length; x++)
            {
                var error = errors[x];
                if (error)
                {
                    var message = error.errorMessage || '';
                    if (error.errorElementId)
                    {
                        if (document.getElementById && document.getElementById(error.errorElementId))
                        {
                            var elm = document.getElementById(error.errorElementId);
                            // PB 5/10/2008: alleen onblur meldingen tonen als er iets is ingevuld.
                            if (typeof (elm.innerText) != 'undefined' && formValidation_getValue(element) != '')
                            {
                                elm.innerText = message;
                            }
                            else if (typeof (elm.textContent) != 'undefined' && formValidation_getValue(element) != '')
                            {
                                elm.textContent = message;
                            }
                        }
                    }
                    else
                    {
                        if (!alertMessage)
                        {
                            alertMessage = message;
                        }
                    }
                }
            }
            if (alertMessage)
            {
                alert(alertMessage);
            }
        }
    }
}
function formValidation_getValue(el)
{
    var r = "";

    switch (el.type)
    {
        case 'text':
        case 'button':
        case 'submit':
        case 'password':
        case 'textarea':
        case 'hidden':
            r = String(el.value || '').replace(/(\s+)/ig, " ");  //bugfix: enters in textarea gaven problemen
            break;
        case 'checkbox':
            if (el.checked == true)
            {
                r = el.value || '';
            }
            break;
        case 'select-one':
            if (el.options.selectedIndex > -1)
            {
                if (typeof(el.options[el.options.selectedIndex].value) == 'undefined')
                {
                    r = el.options[el.options.selectedIndex].text;
                }
                else
                {
                    r = el.options[el.options.selectedIndex].value;
                }
            }
            break;
        default:
            // radio button
            if (typeof (el.length) != 'undefined')
            {
                for (var x = 0; x < el.length; x++)
                {
                    if (el[x].checked == true)
                    {
                        r = el[x].value || '';
                    }
                }
            }
            else if (el.checked == true)
            {
                r = el.value || '';
            }
            break;
    }
    return r;
}

function formValidation_maxLength(el) {
    var maxlength = el.getAttribute ? parseInt(el.getAttribute("maxlength")) : "";
    if (el.getAttribute && el.value.length > maxlength) el.value = el.value.substring(0, maxlength);
}

function formValidation_configObject()
{
    var rules = [];
    this.defaultErrorMessage = '';

    this.addRule = function(paramObject)
    {
        rules.push(paramObject);
    }

    this.getRules = function()
    {
        return rules;
    }
}

function systemError(s)
{
    alert(s);
}

function formValidation_saveOnExit(formName, func) 
{
    this.formName = formName;
    this.func = func;
    origValues = new Object();

    var f = document.forms[this.formName];
    for (var i = 0; i < f.elements.length; i++) 
    {
        origValues[f.elements[i].name] = formValidation_getValue(f.elements[i]);
    }

    this.valuesChanged = function (event) 
    {
        var f = document.forms[formName];
        for (var i = 0; i < f.elements.length; i++) 
        {
            if (formValidation_getValue(f.elements[i]) != origValues[f.elements[i].name]) 
            {
                if (func() == false) 
                {
                    event = event || window.event;

                    // Cancelling bubbling:    
                    if (event.stopPropagation) 
                    {
                        // DOM standard        
                        event.stopPropagation();
                    }
                    else 
                    {
                        // Older mechanism        
                        event.cancelBubble = true;
                    }

                    // Preventing default action:    
                    if (event.preventDefault) 
                    {
                        // DOM standard        
                        event.preventDefault();
                    }
                    else 
                    {
                        // Older mechanism        
                        event.returnValue = false;
                    }

                    return false;
                }
            }
        }
        return true;
    }
}
