function validate_field(fi,reg) {
	if (fi.match(reg)) {
		return true;
	}
	return false;
}



function validateForm(frm,fi,validreg) {

	var el,noerr,frm;
	noerr = true;
	if (document.forms[frm])
	{
		frm = document.forms[frm];
	} else {
		return true;
	}

	for (var i in fi) {
		el = frm[fi[i]];

		if (el) {
			if (el.value == '') {
				noerr = false;
				el.style.background = '#ffdddd';
			} else {
				el.style.background = '#ffffff';
			}
		}
	}
	if (!noerr) {
		if (errmsg)	alert(errmsg);
	} else {
		var messages = '';
		for (i in validreg) {
			if (frm[i]) {
				if (!validate_field(frm[i].value,validreg[i])) {
					frm[i].style.background = '#ffdddd';
					messages += errormsg[i] + '\n';
					noerr = false;
				}
			}
		}
		if (!noerr) {
			alert(messages);
		}
	}

	return noerr;
}


function validateNumeric(value) {
	if (value.length == 0) return true;
	var v = parseFloat(value);
	if (isNaN(v) || (v != value)) return false;
	return true;
}

function validateRegExp(value,param) {
	var rg = new RegExp(param);
	if (value.match(rg)) {
		return true;
	}
	return false;
}


function validateMin(value,param) {
	value = parseFloat(value);
	if (value < parseFloat(param)) {
		return false;
	}
	return true;
}

function validateMax(value,param) {
	value = parseFloat(value);
	if (value > parseFloat(param)) {
		return false;
	}
	return true;
}

function validateMinLength(value,param) {
	if (value.length < param) return false;
	return true;
}

function validateMaxLength(value,param) {
	if (value.length > param) return false;
	return true;
}

function formValidate(frmname) {
	var frm,prefix,inp,i,j,rez,result;
	result = true;
	if (prefix = frmname.match(/^frm_(\w+)$/)) {
		prefix = prefix[1];
		if (document.forms[frmname]) {
			frm = document.forms[frmname];
			if (formRules[prefix]) {
				var rules = formRules[prefix];
				for (i in rules) {
					inp = 'prop_' + i;
					if (frm[inp]) {
						for (j in rules[i]) {
							rez = true;
							switch (rules[i][j].type) {
							case PR_NUMERIC:
								rez = validateNumeric(frm[inp].value);
								break;
							case PR_REGEXP:
								rez = validateRegExp(frm[inp].value,rules[i][j].value);
								break;
							case PR_MIN:
								rez = validateMin(frm[inp].value,rules[i][j].value);
								break;
							case PR_MAX:
								rez = validateMax(frm[inp].value,rules[i][j].value);
								break;
							case PR_NOTEMPTY:
								rez = !validateRegExp(frm[inp].value,'^\s*$');
								break;
							}
							if (!rez) {
								frm[inp].style.background = '#ffdddd';
								result = false;
							} else {
								frm[inp].style.background = '#ffffff';
							}
						}
					}
				}
			};
		};
	};
	return result;
}


/*
*	rules:[
*		{rule_id:5,type:2,value:"^$",order:1,label:"errlabel"}
*	]
*
*
*
*/

function cValidator (field,rules,rel,checkRelate) {
	this.field = field;
	this.rules = rules;
	this.rel = rel;
	this.orlogic = false;
	this.checkRelate = checkRelate;
	this.errMsg = [];

	this.validate = function(value) {
		var i;
		if (this.rel && this.checkRelate) {
			if (!this.checkRelate(this.rel,this.orlogic)) {
				return true;
			}
		}

		result = true;
		this.errMsg = [];
		var rules = this.rules;
		for (i = 0;i < rules.length; i++) {
			rez = true;
			switch (rules[i].type) {
			case PR_NUMERIC:
				rez = validateNumeric(value);
				break;
			case PR_REGEXP:
				rez = validateRegExp(value,rules[i].value);
				break;
			case PR_MIN:
				rez = validateMin(value,rules[i].value);
				break;
			case PR_MAX:
				rez = validateMax(value,rules[i].value);
				break;
			case PR_NOTEMPTY:
				rez = !validateRegExp(value,'^\s*$');
				break;
			case PR_MINLENGTH:
				rez = validateMinLength(value,rules[i].value);
				break;
			case PR_MAXLENGTH:
				rez = validateMaxLength(value,rules[i].value);
				break;
			}

			if (!rez) {
				result = false;
				if (this.rules[i].label) {
					this.errMsg.push(this.rules[i].label);
				}
			}
		}
		return result;
	}
}


function cFormValidator() {
	this.forms = [];
	this.cssError = 'error';
	this.markErrors = true;
	this.errMsg = {};
	this.checkRelate = null;//relations function
	this.showErrors = false;//show error messages

	this.addForm = function(frm,fields) {
		this.forms[frm.getAttribute('name')] = {form:frm}
		if (fields) {
			var vl = [];
			for (var i in fields) {
				vl.push(new cValidator(i,fields[i]));
			}

			this.forms[frm.getAttribute('name')].validators = vl;
		} else {
			this.forms[frm.getAttribute('name')].validators = [];
		}
	}

	this.addValidators = function(frmname,fields) {
		if (this.forms[frmname]) {
			for (var i in fields) {
				this.forms[frmname].validators.push(new cValidator(i,fields[i]));
			}
		}
	}

	this.removeValidators = function(frmname,field) {
		if (this.forms[frmname]) {
			var v = this.forms[frmname].validators;
			var b = [];
				for (i = 0 ; i < v.length; i++) {
					if (v[i].field != field ) {
						b.push(v[i]);
					};
				}
			this.forms[frmname].validators = b;
		}
	}

	this.addFieldSet = function (frmname,struct,dmode) {
		if (struct && struct.length) {
			var n,v;
			for (var i in struct) {
				if (struct[i].flags&PF_MANDATORY) {
					if (!struct[i].rules) struct[i].rules = [];
					struct[i].rules.push({type:PR_NOTEMPTY,label:"emptyfield"});
				}
				if (struct[i].rules && struct[i].rules.length) {
					n = dmode ? 'inp' + struct[i].id: 'item_value' + struct[i].id;
					v = new cValidator(n,struct[i].rules,struct[i].rel,this.checkRelate);
					v.orlogic = struct[i].flags&PF_REL_OR;
					this.forms[frmname].validators.push(v);
				}
			}
		}
	}

	this.clearValidators = function(frmname) {
		if (this.forms[frmname]) {
			this.forms[frmname].validators = [];
		}
	}

	this.validateForms = function() {
		var result = {};
		for (var i = 0;i < arguments.length;i++) {
			if (this.forms[arguments[i]]) {
				result[arguments[i]] = this.validate(this.forms[arguments[i]]);
			}
		}
		return result;
	}

	this.validateForm = function (frmname) {
		if (this.forms[frmname]) {
			return this.validate(this.forms[frmname]);
		} else {
			return true;
		}
	}

	this.validate = function (frm) {
		var i,k,result,value;
		var f = frm.form;var v = frm.validators;
		this.errMsg[frm] = {};
		result = true;
		for (i = 0 ; i < v.length; i++) {
			if (f[v[i].field]) {
				if (f[v[i].field].length)
				{
					value = '';
					for (k = 0; k < f[v[i].field].length;k++ )
					{
						if (f[v[i].field][k].checked || f[v[i].field][k].selected) value = f[v[i].field][k].value;
					}
				} else {
					value = f[v[i].field].value;
				}
				if (!v[i].validate(value)) {
					if (this.markErrors) {
						this.markError(f[v[i].field],v[i].errMsg);
					}
					result = false;
					if (v[i].errMsg.length) {
						this.errMsg[frm][v[i].field] = v[i].errMsg;
					}
				} else if (this.markErrors) {
					this.clearError(f[v[i].field]);
				}
			}
		}
		return result;
	}

	this.markErrorList = function(frmname,fieldList,fieldPrefix) {

		if (this.forms[frmname]) {
			var f = this.forms[frmname].form;
			var fi;
			for (i in fieldList) {
				fi = (fieldPrefix||'') + i;
				if (f[fi]) {
					this.markError(f[fi],fieldList[i]);
				}
			}
		}
	}

	this.markError = function(field,msgs) {

		var cl;
		if (!field.nodeName)
		{
			if (field[0] && field[0].parentNode) {
				this.markError(field[0].parentNode,msgs);
			}
			return;
		}

		if (this.showErrors) {
			if (msgs && langMaster) {
				while(field.nextSibling) {
					cl = field.nextSibling;
					if (cl && cl.className == this.cssError) {
						cl.parentNode.removeChild(cl);
					} else {
						break;
					}
				}
				for (var i in msgs) {
					if (msgs[i] != 'none')
					{
						d = (document.createElement('div'));
						d.className = this.cssError;
						var errtxt = langMaster.getLabel(msgs[i]);
						if (errtxt != '') {
							d.appendChild(document.createTextNode(errtxt));
						}


						if (field.nextSibling) {
							field.parentNode.insertBefore(d,field.nextSibling);
						} else {
							field.parentNode.appendChild(d);
						}
					}
				}
			}
		}

		field.validateError = true;

	  	if (field.className && (cl = field.className.split(/\s/))) {
			for (var i in cl) {
				if (cl[i] == this.cssError) return;
			}
			field.className += ' ' + this.cssError;
	  	} else {
	  		field.className = this.cssError;
		}



	}

	this.clearError = function(field) {
		var cl;
		if (!field.nodeName)
		{
			if (field[0] && field[0].parentNode) this.clearError(field[0].parentNode);
			return;
		}

		if (field.className && (cl = field.className.split(/\s/))) {
			var cm = [];
			for (var i in cl) {
				if (cl[i] != this.cssError) cm.push(cl[i]);
			}
			field.className = cm.join(' ');
			field.validateError = false;
		}
		if (this.showErrors) {
			while(field.nextSibling) {
				cl = field.nextSibling;
				if (cl && cl.className == this.cssError) {
					cl.parentNode.removeChild(cl);
				} else {
					break;
				}
			}
		}
	}
}

var formValidator = new cFormValidator();
var formRules = {};