// formChecker v1.6.0 (June 7, 2007) by Bramus! 
// http://www.bram.us/
//
// License : don't use, nor modify without Bramus! his permission.
//
// Checking routines based upon http://juicystudio.com/article/generic-form-validation.php/
//
// v 1.6.0 - Tuesday, June 7, 2007
//          - FEATURE   : added _isColor
//
// v 1.5.1 - Tuesday, June 5, 2007
//          - CHANGE    : Added check to see if formChecker doesn't exist yet, to avoid conflicts if multiple includes are made.
//
// v 1.5.0 - Wednesday, February 7, 2007
//          - CHANGE    : Dateverification no longer depends on _my_ datepicker, since frequencydecoder his implementation 
//                        is way more flexible and dynamic than mine
//          - CHANGE    : Due to the change above, the date validation needed to be real now (and not just checking on a string).
//                        Implementation modded from http://www.codetoad.com/forum/17_10053.asp
//
// v 1.4.2 - Wednesday, November 29, 2006
//          - FEATURE   : added isUrl (http & ftp & https only)
//
// v 1.4.1 - Wednesday, August 23, 20006
//          - BUGFIX    : Minor bugfix in _isDate
//
// v 1.4 - Monday, August 7, 2006
//          - FEATURE   : checkForm now shows and errormessage into an element with id=error_{nameofthefield}, if it is found. (backdrop from iedereenleeftmee)
//          - FEATURE   : possibility to make fields optional by adding optional to the class of the element
//          - CHANGE    : instead of selecting all children from the form by calling objForm.getElementsByTagName('*'),
//                        now only the following elements are selected: input, textarea, select
//
// v 1.3 - Monday, July 31, 2006
//          - CHANGE    : greatly tweaked checkBox & radio checking (complete overhaul)
//
// v 1.2 - Somewhere in June 2006
//          - FEATURE   : checkBox & radio checking
//
// v 1.1 - Somewhere in Q1 2006
//          - FEATURE   : added isDate
//
// v 1.0 - Somewhere Q3 2005
//          - first version
//
// some stuff one needs to read before sinning against Exodus 20.15 (*)!
// - to validate a checkbox, you must place it in a label and give the label lbl_$item as id
//
// (*) See http://www.biblegateway.com/passage/?search=exodus%2020.15&version=31 for more details on Exodus 20.15 ;)

if (!formChecker) {

    var formChecker = {
    
        okColor         : '#ffffff',                                    // background to set when value is ok (textfield, textarea, select)
        nokColor        : '#ea9b9b',    /* '#ea9b9b', */                // background to set when value is not ok   
        okTextColor     : '#000000',                                    // background to set when value is ok (checkbox/radiobutton)
        nokTextColor    : '#ea9b9b',    /* '#CF2639', */                // background to set when value is not ok (checkbox/radiobutton)
        nokMessage      : 'Gelieve je e-mailadres in te vullen',       // message to alert when form not ok, leave empty to not alert any message
        
        errorMsgSelect  : 'Please select a value',                      // message to show on screen when select not ok
        errorMsgCheck   : 'Please make a choice',                       // message to show on screen when checkbox/radiobutton not ok
        errorMsgString  : 'Please complete this field',                 // message to show on screen when a textfield is empty
        errorMsgNumber  : 'Please enter a number',                      // message to show on screen when no number was entered
        errorMsgEmail   : 'Please enter a valid e-mailaddress',         // message to show on screen when no e-mail was entered
        errorMsgUrl     : 'Please enter a valid url',                   // message to show on screen when no url was entered
        errorMsgDate    : 'Please choose a date',                       // message to show on screen when no date was selected
        errorMsgColor   : 'Please enter a hex color',                   // message to show on screen when no date was selected
    
        checkForm       : function (daForm) {                       
                            var arClass, bValid, gotError;        
                            var objForm= daForm;
                                            
                            //var objField  = objForm.getElementsByTagName('*');    // old method : got ALL items (including labels and such)       
                            var objField    = formChecker._mergeNodeLists(
                                                    objForm.getElementsByTagName('input'), 
                                                    objForm.getElementsByTagName('textarea'), 
                                                    objForm.getElementsByTagName('select')
                                               ); 
                            
                            gotError = false;
                            
                           /* document.getElementById('formSubmit').disabled      = true;
                            if (document.getElementById('spinner')) {
                                document.getElementById('spinner').style.visibility = 'visible';
                            }*/
                            
                            for (var iFieldCounter=0; iFieldCounter<objField.length; iFieldCounter++) {
                            
                                // Allow for multiple values being assigned to the class attribute
                                arClass = objField[iFieldCounter].className.split(' ');
                                
                                for (var iClassCounter=0; iClassCounter<arClass.length; iClassCounter++) {
                                    
                                    // console.debug("checking item '%s' with class '%s'", objField[iFieldCounter].name, arClass[iClassCounter]);
                                
                                    switch (arClass[iClassCounter]) {
                                    
                                        case 'select':              
                                            bValid      = formChecker._isSelected(objField[iFieldCounter]);
                                            errorMsg    = formChecker.errorMsgSelect;
                                            break;
                                        case 'check':               
                                            bValid      = formChecker._isChecked(objField[iFieldCounter]);
                                            errorMsg    = formChecker.errorMsgCheck
                                            break;
                                        case 'string':
                                            bValid      = formChecker._isString(objField[iFieldCounter]);
                                            errorMsg    = formChecker.errorMsgString;
                                            break;
                                        case 'number' :
                                            bValid      = formChecker._isNumber(objField[iFieldCounter]);
                                            errorMsg    = formChecker.errorMsgNumber;
                                            break;
                                        case 'url' :
                                            bValid      = formChecker._isUrl(objField[iFieldCounter]);
                                            errorMsg    = formChecker.errorMsgUrl;
                                            break;
                                        case 'email' :
                                            bValid      = formChecker._isEmail(objField[iFieldCounter]);
                                            errorMsg    = formChecker.errorMsgEmail;
                                            break;
                                        case 'date' :
                                            bValid      = formChecker._isDate(objField[iFieldCounter]);
                                            errorMsg    = formChecker.errorMsgDate;
                                            break;
                                        case 'colour' :
                                        case 'color' :
                                            bValid      = formChecker._isColor(objField[iFieldCounter]);
                                            errorMsg    = formChecker.errorMsgColor;
                                            break;
                                        default:
                                            bValid = 'NULL';
                                            break;
                                        
                                    }
                        
                                    if (bValid == false) {
                        
                                        gotError = true;
                                        
                                        // date : color the label
                                        if(arClass[iClassCounter] == 'check') {
                                            var elems = document.getElementsByName(objField[iFieldCounter].name);
                                            for (var i=0; i<elems.length; i++) {
                                                document.getElementById('lbl_' + elems[i].id).style.color = formChecker.nokTextColor;
                                            }
                                        // normal : color the item
                                        } else {
                                            //objField[iFieldCounter].focus();
                                            objField[iFieldCounter].style.background = formChecker.nokColor;
                                        }
                                    
                                        // set errorMessage 
                                        if (document.getElementById("error_" + objField[iFieldCounter].name)) {
                                            document.getElementById("error_" + objField[iFieldCounter].name).innerHTML          = errorMsg;
                                            document.getElementById("error_" + objField[iFieldCounter].name).style.visibility   = 'visible';
                                        }
                                        
                                    } else {
                                        
                                        if (bValid != 'NULL') {     
                                            // date : color the label
                                            if(arClass[iClassCounter] == 'check') {
                                                var elems = document.getElementsByName(objField[iFieldCounter].name);
                                                for (var i=0; i<elems.length; i++) {
                                                    document.getElementById('lbl_' + elems[i].id).style.color = formChecker.okTextColor;
                                                }
                                            // normal : color the item
                                            } else {
                                                //objField[iFieldCounter].focus();
                                                objField[iFieldCounter].style.background = formChecker.okColor;
                                            }
                                            
                                            // unset errorMessage                                   
                                            if (document.getElementById("error_" + objField[iFieldCounter].name)) {
                                                document.getElementById("error_" + objField[iFieldCounter].name).innerHTML          = '';
                                                document.getElementById("error_" + objField[iFieldCounter].name).style.visibility   = 'hidden';
                                            }
                                        }   
                                        
                                    }
                                }
                            }
                            
                            if (gotError) {
                                if (formChecker.nokMessage != '') {
                                    alert(formChecker.nokMessage);
                                }
                                /*document.getElementById('formSubmit').disabled      = false;
                                document.getElementById('spinner').style.visibility = 'hidden';*/
                                return false;
                            } else {
                                return true;
                            }
                        
        },
        
        _mergeNodeLists     : function (objInput, objTextarea, objSelect) {
        
                                var objField = new Array();
                                
                                if (objInput.length != 0) {
                                    for (i = 0; i < objInput.length; i++) {
                                        objField[i] = objInput.item(i); 
                                    }
                                }
                                
                                if (objTextarea.length != 0) {
                                    for (i = 0; i < objTextarea.length; i++) {
                                        objField[objInput.length + i]   = objTextarea.item(i);  
                                    }
                                }
                                
                                if (objSelect.length != 0) {
                                    for (i = 0; i < objSelect.length; i++) {
                                        objField[objInput.length + objTextarea.length + i]  = objSelect.item(i);    
                                    }
                                }   
                                
                                return objField;
        },
        
        _isOptional         : function(className) {
                                //alert(className);
                                var re = new RegExp("optional");
                                var m = re.exec(className);
                                if (m == null) {
                                    return false;
                                } else {
                                    return true;
                                }
        },
            
        _isSelected         : function (objField) {
                                if (formChecker._isOptional(objField.className) && (objField.selectedIndex == 0)) {
                                    return true;
                                } else {
                                    if (objField.selectedIndex == 0) {
                                        return false;
                                    } else {
                                        return true;
                                    }
                                }
        },
        
        _isChecked          : function (objField) {
                                var arrOptions = document.getElementsByName(objField.name);
                                for (var i=0; i<arrOptions.length; i++) {
                                    if (arrOptions[i].checked) return true;
                                }
                                return false;
        },
            
        _isString           : function (objField) {
                                strValue    = objField.value.replace(/^\s*|\s*$/g, '');
                                if (formChecker._isOptional(objField.className) && (strValue == "")) {
                                    return true;
                                } else {
                                    return (typeof strValue == 'string' && strValue != ''); //  && isNaN(strValue)
                                }
        },
            
        _isNumber           : function (objField) {
                                strValue    = objField.value;
                                if (formChecker._isOptional(objField.className) && (strValue == "")) {
                                    return true;
                                } else {
                                    return (!isNaN(strValue) && strValue != '');
                                }
        },
            
        _isEmail            : function (objField) {
                                strValue    = objField.value;
                                if (formChecker._isOptional(objField.className) && (strValue == "")) {
                                    return true;
                                } else {
                                    var objRE = /^[\w-\.\']{1,}\@([\da-zA-Z-]{1,}\.){1,}[\da-zA-Z-]{2,}$/;
                                    return (strValue != '' && objRE.test(strValue));
                                }
        },
        
        _isUrl              : function (objField) { 
                                strValue    = objField.value;
                                if (formChecker._isOptional(objField.className) && (strValue == "")) {
                                    return true;
                                } else {
                                    var regexp = /(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/
                                    return regexp.test(strValue);
                                }   
        },
        
        _isDate             : function (objField) {
                                strValue    = objField.value;
                                if (formChecker._isOptional(objField.className) && (strValue == "")) {
                                    return true;
                                } else {
                                    //return !isNaN(new Date(strValue));        // <<--- this needs checking
                                    //return !isNaN(Date.parse(strValue));      // <<--- this needs checking -->> only works with / as divider
                                    
                                    var dateStr     = strValue;
                                    var datePat     = /^(\d{4})(\/|-)(\d{1,2})(\/|-)(\d{1,2})$/; // (YYYY-MM-DD) or (YYYY/MM/DD)
                                    var matchArray  = dateStr.match(datePat); // is the format ok?
                                    
                                    if (matchArray == null) {
                                        return false;
                                    }
                                    
                                    year    = matchArray[1]; // parse date into variables
                                    month   = matchArray[3];
                                    day     = matchArray[5];
                                    
                                    if (month < 1 || month > 12) { // check month range
                                        // alert("Month must be between 1 and 12.");
                                        return false;
                                    }
                                    
                                    if (day < 1 || day > 31) {
                                        // alert("Day must be between 1 and 31.");
                                        return false;
                                    }
                                    
                                    if ((month==4 || month==6 || month==9 || month==11) && day==31) {
                                        // alert("Month "+month+" doesn't have 31 days!")
                                        return false;
                                    }
                                    
                                    if (month == 2) { // check for february 29th
                                        var isleap = (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0));
                                        if (day > 29 || (day==29 && !isleap)) {
                                            // alert("February " + year + " doesn't have " + day + " days!");
                                            return false;
                                        }
                                    }
                                    return true; // date is valid
                                }
        },
        
        _isColor            : function(objField) {
                                strValue    = objField.value;
                                if (formChecker._isOptional(objField.className) && (strValue == "")) {
                                    return true;
                                } else {
                                    var regexp = /^\#?[0-9A-F]{6}$/;
                                    return regexp.test(strValue.toUpperCase());
                                }
        }
    }
}
