var sjWidgets = {
	'initAlert': false,
	'alert': function(){
		var text = arguments[0];
		var theme = arguments[1] || 'alert';
		try {
			if (!this.initAlert)
			{
				$.jGrowl.defaults.closerTemplate = '<div>[закрыть все]</div>';
				$.jGrowl.defaults.position = arguments[2] || 'bottom-right';
			}
			$.jGrowl(
				text,
				{
					glue:'top',
					theme:theme,
					corners:5,
					life:5000
				}
			)
			if (!this.initAlert)
			{
				if ($.browser.msie && $.browser.version >= 8)
				{
					$('#jGrowl').css('position', 'absolute');
				}
				this.initAlert = true;
			}
		} catch(e) {
			alert(text)
		}
	},
	'sendRequest': function(data, reqType, targeturi){
		var uri = targeturi && targeturi.length ? targeturi : this.baseURI;
		var backref = this;
		var errmsg = 'Произошла ошибка системы!';
		if (typeof(backref.setLoadingState) == 'function')
			backref.setLoadingState(true);
		$.ajax({
			url: uri,
			cache: false,
			dataType: 'text',
			error: function(xhr, ts, err){
				if (typeof(backref.setLoadingState) == 'function')
					backref.setLoadingState(false, true);
				if (/isdvlpr_on=1;/.test(document.cookie))
					errmsg += ' (ошибка xhttprequest: status = "' + xhr.status + '")';
				sjWidgets.alert(errmsg);
			},
			success: function(data){
				if (typeof(backref.setLoadingState) == 'function')
					backref.setLoadingState(false);
				try {
					eval(data);
				}
				catch(e) {
					if (/isdvlpr_on=1;/.test(document.cookie))
						errmsg += ' (ошибка при обработке ответа с сервера: ' + e.message + ' at line ' + e.lineNumber + ' in ' + e.fileName + ')';
					sjWidgets.alert(errmsg);
				}
			},
			data: data,
			type: reqType
		});
	},
	'getFormData': function(form){
		var food = {};
		$(':input:not(:checkbox),input:checkbox:checked', form).each(function(){
			food[this.name] = this.value == this.title ? '' : $(this).val()
		});
		return food;
	},
	'marks': [],
	'notch': function(name){
		this.marks.push([name, new Date()]);
	},
	'printMarks': function(){
		if ($.browser.msie)
		{
			var msg = '';
			for (i in this.marks)
			{
				if (i > 0)
					msg +=
						this.marks[i-1][0] + ' to ' +
						this.marks[i][0] + ': ' +
						(this.marks[i][1].getTime() - this.marks[i-1][1].getTime()) + ' ms\n';
			}
			window.alert(msg);
		}
		else
		{
			for (i in this.marks)
			{
				if (i > 0)
					this.log(
						this.marks[i-1][0] + ' to ' +
						this.marks[i][0] + ': ' +
						(this.marks[i][1].getTime() - this.marks[i-1][1].getTime()) + ' ms'
					);
			}
		}
	},
	'log': function(message){
		if (typeof(window.console) == 'undefined')
			this.alert(message);
		else
			window.console.log(message);
	},
	'stop': function(){
		if ($.browser.msie)
			window.document.execCommand('Stop');
		else
			window.stop();
		return false;
	},
    'makeListSelect' : function() {
	new ListSelect($(this));
    }
};

//Правило для проверяльщика
function Rule() {};
Rule.prototype = {
	field : '', //Имя поля, которое проверяем
	required : false, //Обязательно ли это поле
	name : '',		  //Как это поле по-русски называется
	checkFunc : null  //Функция, которой это поле следует проверять. Если не задана - то и не проверяем
					  //Предполагается, что эта функция возвращает ошибку, если она есть
};

//Проверяльщик для форм
//$form - что проверяем (jQuery-объект),
//rules - массив объектов-правил для каждого поля
function formParser($form, rules) {
	this.$form = $form;
	this.rules = rules;
	this.results = [];   //Тут храним результаты
	this.parsed = false; //Тут храним флаг того, что уже проходили проверку
}

formParser.prototype = {

	//Установщик для правил
	setRules : function(rules) {
		this.rules = rules;
		this.results = [];
		this.parsed = false;
	},

	//Метод для разбора ошибок на форме
	parse : function() {
		//Если уже проходили проверку данной формы для данного набора правил - выходим
		if(this.parsed) {
			return;
		}

		this.results = [];

		for (var rule_index in this.rules) {
			var rule = this.rules[rule_index];
			var field_value = this.$form.find("[name='"+rule.field+"']").val();
			if(!field_value && rule.required) {
				this.results.push({field : rule.field, error: "Поле не заполнено."});
				continue;
			}
			if(typeof rule.checkFunc == "function") {
				var result = rule.checkFunc(this.$form, field_value);
				if(result) {
					this.results.push({field : rule.field, error: result});
					continue;
				}
			}
		}

		this.parsed = true;
	},

	getResults : function() {
		this.parse();
		return this.results;
	},

	valid : function() {
		this.parse();
		return (this.results.length === 0);
	},

	reset : function() {
		this.parsed = false;
	}
};

function cleanErrors($form, rules) {
	for (var rule_index in rules) {
		var rule = rules[rule_index];
		var field =
			$form.find("[name='"+rule.field+"']");
		field.removeClass('field_with_error');
		field.next('span.tiny_error').remove();
	}
}

function attachErrors($form, errors) {
	for (var error_index in errors) {
		var error = errors[error_index];
		var field = $form.find("[name='"+error.field+"']");
		field.addClass('field_with_error');
		field.after('<span class="tiny_error">'+error.error+'</span>');
	}
}
