/************************************************************
Библиотека для унифицированной проверки правильности 
заполенности форм.

Стиль, который отвечает за внешний вид сообщения об ошибке, 
которое появляется рядом с элементом формы. Нужно запихать
его в CSS или в страницу со скриптом.

<style type="text/css">
.mess {
	color:#999999;
	font-size:12px;
	font-family:Arial, Helvetica, sans-serif;
}
</style>

Формат аргумента, который передается в конструктор класса.

check = new Array(
	{id:'first', checkType:'isEmpty'}, 
	{id:'second', checkType:'isInInterval', start:0, end:100},
	{id:'third', checkType:'isEmail'}
);

id - идентификатор элемента формы, значение которого нужно
проверить.

checkType - тип проверки, должен совпадать с именем одного
из методов класса.

start, end - дополнительные параметры, которые могут понадо-
биться для проверки определенным методом.
************************************************************/

function checker(form, checkArray) {
	this.form = form;
	this.elems = this.form.elements;
	this.checkArray = checkArray;
	this.error = false;
	this.currentCheck = null;
	
	//Обход всех элементов, которые нужно проверить
	this.check = function() {
		for (i=0; i<this.checkArray.length; i++) {
			if (!this.elems[this.checkArray[i].id]) continue;			
			var elem = this.elems[this.checkArray[i].id];

			if (elem.type == 'hidden' || elem.type == 'submit' || elem.type == 'select') continue;
			
			this.currentCheck = this.checkArray[i];
			var res = eval('this.' + this.checkArray[i].checkType + '()');

			if (res !== true) {
				this.errorHandling(elem, res);
				this.error = true;
			} else {
				//Убираем обводку у элемента формы
				if (window.navigator.appName.indexOf('Microsoft') != -1) {
					elem.style.border = 'solid 1px #7F9DB9';
				} else {
					elem.style.border = '';
				}
				//Убираем сообщение об ошибке
				if (messDiv = document.getElementById(elem.id + '_mess')) {
					document.body.removeChild(messDiv);
				}
				continue;
			}
		}
		return this.error == false ? true : false;
	}
	
	//Определение координат объекта, относительно которого будет
	//отпозиционировано сообщение об ошибке
	this.getBounds = function(elem) {
		var left = elem.offsetLeft;
		var top  = elem.offsetTop;
		for (var parent = elem.offsetParent; parent; parent = parent.offsetParent) {
			left += parent.offsetLeft;
			top  += parent.offsetTop;
		}
		return {left: left, top: top, width: elem.offsetWidth, height: elem.offsetHeight};
	}
	
	//Рассчет ширины объекта
	this.getObjectWidth = function(elem) {
    	var result = 0;
    	if (elem.offsetWidth) {
        	result = elem.offsetWidth;
    	} else if (elem.clip && elem.clip.width) {
        	result = elem.clip.width;
    	} else if (elem.style && elem.style.pixelWidth) {
        	result = elem.style.pixelWidth;
    	}
    	return parseInt(result);
	}
	
	//Обработка ошибок
	this.errorHandling = function(elem, mess) {
		elem.style.border = 'solid 1px #FF0000';
		
		//Вывод сообщения об ошибке
		if (!document.getElementById(elem.id + '_mess')) {
			var message = document.createElement('div');
			
			message.style.position = 'absolute';
			message.style.left = this.getBounds(elem).left + this.getObjectWidth(elem) - 150 + 'px';
			message.style.top = this.getBounds(elem).top + 20 + 'px';
			
			message.setAttribute('id', elem.id + '_mess');
			message.className = 'mess';
			message.appendChild(document.createTextNode(mess));
			document.body.appendChild(message);
		}
	}
	
	//Получение элемента по его идентификатору
	this.idToElem = function(id) {
		if (elem = document.getElementById(id)) {
			return elem;
		}
		return false;
	}
	
	//Проверка поля на заполненность
	this.isEmpty = function() {
		var elem = this.idToElem(this.currentCheck.id);
		if (!elem) return false;
		if (elem.value == '') return 'Поле должно быть заполнено';
		else return true;
	}
	
	//Является ли значение поля правильным email адресом
	this.isEmail = function() {
		var elem = this.idToElem(this.currentCheck.id);
		if (!elem) return false;
		var re = /[_\.0-9a-z-]+@([0-9a-z][0-9a-z_-]+\.)+[a-z]{2,4}/;
		if (!elem.value.match(re)) return 'Поле должно содержать адрес электронной почты';
		else return true;
	}
	
	//Проверка на вхождение числа в диапазон
	this.isInInterval = function() {
		var elem = this.idToElem(this.currentCheck.id);
		if (elem.value == '') {
			return 'Число должно быть в диапазоне от ' + this.currentCheck.start + ' до ' + this.currentCheck.end;
		}
		var re = /^\d+$/;
		if (!elem.value.match(re)) {
			return 'Введенное значение должно быть числом';
		}
		var num = parseInt(elem.value);
		if (num > this.currentCheck.end || num < this.currentCheck.start) {
			return 'Число должно быть в диапазоне от ' + this.currentCheck.start + ' до ' + this.currentCheck.end;
		}
		return true;
	}
}