var Page_BlockSubmit = false;
var focusElement = null;
var enableFocus = true;
var validatorForm = null;

function ValidationInit()
{
    if (typeof(Page_Validators)!='undefined')
    {
        for (var i=0; i<Page_Validators.length; i++)
            AttachToControl(Page_Validators[i]);
    }
    
    if (focusElement!=null)
		focusElement.focus();
}

function AttachToControl(vld)
{
    var validator = document.getElementById(vld[1]);
    var ctrl = document.getElementById(vld[2]);
    
    var handler = function() { UpdateValidator(vld); }
    
    if (ctrl)
    {
        switch(ctrl.tagName)
        {
            case "INPUT": 
            case "SELECT": ValidatorAttachEvent(ctrl,"change",handler); break;
            case "TABLE":
                var els = ctrl.getElementsByTagName("INPUT");
                for (var i=0; i<els.length; i++) ValidatorAttachEvent(els[i],"click",handler);
                break;
        }
    }
    
    if (validatorForm==null)
    {
		if (ctrl==null || typeof(ctrl.form)=='undefined')
		{
			var forms = document.getElementsByTagName("form");
			
			for (var i=0; i<forms.length; i++)
			{
				if (typeof(forms[i].contains)!='undefined' && forms[i].contains(validator))
				{
					validatorForm = forms[i];
					ValidatorAttachEvent(validatorForm, "submit", ValidatorOnSubmit);
					break;
				}
			}
		}
		else
		{
			validatorForm = ctrl.form;
		}
    }
}



function ValidatorAttachEvent(ctrl,evnt,handler)
{
    if (validatorForm==null)
    {
        validatorForm = ctrl.form;
        
        ValidatorAttachEvent(validatorForm, "submit", ValidatorOnSubmit);
    }

    if (typeof(ctrl['attachEvent'])!='undefined')
        ctrl.attachEvent("on"+evnt, handler);
    else if (typeof(ctrl['addEventListener'])=='function')
        ctrl.addEventListener(evnt,handler,false);        
}

function Page_ClientValidate()
{
	var allowSubmit = true;
    for (var i=0; i<Page_Validators.length; i++)
        allowSubmit &= UpdateValidator(Page_Validators[i]);

	Page_BlockSubmit = (!allowSubmit);
	
	return allowSubmit;
}

function ValidatorOnSubmit(e)
{
    if (Page_BlockSubmit)
    {
        if (typeof(window.event)!='undefined')
            window.event.returnValue = false;
        else if (typeof(e)!='undefined')
            e.preventDefault();
    }
}

function UpdateValidator(vld)
{
    var isValid = ValidateControl(vld);
    
    var validator = document.getElementById(vld[1]);
    
    switch (validator.className)
    {
        case 'staticValidator':
            validator.style.visibility = (isValid) ? 'hidden' : 'visible';
            break;
        case 'dynamicValidator':
            validator.style.display = (isValid) ? 'none' : 'inline';
            break;
    }
    
    return isValid;
}

function ValidateControl(vld)
{
    if (typeof(window['ValidateControl_'+vld[0]])!='undefined')
        return window['ValidateControl_'+vld[0]](vld);
}

function GetCheckedValue(frm,name,prop)
{
    var els = frm.getElementsByName(name);
    for (var i=0; i<els.length; i++) if (els[i][prop]) return els[i].value;
    return '';
}

function ValidatorGetValue(id) {
    var control;
    control = document.getElementById(id);
    
    if (typeof(control.value) == "string") {
        return control.value;
    }
    if (typeof(control.tagName) == "undefined" && typeof(control.length) == "number") {
        var j;
        for (j=0; j < control.length; j++) {
            var inner = control[j];
            if (typeof(inner.value) == "string" && (inner.type != "radio" || inner.status == true)) {
                return inner.value;
            }
        }
    }
    else {
        return ValidatorGetValueRecursive(control);
    }
    return "";
}
function ValidatorGetValueRecursive(control)
{
    if (typeof(control.value) == "string" && (control.type != "radio" || control.checked == true)) {
        return control.value;
    }
    var i, val;
    for (i = 0; i<control.childNodes.length; i++) {
        val = ValidatorGetValueRecursive(control.childNodes[i]);
        if (val != "") return val;
    }
    return "";
}

function ValidatorConvert(op, dataType, val) {
    function GetFullYear(year) {
        return (year + parseInt(val.century)) - ((year <= parseInt(val.cutoffyear, 10)) ? 0 : 100);
    }
    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 == "Double") {
        exp = new RegExp("^\\s*([-\\+])?(\\d*)\\" + val.decimalchar + "?(\\d*)\\s*$");
        m = op.match(exp);
        if (m == null)
            return null;
        if (m[2].length == 0 && m[3].length == 0)
            return null;
        cleanInput = m[1] + (m[2].length>0 ? m[2] : "0") + (m[3].length>0 ? "." + m[3] : "");
        num = parseFloat(cleanInput);
        return (isNaN(num) ? null : num);
    }
    else if (dataType == "Currency") {
        var hasDigits = (val.digits > 0);
        var beginGroupSize, subsequentGroupSize;
        var groupSizeNum = parseInt(val.groupsize, 10);
        if (!isNaN(groupSizeNum) && groupSizeNum > 0) {
            beginGroupSize = "{1," + groupSizeNum + "}";
            subsequentGroupSize = "{" + groupSizeNum + "}";
        }
        else {
            beginGroupSize = subsequentGroupSize = "+";
        }
        exp = new RegExp("^\\s*([-\\+])?((\\d" + beginGroupSize + "(\\" + val.groupchar + "\\d" + subsequentGroupSize + ")+)|\\d*)"
                        + (hasDigits ? "\\" + val.decimalchar + "?(\\d{0," + val.digits + "})" : "")
                        + "\\s*$");
        m = op.match(exp);
        if (m == null)
            return null;
        if (m[2].length == 0 && hasDigits && m[5].length == 0)
            return null;
        cleanInput = m[1] + m[2].replace(new RegExp("(\\" + val.groupchar + ")", "g"), "") + ((hasDigits && m[5].length > 0) ? "." + m[5] : "");
        num = parseFloat(cleanInput);
        return (isNaN(num) ? null : num);
    }
    else if (dataType == "Date") {
        var yearFirstExp = new RegExp("^\\s*((\\d{4})|(\\d{2}))([-/]|\\. ?)(\\d{1,2})\\4(\\d{1,2})\\s*$");
        m = op.match(yearFirstExp);
        var day, month, year;
        if (m != null && (m[2].length == 4 || val.dateorder == "ymd")) {
            day = m[6];
            month = m[5];
            year = (m[2].length == 4) ? m[2] : GetFullYear(parseInt(m[3], 10))
        }
        else {
            if (val.dateorder == "ymd"){
                return null;
            }
            var yearLastExp = new RegExp("^\\s*(\\d{1,2})([-/]|\\. ?)(\\d{1,2})\\2((\\d{4})|(\\d{2}))\\s*$");
            m = op.match(yearLastExp);
            if (m == null) {
                return null;
            }
            if (val.dateorder == "mdy") {
                day = m[3];
                month = m[1];
            }
            else {
                day = m[1];
                month = m[3];
            }
            year = (m[5].length == 4) ? m[5] : GetFullYear(parseInt(m[6], 10))
        }
        month -= 1;
        var date = new Date(year, month, day);
        if (year < 100) {
            date.setFullYear(year);
        }
        return (typeof(date) == "object" && year == date.getFullYear() && month == date.getMonth() && day == date.getDate()) ? date.valueOf() : null;
    }
    else {
        return op.toString();
    }
}
function ValidatorCompare(operand1, operand2, operator, val) {
    var dataType = val.type;
    var op1, op2;
    if ((op1 = ValidatorConvert(operand1, dataType, val)) == null)
        return false;
    if (operator == "DataTypeCheck")
        return true;
    if ((op2 = ValidatorConvert(operand2, dataType, val)) == null)
        return true;
    switch (operator) {
        case "NotEqual":
            return (op1 != op2);
        case "GreaterThan":
            return (op1 > op2);
        case "GreaterThanEqual":
            return (op1 >= op2);
        case "LessThan":
            return (op1 < op2);
        case "LessThanEqual":
            return (op1 <= op2);
        default:
            return (op1 == op2);
    }
}

function ValidateControl_XCompareValidator(vld)
{
    var val1 = ValidatorGetValue(vld[2]);
    var val2 = vld[5]=='' ? vld[6] : ValidatorGetValue(vld[5]);

    if (val1.length==0) return true;
    if (val2.length==0 && vld[3]!="DataTypeCheck") return true;
   
    var ret = ValidatorCompare(val1, val2, vld[3], vld[7]);
    
    return ret;
}

function ValidateControl_XRequiredFieldValidator(vld)
{
    return ValidatorGetValue(vld[2])!=vld[3];
}

function ValidateControl_XRegularExpressionValidator(vld)
{
	var value = (vld[2]!='' && vld[2]!=null) ? ValidatorGetValue(vld[2]) : "";
	
	if (value.length==0) return true;
	
	var re = new RegExp(vld[3]);
	
	return (re.test(value));
}

function ValidateControl_XCustomValidator(vld)
{
	var value = (vld[2]=='') ? '' : ValidatorGetValue(vld[2]);
	var sender = document.getElementById(vld[0]);
	var args = {IsValid:true,Value:value};
	
	var fnc = window[vld[3]];
	
	if (typeof(fnc)!='undefined')
		fnc(sender, args);

	return args.IsValid;
}

function RegisterControlFocus(ctrl)
{
	if (focusElement==null)
	{
		if (typeof(ctrl).toLowerCase()=='string')
			ctrl = document.getElementById(ctrl);
			
		focusElement = ctrl;
	}
}