var courtMain = {
	
	browser: {},
	
	
	/**
	 * Объявляем внутренние переменные и обработчики сообытий
	 */
	init: function() {
		//Объявляем событие загрузки общего объекта модулей court
		$(document).trigger('courtMainLoad');
		//Запоминаем данные по браузеру
		this.browser = $.browser;
	},
	
	
	/**
	 * Функция стилизует полосу прокрутки для элемента
	 * 
	 * @param obj	element
	 */
	setCustomScroll: function(element) {
		if (this.browser.msie && parseInt(this.browser.version) < 9) {
			//Для ИЕ ниже 9 версии устанавливаем обычный скролл
			$(element).css('overflow-y', 'auto');
			
		} else {
			//Устанавливаем стилизованный скролл
			fleXenv.fleXcrollMain(element);
		}
	},
	
	
	/**
	 * Функция устанавливает стилизованный скролл в начало элемента
	 * 
	 * @param obj	element
	 */
	resetCustomScroll: function(element) {
		if (!this.browser.msie || parseInt(this.browser.version) > 8) {
			//Для всех браузеров кроме ИЕ ниже 9 версии
			element.fleXcroll.setScrollPos(false,0);
		}
	},
	
	
	/**
	 * Функция устанавливает стилизованный скролл в начало элемента
	 * 
	 * @param obj	param.element
	 * @param int	param.margin
	 */
	setPosCustomScroll: function(param) {
		if (!this.browser.msie || parseInt(this.browser.version) > 8) {
			//Для всех браузеров кроме ИЕ ниже 9 версии
			param.element.fleXcroll.setScrollPos(false,param.margin);
		}
	},
	
	
	/**
	 * Функция устанавливает в поле placeholder для браузеров, 
	 * которые не отображжают данный атрибут
	 * 
	 * @param obj	$element
	 */
	setPlaceholder: function($element) {
		var name,
			version = parseInt(this.browser.version),
			except = {
				'msie': 10,
				'mozilla': 4,
				'opera': 11
			}
		
		for (name in except) {
			if (this.browser[name] && version < except[name]) {
				$element.inputDefaults();
			}
		}
	},
	
	
	/**
	 * Функция активирует событие клика по кастомному пункту списка,
	 * который соответствует переданному значению, для вызова всех связанных с ним события
	 * 
	 * @param obj	$field		Поле
	 * @param str	value		Значение поля
	 */
	setCustomLinkClick: function($field, value) {
		var $opt, index;
		
		if (value) {
			$opt = $field.children('option[value="'+value+'"]');
		} else {
			$opt = $field.children('option').first();
		}
		
		index = $opt.index();
		
		//Активируем событие клика по кастомному пункту списка и связанные с ним события
		$field
			.parent()
			.find('.js-select-custom-item').eq(index)
			.find('a')
			.trigger('click');
	}, 
	
	
	/**
	 * Функция проверяет поля на заполненность и правильность заполнения и возвращает результат
	 * 
	 * @param obj	$fields		Поля для проверки
	 * 
	 * @return bool
	 */
	setFieldsCheck: function($fields) {
		var i = 0, result = true;
		
		for (i; i < $fields.length; i++) {
			//Проверяем поле
			if (!this.validField($fields.eq(i))) {
				result = false;
			}
		}
			
		return result;
	},
	
	
	/**
	 * Функция устанавливает значения в переданные поля
	 * 
	 * @param obj	$fields		Поля
	 * @param obj	values		Значения
	 */
	setFieldsValue: function($fields, values) {
		var i = 0, $field, name;
		
		for (i; i < $fields.length; i++) {
			$field = $fields.eq(i);
			name = $field.attr('name');
			
			if (values[name]) {
				this.setFieldValue($field, values[name]);
			}
		}
	},
	
	
	/**
	 * Функция устанавливает значение в переданное поле
	 * 
	 * @param obj	$field		Поле
	 * @param obj	value		Значения
	 */
	setFieldValue: function($field, value) {
		if ($field.hasClass('ui-select--multi')) {
			//Устанавливаем значение и вызываем обработчик изменения поля
			$field.val(value).change();
			
		} else if ($field.hasClass('ui-select')) { 
			//Активируем событие по кастомному пункту списка, который соответствует значению
			this.setCustomLinkClick($field, value);
			
		} else if ($field.hasClass('ui-form-checkbox')) {
			if (value != 0 && !$field.attr('checked')) {
				//Ставим галочку на чекбокс
				$field.trigger('click');
			}
			
		} else {
			//Устанавливаем значение в поле
			$field.val(value);
		}
	},
	
	/**
	 * Функция устанавливает в поле сообщение
	 * 
	 * @param obj	$field		Поле, в которое нужно установить сообщение
	 * @param bool	isWarning	TRUE - сообщение о том, что поле нужно заполнить, FALSE - сообщение об ошибке
	 * @param str	message		Сообщение, которое нужно установить в поле
	 */
	setFieldError: function($field, isWarning, message) {
		var $block = $field.parent(),
			width = $block.width(),
			warning = width < 118 ? 'Укажите' : 'Заполните поле',
			error = width < 128 ? 'Неверно' : 'Неверный формат',
			selector = isWarning ? 'g-warning' : 'g-error';
			
		if (!message) {
			message = isWarning ? warning : error;
		}
		
		//Устанавливаем отметку в блок, в котором расположено поле
		$block.addClass(selector);
		//Устанавливаем сообщение в поле
		$field.val(message);
	},
	
	/**
	 * Функция блокирует поля
	 * 
	 * @param obj	$fields
	 */
	setFieldsDisabled: function($fields) {
		var i = 0;
		
		for (i; i < $fields.length; i++) {
			this.setFieldDisabled($fields.eq(i));
		}
	},
	
	/**
	 * Функция блокирует поле
	 * 
	 * @param obj	$field
	 */
	setFieldDisabled: function($field) {
		if (!$field.attr('disabled')) {
			$field.attr('disabled', true);
			
			if ($field.hasClass('ui-select')) {
				$field.trigger('change', true);
			} else if ($field.hasClass('js-textfield')) {
				$field.parent().addClass('b-textfield--disabled');
			} else if ($field.hasClass('ui-textarea')) {
				$field.parent().addClass('b-textarea--disabled');
			}
		}
	},
	
	
	/**
	 * Функция снимает сообщение об ошибке с поля
	 * 
	 * @param obj	$field
	 */
	resetFieldError: function($field) {
		var $block = $field.parent();
		
		if ($field.hasClass('ui-select')) {
			this.resetSelectError($field);
			
		} else if ($block.hasClass('g-error') || $block.hasClass('g-warning')) {
			//Снимаем отметки с блока, в котором расположено поле
			$block.removeClass('g-warning g-error');
			//Убираем сообщение в поле
			$field.val('');
		}
	},
	
	
	/**
	 * Функция снимает сообщение об ошибке со списка <select>
	 * 
	 * @param obj	$select
	 * @param str	value		Значние, которое нужно установить в поле
	 */
	resetSelectError: function($select, value) {
		var $block = $select.parent();
		
		value = value ? value : 'empty';
		
		if ($block.hasClass('g-error') || $block.hasClass('g-warning')) {
			//Снимаем отметки с блока, в котором расположено поле
			$block.removeClass('g-warning g-error');
			//Активируем событие по кастомному пункту списка, который соответствует значению
			this.setCustomLinkClick($select, value);
		}
	},
	
	
	/**
	 * Функция разблокировывает поля
	 * 
	 * @param obj	$fields
	 */
	resetFieldsDisabled: function($fields) {
		var i = 0;
		
		for (i; i < $fields.length; i++) {
			this.resetFieldDisabled($fields.eq(i));
		}
	},
	
	
	/**
	 * Функция разблокировывает поле
	 * 
	 * @param obj	$field
	 */
	resetFieldDisabled: function($field) {
		if ($field.attr('disabled')) {
			$field.attr('disabled', false);
			
			if ($field.hasClass('ui-select')) {
				$field.trigger('change', false);
			} else if ($field.hasClass('js-textfield')) {
				$field.parent().removeClass('b-textfield--disabled');
			} else if ($field.hasClass('ui-textarea')) {
				$field.parent().removeClass('b-textarea--disabled');
			}
		}
	},
	
	
	/**
	 * Функция возвращает текст элемента списка
	 * 
	 * @param obj	$select		Список
	 * @param str	value		Значение элемента списка
	 * 
	 * @return str
	 */
	getSelectOptText: function($select, value) {
		return $select.children('option[value="'+value+'"]').text();
	},
	
	
	/**
	 * Функция проверяет установлена ли в поле ошибка или предупреждение
	 * 
	 * @param obj	$field
	 * 
	 * @return bool
	 */
	isFieldError: function($field) {
		var $block = $field.parent();
		
		return $block.hasClass('g-error') || $block.hasClass('g-warning');
	},
	
	
	/**
	 * Функция проверяет правильность введенного e-mail адреса и заполненность поля
	 * 
	 * @param obj	$field		Поле для проверки
	 * 
	 * @return bool
	 */
	validField: function($field) {
		var result = true,
			$block = $field.parent();
		
		if ($block.hasClass('g-error') || $block.hasClass('g-warning')) {
			result = false;
			
		} else if (!$field.attr('disabled')) {
			if ($field.hasClass('mail-valid')) {
				//Проверяем правильность введенного e-mail адреса
				result = this.validMail($field);
				
			} else if ($field.hasClass('select-valid')) {
				//Проверяем заполненность списка
				result = this.validSelect($field);
				
			} else if ($field.hasClass('date-valid')) { 
				//Проверяем правильность введенной даты
				result = this.validDate($field);
				
			} else if ($field.hasClass('time-valid')) { 
				//Проверяем правильность введенного времени
				result = this.validTime($field);
				
			} else if ($field.hasClass('case-number-valid')) { 
				//Проверяем правильность введенного номер дела
				result = this.validCaseNumber($field);
				
			} else if ($field.hasClass('required')) {
				//Проверяем заполненность поля
				result = this.validValue($field);
			}
		}
		
		return result;
	},
	
	
	/**
	 * Функция проверяет правильность введенного e-mail адреса
	 * 
	 * @param obj		$field		Поле для проверки
	 * @param regexp	pattern		Регулярное выражение для проверки значения поля
	 * 
	 * @return bool
	 */
	validPattern: function($field, pattern) {
		var value = $field.val(),
			result = pattern.test(value);
		
		if (!result) {
			//Устанавливаем в поле сообщение об ошибке
			this.setFieldError($field, false);
		}
		
		return result;
	},
	
	
	/**
	 * Функция проверяет правильность введенного e-mail адреса
	 * 
	 * @param obj	$field		Поле для проверки
	 * 
	 * @return bool
	 */
	validMail: function($field) {
		var value = $field.val(),
			pattern = new RegExp("[a-z0-9!#$%&'*+\\/=?^_`{|}~-]+(?:.[a-z0-9!#$%&'*+\\/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?"),
			result = pattern.test(value.toLowerCase());
			
		if (!result) {
			//Устанавливаем в поле сообщение об ошибке
			this.setFieldError($field, false);
		}
		
		return result;
	},
	
	
	/**
	 * Функция проверяет заполненность списка <select>
	 * 
	 * @param obj	$select		Поле для проверки
	 * 
	 * @return bool
	 */
	validSelect: function($select) {
		var result = ($select.val() && $select.val() != 'empty') ? true : false;
			
		if (!result) {
			//Устанавливаем в поле сообщение об ошибке
			this.setFieldError($select, true);
		}
		
		return result;
	},
	
	
	/**
	 * Функция проверяет правильность введенного даты
	 * 
	 * @param obj	$field		Поле для проверки
	 * 
	 * @return bool
	 */
	validDate: function($field) {
		var value = $field.val(),
			result = Date.parse(value) ? true : false;
		
		if (!result) {
			//Устанавливаем в поле сообщение об ошибке
			this.setFieldError($field, false);
		}
		
		return result;
	},
	
	
	/**
	 * Функция проверяет правильность введенного времени
	 * 
	 * @param obj	$field		Поле для проверки
	 * 
	 * @return bool
	 */
	validTime: function($field) {
		var value = $field.val().split(':'),
			hour = (value[0] >= 0 && value[0] <= 23) ? true : false,
			min = (value[1] >= 0 && value[1] <= 59) ? true : false,
			result = hour && min ? true : false;
		
		if (!result) {
			//Устанавливаем в поле сообщение об ошибке
			this.setFieldError($field, false);
		}
		
		return result;
	},
	
	
	/**
	 * Функция проверяет правильность введенного номер дела
	 * 
	 * @param obj	$field		Поле для проверки
	 * 
	 * @return bool
	 */
	validCaseNumber: function($field) {
		var value = $field.val().toLowerCase(),
			pattern = new RegExp("^([аaф]\\d{2}п{0,1}\\-\\d+\\/\\d{2,4})$|^((сип|вас|с01)\\-\\d+\\/\\d{2,4})$|^(\\d{1,2}ап\\-\\d+\\/\\d{2,4})$"),
			result = pattern.test(value);
		
		if (!result) {
			//Устанавливаем в поле сообщение об ошибке
			this.setFieldError($field, false);
		}
		
		return result;
	},
	
	
	/**
	 * Функция проверяет заполненность поля
	 * 
	 * @param obj	$field		Поле для проверки
	 * 
	 * @return bool
	 */
	validValue: function($field) {
		var result = $field.val() ? true : false;
			
		if (!result) {
			//Устанавливаем в поле сообщение об ошибке
			this.setFieldError($field, true);
		}
		
		return result;
	},
	
	
	/**
	 * Функция очищает поля
	 * 
	 * @param obj	$fields
	 */
	clearFields: function($fields) {
		var i = 0;
		
		for (i; i < $fields.length; i++) {
			this.clearField($fields.eq(i));
		}
	},
	
	
	/**
	 * Функция очищает поле
	 * 
	 * @param obj	$field
	 */
	clearField: function($field) {
		var val, i, sum;
		
		if ($field.hasClass('ui-select--multi')) {
			val = $field.val();
			
			if (val) {
				for (i = 0, sum = val.length; i < sum; i++) {
					this.setCustomLinkClick($field, val[i]);
				}
				$field.val(null).trigger('change');
			}
		} else if ($field.hasClass('ui-select')) {
			//Определяем значение первого элемента списка
			val = $field
					.children()
					.first()
					.val();
			//Активируем событие по кастомному пункту списка, который соответствует значению
			this.setCustomLinkClick($field, val);
			
		} else if ($field.hasClass('ui-form-checkbox') && $field.attr('checked')) {
			//Снимаем галочку с чекбокса
			$field.trigger('click');
			
		} else {
			//Устанавливаем значение в поле
			$field.val('');
			//Устанавливаем в поле placeholder для старых браузеров
			this.setPlaceholder($field);
		}
		
		//Снимаем сообщение об ошибке с поля
		this.resetFieldError($field);
	}
}

$(function(){
	courtMain.init();
});