﻿/**
* modified: 
*  - [2007-12-13] added support for mandatory select boxes (selectedIndex == 0 now is not allowed in a mandatory setting) 
**/
//var 
function BBValidator()
{
    this.obj_form = undefined;
    this.str_formName = " ";
}

BBValidator.prototype = 
{
    init : function (html_formElement)
    {
        this.obj_formElement = html_formElement;
        this.str_formName = html_formElement.getAttribute('forforms', 0);
        
        this.obj_form = document.getElementById(this.str_formName);
        
        // Check if a good form is found
        if( (!this.obj_form) || (!this.str_formName) || (!this.str_formName.length) )
        {
        
            // No good form found, move up the tree and try to find the form 
            // (note: the form object (div or table) has to have an id for this to work)
            this.str_formName = this.findFormObject(this.obj_formElement);
            
            if(this.str_formName)
            {
                this.obj_form = document.getElementById(this.str_formName);
            }
        }
        
        
        if(this.obj_form === null)
        {
            alert("Sorry, error occured: the form could not be found.");
            return false;
        }
    
    },
    
    findFormObject : function (elm)
    {
	    if((elm.parentNode != null) && (elm.parentNode.tagName != undefined))
	    {
            //console.debug("nodeName: " + elm.parentNode.nodeName);
		    if(elm.parentNode.getAttribute('editFor')!= null)
		    {
			    return elm.parentNode.getAttribute('bbformname');
		    }
		    else
		    {
			    return this.findFormObject(elm.parentNode)
		    }
	    }
    },

    
    validate : function(bln_submit) 
    {
        var arry_elements;
        var str_return;
        var str_error = "";
        var arry_errors = new Array();
    
        arry_elements = this.findFormElements(this.obj_form);
        
        for(var int_counter = 0; int_counter < arry_elements.length; int_counter++)
        {
            var obj_current = arry_elements[int_counter];
            
            str_return = "";
            
            if(obj_current.getAttribute("mandatory", 0))
            {
                if( (obj_current.nodeName.toLowerCase()=="input") && ( (obj_current.type == "checkbox") || (obj_current.type == "radio")) )
                {
                    if(!obj_current.checked)
                        str_return = obj_current.getAttribute("mandatorymessage", 0);
                        
                } else if(obj_current.nodeName.toLowerCase()=="select"){
                    if(obj_current.selectedIndex === 0)
                    {
                        str_return = obj_current.getAttribute("mandatorymessage", 0);
                    }
                } else if(!this._getValue(obj_current))
                {
                    str_return = obj_current.getAttribute("mandatorymessage", 0);
                }
                    
            } else if( (obj_current.nodeName.toLowerCase()=="input") && ((obj_current.type == "checkbox") || (obj_current.type == "radio")) )
            {
                if(obj_current.checked)
                    str_return = this._checkElement(obj_current);
            }
            if(!str_return.length && ( (obj_current.getAttribute("mandatoryreg", 0)) || (obj_current.getAttribute("tovalidateas", 0)) ) )
            {
                    str_return = this._checkElement(obj_current);
            }
            if(str_return)
            {
                if (this._getErrorClass(obj_current) != undefined)
                {
                    this._addCSSClass(obj_current, this._getErrorClass(obj_current));
                }
                
                str_toReturn = obj_current.getAttribute("mandatoryerror", 0);
                
                arry_errors.push(str_return);
            } else {
            
                if (this._getErrorClass(obj_current) != undefined)
                {
                    this._removeCSSClass(obj_current, this._getErrorClass(obj_current));
                }
            }
        }
        
        for(var int_counter = 0; int_counter < arry_errors.length; int_counter++)
        {
            if(int_counter > 0)
            {
                str_error = str_error + "\n";
            }
            str_error = str_error + arry_errors[int_counter];
        }
        
        if(arry_errors.length)
        {
            alert(str_error);
            
            return false;
        } else if(bln_submit === true)
        {
            if(nf_SendForm != undefined)
                nf_SendForm(this.obj_formElement);
        }
        
        return false;
    },
    
    _checkElement : function(html_node)
    {
        var str_validateAs;
        var str_mandatoryReg;
        var bln_valid = true;
        var str_toReturn = "";
        var str_value;
        
        str_validateAs = html_node.getAttribute('tovalidateas', 0);
        
        switch(str_validateAs)
        {
            case 'Postcode':
                bln_valid = this.check_zipcode(html_node);
                break;
            case 'E-mail':
                bln_valid = this.check_email(html_node);
                break;
            case 'Giro':
                bln_valid = this.check_bank_giro(html_node);
                break;
            case 'Datum[dd-mm-yyyy]':
                bln_valid = this.check_dateDdMmYyyy(html_node);
                break;
            case 'Datum[yyyy-mm-dd]':
                bln_valid = this.check_dateYyyyMmDd(html_node);
                break;
                
            default:
                str_mandatoryReg = html_node.getAttribute('mandatoryreg', 0);
                
                if(str_mandatoryReg)
                {
                    str_value = this._getValue(html_node);
                
                    if(str_mandatoryReg  && str_value != "" && str_value != "undefined" && !this.validateRegExp(str_value, str_mandatoryReg))
                    {
                        bln_valid = false;
                    }
                }
                break;

        }
        
        if(bln_valid == false) 
        {
        
            str_toReturn = html_node.getAttribute("mandatoryerror", 0);
            
        }
        
        return str_toReturn;
        
    },
    
    _getValue : function(html_node)
    {
        var str_value;
        
        switch(html_node.nodeName.toLowerCase())
        {
            case 'input':
            case 'textarea':
                str_value = html_node.value;
                break;
            case 'select':
                str_value = html_node.options[html_node.selectedIndex].value;
                break;
        }
        
        return str_value;
    
    },
    
    _getErrorClass : function(html_node)
    {
        str_errorClass = html_node.getAttribute('classerror', 0);
        
        return str_errorClass;
    },
    
    /**
    * Returns an array of form elements
    **/
    findFormElements : function (html_node)
    {
        var int_counter;
        var int_counter2;
        var html_currentNode;
        var str_forforms;
        var html_formNode;
        
        // The array to be returned
        var arry_rtrn = new Array();
        
        // array to store the result of a function call
        var arry_result;
        
        html_formNode = this.obj_formElement.form;
                
        for(int_counter = 0; int_counter < html_formNode.elements.length; int_counter++)
        {
            html_currentNode = html_formNode.elements[int_counter];
            
            str_forforms = html_currentNode.getAttribute('forforms', 0);
            
            if(str_forforms == this.str_formName)
            {
                switch(html_currentNode.nodeName.toLowerCase())
                {
                    case 'input':
                    case 'select':
                    case 'textarea':
                        arry_rtrn.push(html_currentNode);
                }
            }
        }
        
        return arry_rtrn;
        
    },
    
    
    
    /**
    * Returns false when the class is already found, otherwise true 
    **/
    _addCSSClass : function (html_node, str_class)
    {
        var int_index;

        int_index = html_node.className.indexOf(str_class);
        
        if( (str_class.length == html_node.className.length) || (((int_index == 0) || (html_node.className.charAt(int_index -1) == ' ')) && (html_node.className.charAt(int_index + str_class.length + 1) == ' ')) )
        {
            return false;
        }
        
        if(html_node.className.length > 0)
            str_class = " " + str_class;
        
        html_node.className += str_class
        
        return true;
    },
    
    /**
    * Remove first occurence of a css class
    **/
    _removeCSSClass : function (html_node, str_class)
    {
        var int_index = html_node.className.indexOf(str_class);
        
        // Bail out when the text was not found
        if(int_index == -1)
        {
            return false;
        } 
            
        //~ if( (str_class.length == html_node.className.length) || (((int_index == 0) || (html_node.className.charAt(int_index -1) == ' ')) && (html_node.className.charAt(int_index + str_class.length + 1) == ' ')) )
        if( ((int_index == 0) &&  (html_node.className.length == str_class.length + int_index))
            || ((html_node.className.charAt(int_index -1) == ' ') && (html_node.className.length == str_class.length + int_index)) 
            || ((html_node.className.charAt(int_index -1) == ' ') && (html_node.className.charAt(int_index + str_class.length + 1) == ' ')) 
            )
        {
            if(int_index > 0)
            {
                str_class = " " + str_class
            }
            
            html_node.className = html_node.className.replace(str_class,"");
        
        }
            
        return true;
    
    },
    
    /**
    * The validation function returns false when it fails, true when stuff is correct 
    **/
    check_bank_giro : function(field) { 
        // Check if number is a valid 7 digit 'Postbank' giro number (optionally prefixed with 'P'), 
        // or more general 13 digit bank-number. Adds 'P' to 7 digit numbers. 
        // check de elf proef if not postbank 
        // voorbeeld
        //0541386913 
        //987654321
        // totaal moet gedeeld door 11.

        var text = this._getValue(field);
        
        // Bail out on an empty text
        if (!text.length) 
            return(true); 
            
        text = text.replace(/[^0-9]/gi,''); // Keep only the numbers... 
        if (text.length==7) 
        {
            return(true); 
        } 
        
        // Do the 11-test... 
        if (text.length!=9) 
            return(false); 
            
        Sum=0; 
        Factor=9; 
        for (i=0; i<9; i++) 
        { 
            Digit = parseInt(text.substring(i,i+1)); 
            Sum += parseInt(Factor*Digit); 
            Factor = Factor-1; 
        } 
        
        if ((Sum%11)==0) 
            return(true); 
        return(false); 
    },

    /** Returns true if the check succeeded (i.e. it is valid) **/
    check_zipcode : function(field) 
    { 
        var text=this._getValue(field);
        
        text = text.replace(/ /g,'').toUpperCase();
        
        if (!text.match(/^[1-9]\d{3}[A-Z]{2}$/)) {
            return false;
        }
        
        return true;
    },
    
    // Returns true if the email is considered 'valid' 
    check_email : function(field) 
    { 
        // If the e-mail address contains: 
        // the e-mail address contains an invalid syntax. Or, if the 
        // syntax does not match the following regular expression pattern 
        // it fails basic syntax verification. 
        // Basic syntax requires: one or more characters before the @ sign, 
        // followed by an optional '[', then any number of letters, numbers, 
        // dashes or periods (valid domain/IP characters) ending in a period 
        // and then 2, 3 or 4 letters (for domain suffixes) or 1 to 3 numbers 
        // (for IP addresses). An ending bracket is also allowed as it is 
        // valid syntax to have an email address like: user@[255.255.255.0] 
        // AvD on nov 14th 2005 - .info was not accepted because it was 4 chars long: regexp corrected... 
        var text=this._getValue(field); 
        
        if (!text.length) 
            return(true); 
        re1 = /(@.*@)|(\.\.)|(@\.)|(\.@)|(^\.)/; 
        re2 = /^.+\@(\[?)[a-zA-Z0-9\-\.]+\.([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$/; 

        if (re1.test(text) || !re2.test(text)) 
        { 
            return(false); 
        } 
        
        return(true); 
    },
    
    check_dateDdMmYyyy : function (html_node)
    {
        var dateformat = /^\d{2}(\-|\/|\.)\d{2}\1\d{4}$/    
        var day, month, year, text;
        
        text = this._getValue(html_node);
        
        if(!text.match(dateformat))
        {
            return false;
        }
        
        day = new Number(text.substr(0,2));
        month = new Number(text.substr(3,2));
        year = new Number(text.substr(6,4));
        
        return this.isDate(day, month, year);
        //return true;
    },
    
    check_dateYyyyMmDd : function (html_node)
    {
        var dateformat = /^\d{4}(\-|\/|\.)\d{2}\1\d{2}$/    
        var day, month, year, text;
        
        text = this._getValue(html_node);
        
        if(!text.match(dateformat))
        {
            return false;
        }
        
        day = new Number(text.substr(8,2));
        month = new Number(text.substr(5,2));
        year = new Number(text.substr(0,4));
        
        return this.isDate(day, month, year);
        //return true;
    },
    
    isDate : function(day, month, year)
    {
        var bln_isValid = true;
        if (month < 1 || month > 12)
        { 
            bln_isValid = false;
        }

        if (day < 1 || day > 31)
        {
            bln_isValid = false;
        }

        if ((month==4 || month==6 || month==9 || month==11) && day==31)
        {
            bln_isValid = 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))
            {
                bln_isValid = false;
            }
        }
        
        return bln_isValid; 
    },
    
    
    validateRegExp : function (str_value, str_expression)
    {
	    var RegEx = new RegExp(str_expression);
    	return !RegEx.test(str_value);
    }
};


function checkValidate(html_node)
{
    var vld_BBValidator;
    
    vld_BBValidator = new BBValidator();
    vld_BBValidator.init(html_node);
    
    // call validate with the True argument (this way the form validator will try to submit the form too)
    return vld_BBValidator.validate(true);
    
    return false;
    
}


