/**
* Класс контроля ввода с помощью JavaScript. Использовать исключительно для удобства интерфейса. Данные необходимо проверять дважды, этим классом и PHP, так как этот класс создан исключительно для удобства и не повышает безопасность сайта
* Класс использует библиотеку JQUERY
*
* @autor Евгений Масляев (http://mrjohn.ru)
* @param id (string) идентификатор элемента, для которого используется контроль ввода
* @param reg_all (string) регулярное выражение для общей проверки введенных данных
* @param reg_char (string) регулярное выражение, которому должен соответствовать каждый символ в отдельности (для удаления ненужных символов в режиме он-лайн)
* @param err_class (string) Какой CSS-класс присвоить проверяемому элементу, если значение введено неправильно
* @param success_class (string) Какой CSS-класс присвоить проверяемому элементу, если значение введено правильно
* @param sample (string) Пример правильного ввода информации в проверяемый элемент (отображается как всплывающая подсказка при неправильном вводе)
* @param cut_len (int) Какая может быть максимально допустимая длина вводимой строки в символах. При превышении длины строка обрезается. Если длина = 0 , то обрезка строки не происходит никогда
* @param acronim ассоциативный массив ключ:значение для замены ключа на значения в строке. Передается через функцию set_acronim
*
* Пример использования класса
*	Необходимо подключить JQUERY, а затем подключить файл с классом к html-странице
*
*	function Test(id){
*		var x = new EnterControl();
*		x.set_acronim({
*			"ул.":"улица"
*		});
*		x.set_params({
*			"reg_char":/^\d$/,
*			"reg_all":/^\d{11}$/,
*			"err_class":"e_class",
*			"success_class":"s_class",
*			"sample":"+79101231234",
*			"cut_len":11
*		});
*		x.check(id);
*		return(true);
*	}
*	Затем у текстового поля с идентификатором input_id в свойстве onchange вызывается функция Test(this.id);
*/

function EnterControl() {
	this.id = null;
	this.reg_all = null;
	this.reg_char = null;
	this.err_class = "e_class";
	this.success_class = "s_class";
	this.sample = "";
	this.cut_len = 0;
	this.acronim = null;
	
	/**
	* Устанавливает массив акронимов
	* @param acronim_array ассоциативный массив для замены ключа на значение
	* @return true
	*/	
	this.set_acronim = function(acronim_array){
		this.acronim = acronim_array;
		return(true);
	}
	/**
	* Выполняет замену принятых сокращений из массива acronim. Например, "ул." на "улица" для улучшения поиска
	* @param str строка, в которой надо выполнить замены
	* @return (string) строку с выполненными заменами
	*/
	this.replace_acronim = function(str){
		if (this.acronim==null) return(str);
		for (var key in this.acronim){
			str = str.replace(key, this.acronim[key]);
		}
		return(str);
	}
	/**
	* Устанавливает настройки класса. Пытается установить параметры, а если это не удается, то пропускает и оставляет по умолчанию
	* @param par_array ассоциативный массив с именами переменных класса и их значениями. Его элементы совпадают с параметрами самого класса
	* @return true
	*/	
	this.set_params = function(par_array){
		for (var key in par_array){
			//Проверка параметров на существование и соответствие типу
			switch (key) {
				case "id":
					if(typeof(par_array[key])=="string") this.id = par_array[key];
					break;
				case "reg_all":
					if(typeof(par_array[key])=="object") this.reg_all = par_array[key];
					break;					
				case "reg_char":
					if(typeof(par_array[key])=="object") this.reg_char = par_array[key];
					break;	
				case "err_class":
					if(typeof(par_array[key])=="string") this.err_class = par_array[key];
					break;
				case "success_class":
					if(typeof(par_array[key])=="string") this.success_class = par_array[key];
					break;
				case "sample":
					if(typeof(par_array[key])=="string") this.sample = par_array[key];
					break;
				case "cut_len":
					if(typeof(par_array[key])=="number") this.cut_len = par_array[key];
					break;									
				default: continue;
			}
		}
		return(true);
	}
	
	/**
	* Проверить элемент
	* @param id идентификатор элемента, который надо проверять
	* @param atr атрибут объекта, который надо проверять
	* @return true или false в зависимости от результата проверки. Если значение удалось исправить - true
	*/
	this.check = function(id, atr){
		var obj = $("#"+id);
		//Проверка параметров на существование и соответствие типу
		if (typeof(atr)!="string") atr = "value";
		if($(obj).length == 0) return(false);
		var val = $(obj).attr(atr);
		if (typeof(val)!="string") return(false);
		//Замена акронимов, если это необходимо
		val = this.replace_acronim(val);
		//Получение проверяемого параметра и посимволиная проверка, если это необходимо
		var res_string = "";
		for (i=0;i<val.length;i++){
			if (this.check_smb(val[i])) res_string += val[i];
		}
		//Если требуется обрезка - обрезать
		if (this.cut_len > 0) res_string = res_string.substr(0, this.cut_len);
		$(obj).attr(atr, res_string);
		//Проверка общего вида строки
		if (!this.check_str(res_string)){
			if ($(obj).hasClass(this.success_class)) $(obj).removeClass(this.success_class);
			if (!$(obj).hasClass(this.err_class)) $(obj).addClass(this.err_class);
			if (this.sample!="") $(obj).attr("title", "Введено неверно. Вводить надо например так: "+this.sample);
		} else {
			if ($(obj).hasClass(this.err_class)) $(obj).removeClass(this.err_class);
			if (!$(obj).hasClass(this.success_class)) $(obj).addClass(this.success_class);
			if (this.sample!="") $(obj).removeAttr("title");
		}
		return(true);
	}
	
	/**
	* Проверка символа на соответствие рег.выражению, занесенному в класс
	* @param smb символ, который надо проверить
	* @return true или false
	*/
	this.check_smb = function(smb){
		if (this.reg_char==null) return(true);
		return(smb.match(this.reg_char));
	}
	
	/**
	* Проверка строки на соответствие рег.выражению, занесенному в класс
	* @param str строка, которую надо проверить
	* @return true или false
	*/	
	this.check_str = function(str){
		if (this.reg_all==null) return(true);
		return(str.match(this.reg_all));
	}
}
