///////////////////////////////////////////////////////////////////////////////
// VDaemon PHP Library version 3.0.3
// Copyright (C) 2002-2005 Alexander Orlov
//
// VDaemon client-side validation file
//
///////////////////////////////////////////////////////////////////////////////

function VDSymError()
{
  return true;
}
window.onerror = VDSymError;

var vdAllForms = new Array();
var vdForm = null;

function VDValidateForm(formName, submit)
{
    if (typeof(vdAllForms[formName]) == "undefined")
        return true;

    var browser = VDDetectBrowser();
    if (browser != "MSIE" && browser != "Netscape" && browser != "Firefox" && browser != "Opera" && browser != "Safari")
        return true;

    vdForm = vdAllForms[formName];
    vdForm.focus = false;
    VDPrepareValues();
    
    var isPageValid = true;
    var eventType = submit ? "submit" : "blur";
    for (var key in vdForm.validators) {
        VDValidateValidator(vdForm.validators[key], eventType);
        isPageValid = isPageValid && vdForm.validators[key].isvalid;
    }
    vdForm.isvalid = isPageValid;
    
    VDUpdateLabels(eventType);
    VDUpdateSummaries(eventType);

    vdForm = null;
    return isPageValid;
}

function VDResetForm(formName)
{
    if (typeof(vdAllForms[formName]) == "undefined")
        return true;

    var browser = VDDetectBrowser();
    if (browser != "MSIE" && browser != "Netscape" && browser != "Firefox" && browser != "Opera" && browser != "Safari")
        return true;

    vdForm = vdAllForms[formName];
    if (typeof(vdForm.controls) == "undefined")
        VDPrepareControls();

    VDUpdateLabels("reset");
    VDUpdateSummaries("reset");

    vdForm = null;
    return true;
}

function VDBindHandlers()
{
    var browser = VDDetectBrowser();
    for (var key in vdAllForms) {
        if (browser == "MSIE" || browser == "Opera") {
            document.forms[key].attachEvent('onsubmit', VDIeSubmitHandler);
            document.forms[key].attachEvent('onreset', VDIeResetHandler);
        } else if (browser == "Netscape" || browser == "Firefox" || browser == "Safari") {
            document.forms[key].addEventListener('submit', VDGeckoSubmitHandler, false);
            document.forms[key].addEventListener('reset', VDGeckoResetHandler, false);
        }
        
        for (var idx = 0; idx < document.forms[key].elements.length; idx++) {
            var element = document.forms[key].elements[idx];
            if (element.type == "submit" && element.tagName != "BUTTON") {
                if (browser == "MSIE" || browser == "Opera") {
                    element.attachEvent('onclick', VDIeClickHandler);
                } else if (browser == "Netscape" || browser == "Firefox" || browser == "Safari") {
                    element.addEventListener('click', VDGeckoClickHandler, false);
                }
            }
            else if (element.type != "button" && element.type != "image" &&
            element.type != "submit" && element.type != "reset") {
					  if (browser == "MSIE" || browser == "Opera") {
							element.attachEvent('onblur', VDIeSubmitHandler);
					  } else if (browser == "Netscape" || browser == "Firefox" || browser == "Safari") {
							element.addEventListener('blur', VDGeckoSubmitHandler, false);
					  }
            }
        }
    }
}

function VDIeSubmitHandler() 
{
	 var formName = VDGetFormName(event.srcElement);
	 
    if (vdForm == null) {
        var submit = event.type == "submit";
		  if(!submit && vdAllForms[formName].validationmode != "onchange")return;
        var valid = VDValidateForm(formName, submit);
        if (submit) {
				if(vdAllForms[formName].validationmode == "afterfirstsubmit")vdAllForms[formName].validationmode = "onchange";
            if (valid) {
                VDDisableButtons(formName);
            } else {
                event.returnValue = false;
            }
        }
    }
}

function VDIeResetHandler() 
{
    if (vdForm == null) {
        var formName = VDGetFormName(event.srcElement);
        VDResetForm(formName);
    }
}

function VDIeClickHandler() 
{
    if (vdForm == null) {
		  var formName = VDGetFormName(event.srcElement);
        vdAllForms[formName].submit = event.srcElement;
    }
}

/*
function VDIeSubmitHandler() 
{
	 var formName = VDGetFormName(event.srcElement);
	 
    if (vdForm == null) {
        var submit = event.type == "submit";
		  if(!submit && vdAllForms[formName].validationmode != "onchange")return;
        var valid = VDValidateForm(formName, submit);
        if (submit) {
			   alert(vdAllForms[formName].validationmode);
				if(vdAllForms[formName].validationmode == "afterfirstsubmit")vdAllForms[formName].validationmode = "onchange";
            if (valid) {
                VDDisableButtons(formName);
            } else {
                event.returnValue = false;
            }
        }
    }
}*/

function VDGeckoSubmitHandler(event) 
{
	 var formName = VDGetFormName(event.target);
	
    if (vdForm == null) {
        var submit = event.type == "submit";
		  if(!submit && vdAllForms[formName].validationmode != "onchange")return;
        var valid = VDValidateForm(formName, submit);
        if (submit) {
			   if(vdAllForms[formName].validationmode == "afterfirstsubmit")vdAllForms[formName].validationmode = "onchange";
            if (valid) {
                VDDisableButtons(formName);
            } else {
                event.preventDefault();
            }
        }
    }
}

function VDGeckoResetHandler(event) 
{
    if (vdForm == null) {
        var formName = VDGetFormName(event.target);
        VDResetForm(formName);
    }
}

function VDGeckoClickHandler(event) 
{
    if (vdForm == null) {
        var formName = VDGetFormName(event.target);
        vdAllForms[formName].submit = event.target;
    }
}

function VDGetFormName(element)
{
    var result = '';
    if (element.tagName == "INPUT" || element.tagName == "SELECT" || element.tagName == "TEXTAREA") {
        element = element.form;
    }
    if (element != null) {
        if (typeof(element.id) == "string") {
            result = element.id;
        } else if (element.getAttributeNode("ID") != null) {
            result = element.getAttributeNode("ID").value;
        }
        if (result == '') {
            if (typeof(element.name) == "string") {
                result = element.name;
            } else if (element.getAttributeNode("NAME") != null) {
                result = element.getAttributeNode("NAME").value;
            }
        }
    }
    return result;
}

function VDDisableButtons(formName)
{
    if (vdAllForms[formName].disablebuttons == "none")
        return;
    
    for (var idx = 0; idx < document.forms[formName].elements.length; idx++) {
        var element = document.forms[formName].elements[idx];
        if (element.type == "submit" || element.type == "image" ||
        (vdAllForms[formName].disablebuttons == "all" &&
        (element.type == "button" || element.type == "reset"))) {
            element.disabled = true;
        }
    }
}

function VDDetectBrowser()
{
    var detect = navigator.userAgent.toLowerCase();
    var browser;

    if (detect.indexOf('konqueror') > -1) browser = "Konqueror";
    else if (detect.indexOf('safari') > -1) browser = "Safari"
    else if (detect.indexOf('omniweb') > -1) browser = "OmniWeb"
    else if (detect.indexOf('opera') > -1) browser = "Opera"
    else if (detect.indexOf('webtv') > -1) browser = "WebTV";
    else if (detect.indexOf('icab') > -1) browser = "iCab"
    else if (detect.indexOf('msie') > -1) browser = "MSIE"
    else if (detect.indexOf('firefox') > -1) browser = "Firefox"
    else if (detect.indexOf('netscape') > -1) browser = "Netscape"
    else browser = "Unknown";
    
    return browser;
}

function VDGetPhpControlName(ctrlName)
{
    var result = new Array();
    var posL, posR, index;
    
    posL = ctrlName.indexOf('[');
    if (posL == 0) {
        return null;
    }
    posR = ctrlName.indexOf(']', posL);
    result[0] = posL > 0 && posR > 0 ? ctrlName.substring(0, posL) : ctrlName;
    result[0] = result[0].replace('[', '_');
    result[0] = result[0].replace('.', '_');
    
    while (posL > 0 && posR > 0) {
        index = ctrlName.substring(posL + 1, posR);
        index = VDEscape(index);
        if (index.match(/^0$|^[1-9][0-9]*$/) != null) { // decimal int
            index = parseInt(index);
        }
        result[result.length] = index;
        
        posL = ctrlName.indexOf('[', posR);
        if (posL != posR + 1) {
            posL = -1;
        } else {
            posR = ctrlName.indexOf(']', posL);
        }
    }
    
    return result;
}

function VDPrepareControls()
{
    var control;
    var phpName;
    var element;
    vdForm.controls = new Array();

    for (var idx = 0; idx < document.forms[vdForm.name].elements.length; idx++) {
        element = document.forms[vdForm.name].elements[idx];
        if (element.name && element.name != "VDaemonValidators" && element.tagName != "BUTTON" &&
        element.type != "button" && element.type != "image" && element.type != "reset") {
            phpName = VDGetPhpControlName(element.name);
            if (phpName != null) {
                control = new Object();
                control.phpName = phpName;
                control.obj = element;
                vdForm.controls[vdForm.controls.length] = control;
            }
        }
    }
}

function VDPrepareValues()
{
    var values, index, ref;
    
    if (typeof(vdForm.controls) == "undefined")
        VDPrepareControls();
    
    vdForm.values = new Array();
    for (var i in vdForm.controls) {
        values = VDGetElementValues(vdForm.controls[i].obj);
        for (var v in values) {
            ref = vdForm.values;
            index = null;
            for (var j in vdForm.controls[i].phpName) {
                if (index != null)
                    ref = ref[index];
                index = vdForm.controls[i].phpName[j];
                if (index === "")
                    index = ref.length;
                if (typeof(ref[index]) != "object") {
                    ref[index] = new Array();
                }
            }
            ref[index] = values[v];
        }
    }
}

function VDGetElementValues(element)
{
    var result = new Array();
    if (element.type == "select-multiple") {
        var options = element.getElementsByTagName("OPTION");
        if (typeof(options.length) == "number") {
            for (var idx = 0; idx < options.length; idx++) {
                var value = VDGetOptionValue(options[idx]);
                if (value != null) {
                    result[result.length] = value;
                }
            }
        }
    } else if (typeof(element.value) == "string") {
        if (element.type == "checkbox" || element.type == "radio") {
            if (element.checked)
                result[result.length] = VDTrim(element.value);
        } else if (element.type == "submit") {
            if (vdForm.disablebuttons == "none" &&
            typeof(vdForm.submit) == "object" && vdForm.submit == element) {
                vdForm.submit = null;
                result[result.length] = VDTrim(element.value);
            }
        } else
            result[result.length] = VDTrim(element.value);
    }
    return result;
}

function VDGetOptionValue(option)
{
    var result = null;
    if (option.selected) {
        if (typeof(option.value) == "string") {
            result = VDTrim(option.value);
        } else {
            result = VDTrim(option.text);
        }
    }
    return result;
}

function VDValidateValidator(validator, eventType)
{
    validator.isvalid = true;
    switch (validator.type) {
        case "required":
            validator.isvalid = VDEvaluateRequired(validator);
            break;
        case "checktype":
            validator.isvalid = VDEvaluateChecktype(validator);
            break;
        case "range":
            validator.isvalid = VDEvaluateRange(validator);
            break;
        case "compare":
            validator.isvalid = VDEvaluateCompare(validator);
            break;
        case "regexp":
            validator.isvalid = VDEvaluateRegExp(validator);
            break;
        case "format":
            validator.isvalid = VDEvaluateFormat(validator);
            break;
        case "custom":
            validator.isvalid = VDEvaluateCustom(validator);
            break;
        case "group":
            validator.isvalid = validator.operator == "and";
            for (var i in validator.validators) {
                VDValidateValidator(validator.validators[i], "");
                if (validator.operator == "and") {
                    validator.isvalid = validator.isvalid && validator.validators[i].isvalid;
                } else {
                    validator.isvalid = validator.isvalid || validator.validators[i].isvalid;
                }
            }
            break;
    }
    
    if (eventType == "submit" && !validator.isvalid && !vdForm.focus) {
        var fcontrol = VDFindFocus(validator);
        if (fcontrol) {
            var ctrlObj = document.forms[vdForm.name].elements[fcontrol];
            if (typeof(ctrlObj) != "undefined") {
                if (typeof(ctrlObj.tagName) == "undefined" && typeof(ctrlObj.length) == "number") {
                    ctrlObj = ctrlObj[0];
                }
                ctrlObj.focus();
                vdForm.focus = true;
            }
        }
    }
}

function VDFindFocus(validator)
{
    var fcontrol = null;
    if (validator.type == "group") {
        for (var i in validator.validators) {
            if (!validator.validators[i].isvalid) {
                fcontrol = VDFindFocus(validator.validators[i]);
                if (fcontrol)
                    break;
            }
        }
    } else if (typeof(validator.fcontrol) == "string") {
        fcontrol = validator.fcontrol;
    }
    
    return fcontrol;
}

function VDUpdateLabels(eventType)
{
    if (typeof(vdForm.labels) == "undefined")
        return;
    var i, j;
    for (i in vdForm.labels) {
        var oLabel = vdForm.labels[i];
        var label = document.getElementById(oLabel.id);
        if (label != null) {
            var isValid = true;
            if (eventType != "reset") {
                for (j in oLabel.validators) {
                    var valName = oLabel.validators[j];
                    var valState = VDGetValidatorState(valName);
                    if (valState != -1) {
                        isValid = isValid && valState;
                    }
                }
            }

            label.innerHTML = "";
            if (isValid) {
                label.innerHTML = oLabel.oktext;
                label.className = oLabel.okclass;
            } else {
                label.innerHTML = oLabel.errtext;
                label.className = oLabel.errclass;
            }
            
            if (typeof(oLabel.cokclass) == "object") {
                for (j in oLabel.cokclass) {
                    if (typeof(vdForm.controls[j].obj) == "object") {
                        vdForm.controls[j].obj.className = isValid ? oLabel.cokclass[j] : oLabel.cerrclass;
                    }
                }
            }
        }
    }
}

function VDUpdateSummaries(eventType)
{
    if (typeof(vdForm.summaries) == "undefined")
        return;

    for (var i in vdForm.summaries) {
        var headerSep, first, pre, post, last, s;
        var oSummary = vdForm.summaries[i];
        var summary = document.getElementById(oSummary.id);
        if (summary != null) {
            if (eventType == "reset" || vdForm.isvalid) {
                //summary.innerHTML = oSummary.showsummary ? "&nbsp;" : "";
                summary.innerHTML = "";
                summary.style.display = "none";
            } else {
                if (oSummary.showsummary) {
                    switch (oSummary.displaymode) {
                        case "list":
                        default:
                            headerSep = "<br>";
                            first = "";
                            pre = "";
                            post = "<br>";
                            last = "";
                            break;
                        case "bulletlist":
                            headerSep = "";
                            first = "<ul>";
                            pre = "<li>";
                            post = "</li>";
                            last = "</ul>";
                            break;
                        case "paragraph":
                            headerSep = " ";
                            first = "";
                            pre = "";
                            post = " ";
                            last = "";
                            break;
                    }

                    s = "";
                    for (var j in vdForm.validators) {
                        var val = vdForm.validators[j];
                        s += VDGetValidatorErrMsg(val, pre, post);
                    }
                    if (s != "") {
                        s = headerSep + first + s + last;
                    }
                    if (oSummary.headertext != "") {
                        s = oSummary.headertext + s;
                    }
                    
                    summary.innerHTML = s;
                    summary.style.display = (s == "") ? "none" : "";
                    //window.scrollTo(0,0);
                }

                if (eventType == "submit" && oSummary.messagebox) {
                    s = "";
                    if (oSummary.headertext != "") {
                        s += oSummary.headertext + "\n";
                    }
                    for (var j in vdForm.validators) {
                        var val = vdForm.validators[j];
                        if (!val.isvalid && val.errmsg != null) {
                            switch (oSummary.displaymode) {
                                case "list":
                                default:
                                    s += val.errmsg + "\n";
                                    break;
                                case "bulletlist":
                                    s += "  - " + val.errmsg + "\n";
                                    break;
                                case "paragraph":
                                    s += val.errmsg + " ";
                                    break;
                            }
                        }
                    }
                    alert(s);
                }
            }
        }
    }
}

function VDGetValidatorErrMsg(val, pre, post)
{
    var result = "";
    if (!val.isvalid) {
        if (val.errmsg) {
            result += pre + val.errmsg + post;
        }
        if (val.type == "group") {
            for (i in val.validators) {
                result += VDGetValidatorErrMsg(val.validators[i], pre, post);
            }
        }
    }
    
    return result;
}

function VDGetValidatorState(valName)
{
    var result = -1;
    if (valName) {
        for (i in vdForm.validators) {
            result = VDGetValStateR(valName, vdForm.validators[i], false);
            if (result != -1) {
                break;
            }
        }
    }
    
    return result;
}

function VDGetValStateR(valName, val, parentState)
{
    var result = -1;
    if (val.name == valName) {
        result = parentState || val.isvalid;
    } else if (val.type == "group") {
        for (i in val.validators) {
            result = VDGetValStateR(valName, val.validators[i], val.isvalid);
            if (result != -1) {
                break;
            }
        }
    }
    
    return result;
}

function VDGetControlValue(ctrlName)
{
    var result = vdForm.values;
    
    if (typeof(ctrlName) != "object")
        return null;
    
    for (var idx in ctrlName) {
        if (typeof(result[ctrlName[idx]]) == "undefined") {
            return null;
        }
        result = result[ctrlName[idx]];
    }
    
    return result;
}

function VDTrim(str)
{
    var match = str.match(/^\s*(\S+(\s+\S+)*)\s*$/);
    return (match == null) ? "" : match[1];
}

function VDEscape(value)
{
    value = value.replace(/\\/g, "\\\\");   //")
    value = value.replace(/'/g, "\\'");     //')
    value = value.replace(/"/g, '\\"');     //")
    
    return value;
}

function VDConvert(op, val)
{
    var dataType = val.validtype;
    var num, cleanInput, m, exp;
    if (dataType == "integer") {
        exp = /^\s*[-+]?\d+\s*$/;
        if (op.match(exp) == null) 
            return null;
        num = parseInt(op, 10);
        return (isNaN(num) ? null : num);
    } else if(dataType == "float") {
        exp = new RegExp("^\\s*([-+]?)(\\d+)?(\\.\\d+)?\\s*$");
        m = op.match(exp);
        if (m == null)
            return null;
        cleanInput = m[1] + (m[2].length > 0 ? m[2] : "0") + m[3];
        num = parseFloat(cleanInput);
        return (isNaN(num) ? null : num);            
    } else if (dataType == "currency") {
        exp = new RegExp("^\\s*([-+]?)(((\\d+)\\,)*)(\\d+)(\\.\\d{1,2})?\\s*$");
        m = op.match(exp);
        if (m == null)
            return null;
        var intermed = m[2] + m[5];
        cleanInput = m[1] + intermed.replace(new RegExp("(\\,)", "g"), "") + m[6];
        num = parseFloat(cleanInput);
        return (isNaN(num) ? null : num);            
    } else if (dataType == "date") {
        return VDConvertDate(op, val);
    } else if (dataType == "time") {
        return VDConvertTime(op, val);
    } else if (dataType == "datetime") {
        exp = /^\s*([-\d\.\/]+)\s+([\d:]+\s?(?:PM|AM)?)\s*$/i;
        m = op.match(exp);
        if (m == null)
            return null;
        var date = VDConvertDate(m[1], val);
        var time = VDConvertTime(m[2], val);
        if (date == null || time == null)
            return null;
        
        return date + time;
        return VDConvertDate(op, val);
    } else {
        return op.toString();
    }
}

function VDConvertDate(op, val)
{
    function VDGetFullYear(year) {
        return (year + 2000) - ((year < 30) ? 0 : 100);
    }
    
    var day, month, year, m, exp;
    if (val.dateorder == "ymd") {
        exp = new RegExp("^\\s*(\\d{2}(\\d{2})?)([-./])(\\d{1,2})\\3(\\d{1,2})\\s*$");
        m = op.match(exp);
        if (m == null)
            return null;
        day = m[5];
        month = m[4];
        year = (m[1].length == 4) ? m[1] : VDGetFullYear(parseInt(m[1], 10));
    } else {
        exp = new RegExp("^\\s*(\\d{1,2})([-./])(\\d{1,2})\\2(\\d{2}(\\d{2})?)\\s*$");
        m = op.match(exp);
        if (m == null)
            return null;
        if (val.dateorder == "dmy") {
            day = m[1];
            month = m[3];
        } else {
            day = m[3];
            month = m[1];
        }
        year = (m[4].length == 4) ? m[4] : VDGetFullYear(parseInt(m[4], 10));
    }
    month -= 1;
    var date = new Date(year, month, day);
    return (typeof(date) == "object" && year == date.getFullYear() && month == date.getMonth() && day == date.getDate()) ? date.valueOf() : null;
}

function VDConvertTime(op, val)
{
    var hour, min, sec, suf, m, exp;
    if (val.timeformat == "12") {
        exp = /^\s*(\d{1,2}):(\d{2})(?::(\d{2}))?\s?(PM|AM)\s*$/i;
        m = op.match(exp);
        if (m == null)
            return null;
        hour = parseInt(m[1], 10);
        min = m[2];
        sec = m[3] ? m[3] : 0;
        suf = m[4].toLowerCase();
        
        if (hour < 1 || hour > 12)
            return null;
        if (hour == 12) {
            hour = (suf == 'am') ? 0 : 12;
        } else if (suf == 'pm') {
            hour += 12;
        }
    } else {
        exp = /^\s*(\d{1,2}):(\d{2})(?::(\d{2}))?\s*$/;
        m = op.match(exp);
        if (m == null)
            return null;
        hour = m[1];
        min = m[2];
        sec = m[3] ? m[3] : 0;
    }
    
    var date = new Date(1970, 0, 1, hour, min, sec);
    return (typeof(date) == "object" && hour == date.getHours() && min == date.getMinutes() && sec == date.getSeconds()) ? date.valueOf() : null;
}

function VDCompare(operand1, operand2, operator, val)
{
    var op1, op2;
    if ((op1 = VDConvert(operand1, val)) == null)
        return false;    
    if ((op2 = VDConvert(operand2, val)) == null)
        return true;

    if (val.validtype == "string" && !val.casesensitive) {
        op1 = op1.toLowerCase();
        op2 = op2.toLowerCase();
    }    
    switch (operator) {
        case "ne":
            return (op1 != op2);
        case "g":
            return (op1 > op2);
        case "ge":
            return (op1 >= op2);
        case "l":
            return (op1 < op2);
        case "le":
            return (op1 <= op2);
        case "e":
        default:
            return (op1 == op2);            
    }
}

function VDEvaluateRequired(validator)
{
    var value = VDGetControlValue(validator.control);
    if (value == null)
        return validator.negation;
    
    var len;
    if (typeof(value) == "object") {
        len = 0;
        for (var i in value) {
            if (value[i] !== '')
                len++;
        }
    } else
        len = value.length;
    
    var result = true;
    if (len < validator.minlength) {
        result = false;
    } else if (validator.maxlength != -1) {
        result = (len <= validator.maxlength);
    }
    if (validator.negation) {
        result = !result;
    }
    
    return result;
}

function VDEvaluateChecktype(validator)
{
    var value = VDGetControlValue(validator.control);
    if (value != null && typeof(value) == "object")
        return true;
    if (value == null || value.length == 0)
        return !validator.required;
    
    var result = (VDConvert(value, validator) != null);
    if (validator.negation) {
        result = !result;
    }
    
    return result;
}

function VDEvaluateRange(validator)
{
    var value = VDGetControlValue(validator.control);
    if (value != null && typeof(value) == "object")
        return true;
    if (value == null || value.length == 0)
        return !validator.required;
    
    var result = (VDCompare(value, validator.minvalue, "ge", validator) &&
                  VDCompare(value, validator.maxvalue, "le", validator));
    if (validator.negation) {
        result = !result;
    }
    
    return result;
}

function VDEvaluateCompare(validator)
{
    var value = VDGetControlValue(validator.control);
    if (value != null && typeof(value) == "object")
        return true;
    if (value == null || value.length == 0)
        return !validator.required;
    
    var compareTo = "";
    if (typeof(validator.comparevalue) != "undefined") {
        compareTo = validator.comparevalue;
    } else if (typeof(validator.comparecontrol) != "undefined") {
        compareTo = VDGetControlValue(validator.comparecontrol);
    } else
        return false;

    if (compareTo == null)
        return false;
    else if (typeof(compareTo) == "object")
        return true;

    var result = VDCompare(value, compareTo, validator.operator, validator);
    if (validator.negation) {
        result = !result;
    }
    
    return result;
}

function VDEvaluateRegExp(validator)
{
    var value = VDGetControlValue(validator.control);
    if (value != null && typeof(value) == "object")
        return true;
    if (value == null || value.length == 0)
        return !validator.required;
    
    var result = true;
    var rx;
    try {
        eval("rx = " + validator.clientregexp + ";");
        var matches = rx.exec(value);
        result = (matches != null);
        if (validator.negation) {
            result = !result;
        }
    } catch(e) {
        result = true;
    }
    
    return result;
}

function VDEvaluateFormat(validator)
{
    var value = VDGetControlValue(validator.control);
    if (value != null && typeof(value) == "object")
        return true;
    if (value == null || value.length == 0)
        return !validator.required;
    
    var rx;
    switch (validator.format) {
        case 'email':
            rx = /^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)*\.\w{2,8}$/;
            break;
        case 'zip_us5':
            rx = /^\d{5}$/;
            break;
        case 'zip_us9':
            rx = /^\d{5}-\d{4}$/;
            break;
        case 'zip_us':
            rx = /^\d{5}(-\d{4})?$/;
            break;
        case 'zip_canada':
            rx = /^[a-z]\d[a-z]\s?\d[a-z]\d$/i;
            break;
        case 'zip_uk':
            rx = /^[a-z](\d|\d[a-z]|\d{2}|[a-z]\d|[a-z]\d[a-z]|[a-z]\d{2})\s?\d[a-z]{2}$/i;
            break;
        case 'phone_us':
            rx = /^(\+?\d{1,3})?[-\s\.]?(\(\d{3}\)|\d{3})[-\s\.]?\d{3}[-\s\.]?\d{4}(([-\s\.]|(\s?(x|ext\.?)))\d{1,5})?$/i;
            break;
        case 'ip4':
            rx = /^(([3-9]\d?|[01]\d{0,2}|2\d?|2[0-4]\d|25[0-5])\.){3}([3-9]\d?|[01]\d{0,2}|2\d?|2[0-4]\d|25[0-5])$/;
            break;
        default:
            rx = /^$/;
            break;
    }
    var matches = rx.exec(value);
    var result = (matches != null);
    if (validator.negation) {
        result = !result;
    }
    
    return result;
}

function VDEvaluateCustom(validator)
{
    var value = null;
    if (typeof(validator.control) == "object") {
        value = VDGetControlValue(validator.control);
    }
    
    var args = new Object();
    args.isvalid = true;
    args.errmsg = validator.errmsg;
    args.value = value;
    if (typeof(validator.clientfunction) == "string") {
        var rx = /^[a-zA-Z_]\w*$/;
        var m = rx.exec(validator.clientfunction);
        var isfunc;
        if (m != null) {
            eval("isfunc = typeof(" + validator.clientfunction + ") == 'function';");
            if (isfunc) {
                eval(validator.clientfunction + "(args);");
                args.isvalid = (args.isvalid === true);
                if (typeof(args.errmsg) == "string") {
                    validator.errmsg = args.errmsg;
                }
            }
        }
    }        
    return args.isvalid;
}
