Array.prototype.clear=function()
{
    this.length = 0;
};

Array.prototype.contains = function (element) 
{
    for (var i = 0; i < this.length; i++) 
    {
        if (this[i] == element) 
        {
            return true;
        }
    }
    return false;
};

var strFormErrorMessage = "";
var checkedCheckboxes = new Array();
var strLastCheckedRadio = "";
var firstObj = null;

function validateForm(Form)
{
    var strRequired = "";
    var strRequiredType = "";
    var blnNeedsChecking;
    
    firstObj = null;
    // Clear array
    checkedCheckboxes.clear();
    
    strFormErrorMessage = "";
    
    //check every element on the form
    for (var i=0; i<Form.length; i++)
    {
        if (Form[i].getAttribute("REQUIRED") != null)
        {
            strRequired = Form[i].getAttribute("REQUIRED");
            strRequiredType = Form[i].getAttribute("REQUIRED_TYPE");
            strName = Form[i].name;
            blnNeedsChecking = false;
            if (strRequired != null)
            {
                if ((strRequired.toLowerCase() == "true") || (strRequired.toLowerCase() == "optional"))
                {
                    blnNeedsChecking = true;
                }
            }
            if (checkedCheckboxes.contains(strName)==false)
            {
                if (Form[i].nodeName.toLowerCase()=='input')
                {
                    checkedCheckboxes.push(strName);
                }
            }
            else
            {
                blnNeedsChecking = false;
            }
            //check wether an VALIDATED-Attribute exists
            if (blnNeedsChecking == true)
            {
                checkControl(Form, Form[i]);
            }
        }
    }

    // show the actual error messages
    valForm_ShowErrorMessage(Form);
    if (firstObj!=null)
    {
        try
        {
            firstObj.focus();
        }
        catch (e)
        {
            // error
            window.console("error");
        }
    }

    // first check if there are no more error messages, so the final submit is coming up
    if (strFormErrorMessage.length == 0)
    {
        // add a hidden input for all unchecked checkboxes
        valForm_FixCheckBoxes(Form);
    }
    
    return (strFormErrorMessage.length > 0 ? false : true);
}
    
function checkControl(form, obj)
{
    var strValue = "";
    var strErrorMsg = obj.getAttribute("ERRORMSG");
    var required = obj.getAttribute("REQUIRED");
    var type = obj.getAttribute("REQUIRED_TYPE");
    var re = "";

    if ((required.toLowerCase() == "true") || (required.toLowerCase() == "optional"))
    {
        //make sure a filled optional text-box is cleared
        if ((required.toLowerCase() == "optional") && (obj.value == ""))
        {
            valForm_SetOK(form, obj);
        }
        else
        {

            switch (type.toLowerCase())
            {
                case "text":
                    if (obj.value == "")
                    {
                        valForm_SetError(form, obj);
                    }
                    else
                    {
                        valForm_SetOK(form, obj);
                    }
                    break;
                case "dutchzip":
                    valForm_formatDutchZip(obj);
                    //read new value
                    strValue = obj.value;
                    re = /^[0-9]{4}\s{0,1}[a-zA-Z]{2}$/; 
                    if (valForm_doRegularExpression(re,strValue)== false) 
                    {
                        valForm_SetError(form, obj);
                    }
                    else
                    {
                        valForm_SetOK(form, obj);
                    }
                    break;
                case "phonenumber":
                    //only NUMERIC KEYS, (, ) , * , +, -,# and spaces are allowed
                    strValue = obj.value;
                    re = /^[\d\(\)\-\+\*\# ]+$/;
                    if (valForm_doRegularExpression(re,strValue)== false) 
                    {
                        valForm_SetError(form, obj);
                    }
                    else
                    {
                        valForm_SetOK(form, obj);
                    }
                    break;
                case "numeric":
                    strValue = obj.value;
                    re = /^[0-9]+$/;
                    if (valForm_doRegularExpression(re,strValue)== false) 
                    {
                        valForm_SetError(form, obj);
                    }
                    else
                    {
                        valForm_SetOK(form, obj);
                    }
                    break;
                case "password":
                    strValue = obj.value;
                    re = /(?=^.{8,30}$)(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[!@#$%^&*()_+}{"":;'?/>.<,]).*$/;
                    if (valForm_doRegularExpression(re,strValue)== false) 
                    {
                        valForm_SetError(form, obj);
                    }
                    else
                    {
                        valForm_SetOK(form, obj);
                    }
                    break;
                case "email":
                    //check if the email address is valid
                    strValue = obj.value;
                    re = /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,6})+$/;
                    if (valForm_doRegularExpression(re,strValue)== false) 
                    {
                        valForm_SetError(form, obj);
                    }
                    else
                    {
                        valForm_SetOK(form, obj);
                    }
                    break;
                case "dd/mm/yyyy":
                    //check if date is valid for the format: DD/MM/YYYY
                    //If D or M is supplied, a preceding 0 will be automatically added.
                    //YYYY should have four digits
                    //allowed separation chars: '/','-','.',' '(space)
                    //All separation chars will be replaced by a '/'
                    valForm_formatDate(obj);
                    if (CheckDate(obj.value,'dd/mm/yyyy')== false) {
                        valForm_SetError(form, obj);
                    }
                    else
                    {
                        valForm_SetOK(form, obj);
                    }
                    break;
                    //arSupportedTypes[0] = "hh:mm"
                    //arSupportedTypes[2] = "mm/dd/yyyy"
                case "select":
                    if (obj.value == "")
                    {
                        valForm_SetError(form, obj);
                    }
                    else
                    {
                        valForm_SetOK(form, obj);
                    }
                    break;
                case "check":
                    var checks = document.getElementsByName(obj.name);
                    if (chkFrm_isOneCheckboxSelected(checks))
                    {
                        valForm_SetOK(form, obj);
                    }
                    else
                    {
                        valForm_SetError(form, obj);
                    }
                    break;
                case "radio":
                    var radios = document.getElementsByName(obj.name);
                    if (obj.name != strLastCheckedRadio) 
                    {
                        //This radiobuttongroup is not checked yet
                        strLastCheckedRadio = obj.name;
                        if (!(chkFrm_isOneRadioButtonSelected(radios))) 
                        {
                            valForm_SetError(form, obj);
                        }
                        else
                        {
                            valForm_SetOK(form, obj);
                        }
                    }
                    break;
                default:
                    break;
            }
        }
    }
}

function valForm_FixCheckBoxes(Form)
{
    var newElement = null;
    
    //check every checkbox
    for (var i=0; i<Form.length; i++)
    {
        if ((Form[i].tagName!="FIELDSET") && (Form[i].type.toLowerCase() == "checkbox"))
        {
            //when a checkbox is not checked...
            if (Form[i].checked == false)
            {
                //create a hidden input-box and put the alternative value in it...
                //because a non-checked checkbox is not submitted with the form...
                newElement = document.createElement("INPUT");
                newElement.type = "hidden";
                newElement.name = Form[i].name;
                newElement.value = Form[i].getAttribute("ALTERNATIVEVALUE");
                
                //add the hidden text-box in the DOM-hierarchy...
                if (Form[i].nextSibling)
                {
                    if (Form[i].nextSibling.nodeName.toUpperCase() == "#TEXT")
                    {
                        Form[i].parentNode.appendChild(newElement);
                    }
                    else
                    {
                        Form[i].nextSibling.insertBefore(newElement);
                    }
                }
                else
                {
                    Form[i].parentNode.appendChild(newElement);
                }
            }
        }
    }
}

function ResetForm(Form)
{
    //check every element on the form
    for (var i=0; i<Form.length; i++)
    {
        if (Form[i].getAttribute("REQUIRED") != null)
        {
            valForm_SetOK(Form, Form[i]);
        }
    }
}

function valForm_SetOK(form, obj)
{
    if (obj.getAttribute("normalClass") != null)
    {
        obj.className = obj.getAttribute("normalClass");
        obj.removeAttribute("normalClass", false);
    }
}

function valForm_SetError(form, obj)
{
    var strErrorType = (form.getAttribute("ERRORTYPE")) ? form.getAttribute("ERRORTYPE") : "";
    //append to the error message, depending on the errortype
    switch (strErrorType.toLowerCase())
    {
        case "alertandinputboxes":
            strFormErrorMessage += obj.getAttribute("ERRORMSG") + "\n";
            if (obj.getAttribute("normalClass") == null)
            {
                obj.setAttribute("normalClass", obj.className, 0);
                obj.className = obj.getAttribute("ERRORCLASS");
            }
            if (firstObj==null) firstObj=obj;
            break;
        case "alert":
            strFormErrorMessage += obj.getAttribute("ERRORMSG") + "\n";
            if (firstObj==null) firstObj=obj;
            break;
        case "div":
            strFormErrorMessage += obj.getAttribute("ERRORMSG") + "<BR>";
            break;
        case "inputboxes":
            strFormErrorMessage = " ";
            //put the classname in a new attribute and put the classname to the errorclass
            if (obj.getAttribute("normalClass") == null)
            {
                obj.setAttribute("normalClass", obj.className, 0);
                obj.className = obj.getAttribute("ERRORCLASS");
            }
            break;
        case "":
            strFormErrorMessage = " ";
            break;
        default:
            break;
    }
}

function valForm_ShowErrorMessage(form)
{
    var strErrorMsgDivID = "";
    var strErrorType = (form.getAttribute("ERRORTYPE")) ? form.getAttribute("ERRORTYPE") : "";
    var strErrorMsgDivID = (form.getAttribute("ERRORDIV")) ? form.getAttribute("ERRORDIV") : "";

    var errorDiv = ((strErrorMsgDivID != "") ? document.getElementById(strErrorMsgDivID) : null);
    
    if (strFormErrorMessage.length > 0)
    {
        switch (strErrorType.toLowerCase())
        {
            case "alertandinputboxes":
                alert(strFormErrorMessage);
                break;
            case "alert":
                alert(strFormErrorMessage);
                break;
            case "div":
                if (errorDiv != null)
                {
                    errorDiv.innerHTML = strFormErrorMessage;
                    errorDiv.style.display = "inline";
                }
                else
                {
                    alert("Please set the Form-attribute: \"ERRORDIV\" to hold the ID of the DIV that will display the errormessage!");
                }
                break;
            case "inputboxes":
                break;
            case "":
                alert("Please set the Form-attribute: \"ERRORTYPE\" to one of the following values: \"alert\", \"div\" or \"inputboxes\" ");
                break;
            default:
                break;
        }
/*        var obj = document.getElementById("FormCheckerError");
        obj.innerHTML = strFormErrorMessage;
        obj.style.display = "block";*/
    }
    else
    {
        switch (strErrorType.toLowerCase())
        {
            case "div":
                errorDiv.innerHTML = "";
                errorDiv.style.display = "none";
                break;
            default:
                break;
        }
    }
}

function valForm_formatDutchZip(obj) 
{
    //remove all spaces
    obj.value = obj.value.replace(/ /g,'')
    //upperCase value
    obj.value = obj.value.toUpperCase();
}

function valForm_doRegularExpression(re, strWhat) 
{
    return (re.test(strWhat) == true);
}

function valForm_formatDate(objField) {
    //replace all spaces, dots and stripes with a slash '/'
    objField.value = objField.value.replace(/[\. \-]/g,'/')
    var arValue = objField.value.split("/")
    var strTmpvalue = '';
    var i;
    if (arValue.length == 3) {
        //two slashes are found
        //Make sure the values have a preceding 0, except the last element
        for (i=0;i<arValue.length-1;i++){
            if (arValue[i].length < 2) {
                arValue[i] = '0' + arValue[i]
            }
        }
        //The last element should have 4 characters (==year)
        while (arValue[arValue.length-1].length < 4) {
            //Ad an x until the length is at least 4 chars
            arValue[arValue.length-1] = 'x' + arValue[arValue.length-1]
        }
        
        //save array data into a string
        for (i=0;i<arValue.length;i++){
            strTmpvalue += arValue[i] + '/'
        }
        //Remove last slash
        if (strTmpvalue.substr(strTmpvalue.length-1,1)=='/') {
            strTmpvalue = strTmpvalue.substr(0,strTmpvalue.length-1)
        }
        
        //Show altered value 
        objField.value = strTmpvalue;
    }
}

function CheckDate(strDatum, strFormat){
    //Input: 
    //    strDatum: Date string to check, use / a delimiter
    //    strFormat: either 'dd/mm/yyyy' OR 'mm/dd/yyyy'
    var datDate, strNewDate = ""
    var strDate_mmddyyyy

    //Create  a string conform mm/dd/yyyy
    switch (strFormat.toLowerCase()) {
        case ('dd/mm/yyyy') :
            var arTmp = strDatum.split("/")
            if (arTmp.length == 3) {
                //two slashes are found
                strDate_mmddyyyy = arTmp[1] + '/' + arTmp[0] + '/' + arTmp[2]
            } else {
                strDate_mmddyyyy = ''
            }
            break;
        case ('mm/dd/yyyy'):
            strDate_mmddyyyy = strDatum
            break;
    }

    //Perform datecheck on DD/MM/YYYY string
    datDate = new Date(strDate_mmddyyyy)
    
    //NOTE :getMonth is zero based
    if( ( datDate.getMonth() + 1 ) < 10 ){strNewDate += "0"}
    strNewDate += ( datDate.getMonth() + 1 ) + "/"
    if( datDate.getDate() < 10 ){strNewDate += "0"}
    strNewDate += datDate.getDate() + "/"
    strNewDate += datDate.getFullYear()
    
    if( ( strNewDate == strDate_mmddyyyy ) && ( strNewDate.length == 10 ) ){
        return true
    } else{
        return false
    }
}


function chkFrm_isOneCheckboxSelected(objCheckbox) {
    //objCheckbox is the radio button collection, not one specific field!!
    var bOneIsChecked = false
    for (k=0;k<objCheckbox.length;k++){
        if (objCheckbox[k].checked) {
            bOneIsChecked = true;
            break;
        }
    }
    return (bOneIsChecked);
}    

function chkFrm_isOneRadioButtonSelected(objRadios) {
    //objCheckbox is the radio button collection, not one specific field!!
    var bOneIsChecked = false
    for (k=0;k<objRadios.length;k++){
        if (objRadios[k].checked) {
            bOneIsChecked = true;
            break;
        }
    }
    return (bOneIsChecked);
}    

