//	Copyright © Coretomic, 2005

/*
**********************************************************
*
*	A complete form input validation class
*
*	compiled by Alexey aka grinka.
*	grinka@yandex.ru
*
*	version 1.12
*
**********************************************************
*/
var LANG_ENGLISH = 0;
var LANG_RUSSIAN = 1;

oV = Validator.prototype;
oV.setFormName = v_setFormName;
oV.setForm = v_setForm;
oV.attachField = v_attachField;
oV.addEQFields = v_addEQFields;
oV.setLanguage = v_setLanguage;
oV.setValidateMessage = v_setValidateMessage;
oV.setFieldMessage = v_setFieldMessage;
oV.Validate = v_Validate;
oV.ValidateForm = v_ValidateForm;
oV.addCheckFields = v_addCheckFields;

oV.getFormName = v_getFormname;
oV.getFieldsCount = v_getFieldsCount;

oV.validateEl = v_validateEl;
oV.fmt = v_fmt;
oV.getErrorMsg = v_getErrorMsg;

/*
**************************************************
*	CONSTRUCTOR
**************************************************
*/
function Validator() {
	// conditions to check, by field
	this.conditions = new Array();
	// pairs of fields that should match
	this.equalities = new Array();
	// 'checkable' fields to validate
	this.checkgroups = new Array();
	// the list of fields to validate
	this.checkfields = new Array();
	// field names, as they are reported to the user, by field
	this.fieldnames = new Array();
	this.formname = '';
	// available messages, by error type and language
	this.messages = new Array();
	// messages to the user, by field name and condition
	this.pMessages = new Array();

	this.setValidateMessage('empty', LANG_ENGLISH, "'{title}' is missing\n");
	this.setValidateMessage('empty', LANG_RUSSIAN, "Вы пропустили поле '{title}' , требующее обязательного заполнения.\nПожалуйста, будьте внимательны!");
	this.setValidateMessage('date', LANG_ENGLISH, "The field '{title}' should be in a form 25.01.2001.");
	this.setValidateMessage('date', LANG_RUSSIAN, "Поле '{title}' должно быть заполнено в таком формате - 25.01.2001.");
	this.setValidateMessage('digits', LANG_ENGLISH, "The field '{title}' is incorrect. It must contains digits only.\n");
	this.setValidateMessage('digits', LANG_RUSSIAN, "Значение поля '{title}' введено неправильно. Поле должно содержать только цифры. Пожалуйста, будьте внимательны.\n");
	this.setValidateMessage('password', LANG_ENGLISH, "'{title}' must contain more than 3 symbols.");
	this.setValidateMessage('password', LANG_RUSSIAN, "Пароль в поле '{title}' должен содержать не меньше 3 символов.");
	this.setValidateMessage('phone', LANG_ENGLISH, "'{title}' is incorrect\n");
	this.setValidateMessage('phone', LANG_RUSSIAN, "В поле '{title}', введена некорректная информация.\nПожалуйста, будьте бдительны!");
	this.setValidateMessage('email', LANG_ENGLISH, "'{title}' is incorrect. It must be a valid e-mail.\n");
	this.setValidateMessage('email', LANG_RUSSIAN, "В поле '{title}', введена некорректная информация.\nПожалуйста, будьте бдительны!");
	this.setValidateMessage('notequal', LANG_ENGLISH, "Field values must be the same!");
	this.setValidateMessage('notequal', LANG_RUSSIAN, "Значения полей должны совпадать!");
	this.setValidateMessage('checked', LANG_RUSSIAN, "Вы должны ознакомиться со всеми необходимыми документами!");
	this.setValidateMessage('checkone',LANG_RUSSIAN, "Вы должны выбрать как минимум один вариант!");
	this.setLanguage(LANG_ENGLISH);
}

/*
**************************************************
*	Special functions
**************************************************
*/
function v_getFormname() {
	return this.formname;
}

function v_getFieldsCount() {
	return this.checkfields.length;
}

function v_setFormName(newname) {
	this.formname = newname;
	this.theForm = eval('document.' + newname);
}

function v_setForm(theform) {
	this.theForm = theform;
}

function v_setLanguage(newlang) {
	this.Language = newlang;
}

function v_setValidateMessage(msgtype, msglang, message) {
	var msger = this.messages[msgtype];
	if (typeof(msger)=='undefined')
		msger = new Array();
	msger[msglang] = message;
	this.messages[msgtype] = msger;
}

function v_setFieldMessage(fieldname, condition, message) {
	var msger = this.pMessages[fieldname];
	if (typeof(msger)=='undefined')
		msger = new Array();
	msger[condition] = message;
	this.pMessages[fieldname] = msger;
}

// format message
function v_fmt(themsg, title) {
	var re = new RegExp("\{title\}");
	return themsg.replace(re, title);
}

function v_getErrorMsg(condition) {
	var temparr = this.pMessages[this.fieldname];
	var temp=null;
	if (typeof(temparr)!='undefined') {
		temp = temparr[condition];
	}
	if (typeof(temp)=='undefined' || !temp) {
		temp = this.messages[condition][this.Language];
	}
	var re = new RegExp("\{title\}");
	if (temp == null) temp = "Error";
	return temp.replace(re, this.fieldnames[this.fieldname]);
}

/*
**************************************************
*	Fields functions
**************************************************
*/
function v_attachField(fieldname, conditions, showname) {
	var slog = 'Attaching: ' + fieldname + '\n';
	if (typeof(this.checkfields[fieldname])=='undefined') {
		this.checkfields[this.checkfields.length] = fieldname;
	}
	this.conditions[fieldname] = conditions;
	this.fieldnames[fieldname] = showname;
	return true;
}

function v_addCheckFields() {
	var tmp = new Array();
	for (i=0; i<arguments.length; i++) {
		tmp[tmp.length] = arguments[i];
	}
	this.checkgroups[this.checkgroups.length] = tmp;
}

function v_addEQFields(field1, field2) {
	var eqpair = new Array(field1, field2);
	this.equalities[this.equalities.length] = eqpair;
}

/*
**************************************************
*	Check functions
**************************************************
*/
// string trim (removes leading and trailing spaces)
function valid_trim(s) {
	if (!s || s.length<1 || s==null) return '';
	var re1 = new RegExp("^[\xA0 ]*");
	var re2 = new RegExp("[\xA0 ]*$");
	return s.replace(re1, "").replace(re2, "");
}

// only digits are allowed
function valid_checkDigit(field) {
	var re = new RegExp("^[0-9]+$");
	return field.value.match(re);
}

// a very basic date validation
function valid_checkDate(field) {
	var re = new RegExp("^[0-9]{1,2}\.[0-9]{1,2}\.[0-9]{4}$");
	return field.value.match(re);
}

// phone number validation
function valid_checkPhoneNumber(field) {
	var re = /^[ ]*(([+]?[ ]*[0-9]+)|[0-9]*)[ ]*((\([0-9]+\))|([0-9]+))?[ ]*[0-9- ]+$/;
	return field.value.match(re);
}

// email address validation
function valid_checkEmailAddress(field) {
	var re = /^\S+@([^\s.@]+\.)+(biz|com|edu|gov|int|mil|net|org|pro|aero|arpa|coop|info|name|museum|[a-z][a-z])$/i;
	return field.value.match(re);
}

// select box validation
function valid_checkSelect(field) {
	var newelem = document.forms[field.form.name][field.name];
	if (!newelem)
		return false;
	if (newelem.selectedIndex==-1)
		return false;
	if (!newelem[newelem.selectedIndex].value)
		return false;
	return true;
}

// check for element emptiness
function valid_checkEmpty(field) {
	if (!field)
		return false;
	// validate radio button/checkbox
	if (typeof(field.type)=='undefined') {
		if (field.length!=0 && (field[0].type=='radio' || field[0].type=='checkbox'))
			return valid_checkRadioArr(field);
		else
			return false;
	}
	if (field.type=='radio' || field.type=='checkbox')
		return valid_checkRadioSingle(field);
	// validate select box
	if (field.type.substring(0,6)=='select') {
		return valid_checkSelect(field);
	}
	// validate text field
	if (field.value.length<1) return false;
	return (valid_trim(field.value).length!=0);
}

// password validation
function valid_checkPassword(field) {
	return (valid_trim(field.value).length >= 3);
}

// returns parameters if FNAME found in the THEARR
// else returns 'false' boolean value
/*
function inarr(fname, thearr) {
	if (!fname || typeof(thearr) == "undefined") return false;
	var flname = trim(fname);
	if (!flname.length) return false;

	flname=flname.toLowerCase();
	var flag = false;
	var ilog = '';
	for (var i=0; i<thearr.length; i++) {
		if (thearr[i].indexOf(flname) == 0) {
			var temp = new String(thearr[i]);
			flag = temp.substr(flname.length + 1);
		}
	}
	return flag;
}
*/

function valid_checkRadioArr(elm) {
	var found = false;
	for (i=0; i<elm.length; i++)
		if (elm[i].checked && elm[i].value !== "")
			found = true;
	return (found)
}

function valid_checkRadioSingle(elm) {
	return elm.checked;
}

/*
**************************************************
*	Validate functions
**************************************************
*/
//
// Validate the form Element
//
function v_validateEl(elm, params) {
	if (!params || !params.length) return true;
	var pArr = params.split(',');
	var result = 'yes';
	var i=0;
	var isNotEmpty = valid_checkEmpty(elm);
	while (i<pArr.length && result=='yes') {
		switch (valid_trim(pArr[i])) {
		case 'empty':
			if (!isNotEmpty) result = this.getErrorMsg('empty');
			break;
		case 'phone':
			if (isNotEmpty)
				if (!valid_checkPhoneNumber(elm))result = this.getErrorMsg('phone');
			break;
		case 'email':
			if (isNotEmpty)
				if (!valid_checkEmailAddress(elm)) result = this.getErrorMsg('email');
			break;
		case 'password':
			if (isNotEmpty)
				if (!valid_checkPassword(elm)) result = this.getErrorMsg('password');
			break;
		case 'digits':
			if (isNotEmpty)
				if (!valid_checkDigit(elm)) result = this.getErrorMsg('digits');
			break;
		case 'date':
			if (isNotEmpty)
				if (!valid_checkDate(elm)) result = this.getErrorMsg('date');
			break;
		case 'checked':
			if (!elm.checked) result = this.getErrorMsg('checked');
		}
		i++;
	}
	return result;
}

//
// Validate the form
// returns: false if validation failed
//
function v_ValidateForm(theform) {
	if (typeof(theform)=='string')
		this.setFormName(theform);
	else
		this.theForm = theform;
	return this.Validate();
}

//
// Validate the form
// returns true on success; false if validation failed
//
function v_Validate() {
	if (this.formname) this.theForm = eval('document.'+this.formname);
	if (!this.theForm) {
		alert('Internal Error: No form');
		return false;
	}
	// return true if there are no fields to validate
	if (!this.checkfields)
		return true;
	var strError = "";
	for (i=0; i<this.checkfields.length; i++) {
		var elm = this.theForm.elements[this.checkfields[i]];
		if (elm) {
			this.fieldname = this.checkfields[i];
			var params = this.conditions[this.fieldname];
			if (params) {
				var isValid = this.validateEl(elm, params);
				if ((isValid && isValid != 'yes')) {
					var altElName = this.fieldname.substring(0, this.fieldname.indexOf("[")) + "[alt]";
					var altEl = this.theForm.elements[altElName];
					if (altEl) isValid = this.validateEl(altEl, params);
				}

				if (isValid && isValid != 'yes') {
					strError += isValid;
					if (typeof(elm.type)!='undefined' && elm.type != "hidden" && !elm.disabled) {
						try {
							elm.focus();
						} catch (err) {}
/*						if (elm.type.substring(0,6)!='select')
							elm.select();
*/
					}
				}
			}
		}
		else {
		}
	}
	// report all incorrect entries in a single alert
	if (strError!="") {
		alert("Please check the following required fields:\n" + strError + "Please try again.");
		return false;
	}

	var equaz = this.equalities;
	if (equaz != null) {
		for (var i=0; i<equaz.length; i++) {
			if (equaz[i]!=null) {
				if (this.theForm.elements[equaz[i][0]].value!=this.theForm.elements[equaz[i][1]].value) {
					alert(this.getErrorMsg('notequal'));
					this.theForm.elements[equaz[i][1]].value = '';
					try {
						this.theForm.elements[equaz[i][1]].focus();
					} catch (err) {}
					return false;
				}
			}
		}
	}
	// 'checkable' fields validation
	if (this.checkgroups.length>0) {
		for (i=0; i<this.checkgroups.length; i++) {
			ogr = this.checkgroups[i];
			found=false;
			for (j=0; j<ogr.length; j++) {
				var elm = this.theForm.elements[ogr[j]];
				if (typeof(elm)!='undefined')
					if (elm.checked)
						found=true;
			}
			if (!found) {
				alert(this.getErrorMsg('checkone',''));
				var elm = this.theForm.elements[ogr[0]];
				try {
					elm.focus();
				} catch (err) {}
				return false;
			}
		}
	}
	return true;
}
