(function ($) {
	var methods = {
		init: function (options) {
			var buttons_array = [], settings = {
				'items': '.RotatorItem',
				'visibleCount': 1, // Количество видимых элементов
				'changeCount': 1, // Количество меняющихся элементов 
				'speed': 1000, // Скорость прокрутки одного слайда
				'prev': null, // Селектор кнопки "Назад"
				'next': null, // Селектор кнопки "Вперед"
				'navigation': null, // Селектор для навигационного бара
				'navDrawPageNumber': false,
				'navPageTemplate': '<a href="#$n"><span>$i</span></a>', // Шаблон для кнопкив навигаторе
				/*'useSwipeTouch': false,*/ // Прокрутка слайдов по тачпадовским жестам. Для работы необходим jQuery Swipe
				'useHashUrl' : false, // Для каждого слайда свой урл, не включать более 1 ротатора на страницу с этим параметром.
                'onMoveComplete': false // Функция, вызываемая после завершения анимации шага
			};
			if (options) {
				$.extend(settings, options);
			}
			if (settings.changeCount > settings.visibleCount) {
				settings.changeCount = settings.visibleCount;
			}
			if (settings.prev) { buttons_array.push(settings.prev); }
			if (settings.next) { buttons_array.push(settings.next); }
			settings.buttons_selector = buttons_array.join(', ');
			var items_count = this.children(settings.items).length;
			if (settings.visibleCount > items_count) { settings.visibleCount = items_count; }
			var page_count = Math.ceil(items_count / settings.changeCount),
				block_count = Math.ceil(items_count / settings.visibleCount) + 1,
				container_width = 100 * block_count,
				items_width = 100 / (block_count * settings.visibleCount);
			this.settings = settings;
			this.data('settings', settings)
				.data('info', {
					'items_count': items_count,
					'container_width': container_width,
					'block_count': block_count,
					'items_width': items_width
				}).children(settings.items).css('width', items_width + '%').wrapAll('<div style="width: ' + container_width + '%;" class="RotatorContainer" />').each(function (i) { $(this).data('index', i + 1); });
			var wrapper = this;
			var title = document.title; // IE9 меняет заголовок
			return this.eq(0).each(function () {
				//Прокрутка навигатором
				if (items_count <= settings.visibleCount) {
					$(settings.buttons_selector).hide();
					$(settings.navigation).hide();
				} else {
					if (settings.useHashUrl) {
						//проставляем стрелкам урлы с хэшами при инициализации ротатора
						//console.log("ставим хэши на кнопки влево/вправо");
						$(settings.prev).attr("href", "#" + getPrevPageNumber(1, page_count));
						$(settings.next).attr("href", "#" + getNextPageNumber(1, page_count));
					} else {
						// Обработчик кнопок "Влево", "Вправо"
						//console.log("ставим обработчики на кнопки влево/вправо");
						$(settings.buttons_selector).click(function () {
							wrapper.rotator('move', ($(this).is(settings.prev)) ? 'prev' : 'next');
							return false;
						});
					}
					if (settings.navigation) {
						var pages_in_page = [];
						if (page_count > 1) {
							for (var i = 0; i < page_count; i++) {
								pages_in_page = [];
								for (var j = i * settings.changeCount + 1; j < ((i + 1) * settings.changeCount + 1); j++) {
									pages_in_page.push(j);
								}
								var tmp_obj = $(settings.navPageTemplate.replace("$i", (i + 1))).data('page', i).data('items', pages_in_page);
								// ставим каждой кнопке в навбаре ссылки-хэши
								if (settings.useHashUrl) {
									tmp_obj.attr("href", "#" + (i + 1));
								}
								if (settings.navDrawPageNumber) {
									tmp_obj.html(i + 1);
								}
								$(settings.navigation).append(tmp_obj);
							}
							$(settings.navigation + ' > a:first').addClass('Active');
							if (!settings.useHashUrl) {
								$(settings.navigation + ' > a').click(function () {
									//console.log("клик по кнопке навбара");
									if ($(wrapper).data('animating') || $(this).hasClass('Active')) {
										return false;
									};

									var is_next = parseInt($(this).siblings('.Active:first').data('page'), 10) < parseInt($(this).data('page'), 10);
									$(this).siblings().removeClass('Active');
									$(this).addClass('Active');
									wrapper.rotator('move', $(this).data('items')[0], is_next);
									return false;
								});
							}
						}
					}
				}
				if (settings.useHashUrl) { 
					$(window).bind("hashchange", function() {
						var hash = get_fragment(location.href);
						//var hashLen = hash.length;
						var isHashEmpty = (hash.length == 0);
						if (isHashEmpty || hash) {
							//console.log("hash changed to " + hash);
							if (!wrapper.data('animating')) {
								document.title = title;
								wrapper.rotator('move', isHashEmpty ? '1' : '' + hash, true);
							} else {
								//console.log("сменился хэш, в то время как ротатор анимируется, игнор");
								//можно не давать менять хэш во время анимации слайдера, этим вылечится быстрое переключение слайдов
							}
						}
					});
				}
				/*if (settings.useSwipeTouch) {
					$(settings.items).swipe({
						swipeLeft: function () { wrapper.rotator('move', 'next'); },
						swipeRight: function () { wrapper.rotator('move', 'prev'); }
					});
				}*/
				// проверка на наличие хэша при загрузке страницы
				setTimeout(function(){$(window).hashchange()}, 200);
			});
		},
		move: function (end_index, is_next) {
			//console.log("начинаем переход на новый слайд " + end_index);
			var wrapper = this;
			if ($(wrapper).data('animating')) {
				//console.log("попытка сменить страницу пока слайдер анимируется");
				return false;
			}
			$(wrapper).data('animating', true);
			//console.log("поставили статус анимируется");
			var rotator_container = this.children(".RotatorContainer"),
				settings = $(this).data('settings'),
				info = $(this).data('info'),
				after_animate_css = { 'margin-left': 0, 'left': 0 },
				current_rotator = rotator_container.children(settings.items + ":visible:first"),
				start_index = current_rotator.data('index');
			if (end_index == 'prev' || end_index == 'next') {
				var step = settings.changeCount,is_prev = (end_index == 'prev');
			} else {
				var step = Math.abs(start_index - end_index),step = (step > info.items_count / 2) ? info.items_count - step : step;
				value_right = (start_index + step) % info.items_count,value_right = (value_right == 0) ? info.items_count : value_right,is_prev = (value_right != end_index);
				if (step == info.items_count / 2) {
					is_prev = !is_next;
				}
				if (start_index == end_index) {
					//console.log("старт = финиш");
					$(wrapper).removeData('animating');
					return this;
				}
			}
			var move_by = step * 100 / settings.visibleCount,container_shift = ((is_prev) ? '+' : '-') + '=' + move_by + '%';
			if (is_prev) {
				// Движение слайдов влево. Предыдущие слайды.
				next_rotators = current_rotator.prevAll(settings.items).slice(0, step); // Запрос на нужное количество предыдущих слайдов
				if (next_rotators.length < step) {
					// Предыдущих слайдов меньше чем требуется, значит надо перенести из конца
					var need_rotators = step - next_rotators.length; // Количество слайдов для переноса из конца в начало
					$(rotator_container.children(settings.items).slice(-need_rotators).get().reverse()).each(function () {
						next_rotators.add($(this).attr('is_clone', 'true').clone(true).prependTo(rotator_container).removeAttr('is_clone'));
					});
				}
				// Из-за того, что вперед были добавлены слайды, теперь надо вернуть начальную позицию ротатора обратным смещением
				rotator_container.css({ 'margin-left': -info.items_width * step * info.block_count + '%' });
			} else {
				// Движение слайдов вправо. Следующие слайды.
				current_rotator.nextAll(settings.items + ":hidden").show(); //Показать все следующие
				next_rotators = current_rotator.nextAll(settings.items).slice(step - 1, step + settings.visibleCount - 1); // Запрос на нужное количество следующих слайдов
				//if (next_rotators.length < settings.visibleCount) {
				if (next_rotators.length < Math.max(settings.visibleCount, step)) {
					//Следующих слайдов меньше чем требуется, значит надо перенести из начала
					//var need_rotators = settings.visibleCount - next_rotators.length;
					var need_rotators = Math.max(settings.visibleCount, step) - next_rotators.length;
					rotator_container.children(settings.items).slice(0, need_rotators).each(function () {
						if ($(this).is(":visible")) {
							next_rotators.add($(this).attr('is_clone', 'true').clone(true).appendTo(rotator_container).removeAttr('is_clone'));
						}
						else {
							next_rotators.add($(this).detach().appendTo(rotator_container).show());
						}
					});
				}
			}
			if (next_rotators.length > 0) {
				next_rotators.show();
			}
			rotator_container.animate({ left: container_shift },settings.speed,function () {
				//console.log("завершена анимация, обновляем данные");
				if (!is_prev) {
					rotator_container.children(settings.items + ":visible").slice(0, step).hide(); //Если были показаны слудующие слайды, то надо скрыть все, в настоящий момент предудущие
				}
				var sel_nav_page = parseInt(rotator_container.children(settings.items + ":visible:first").data('index'), 10);
				if (settings.navigation) {
					$(settings.navigation + ' > a').removeClass('Active').each(function () {
						if (jQuery.inArray(sel_nav_page, $(this).data('items')) > -1) {
							$(this).addClass('Active');
						}
					});
				}
				if (settings.useHashUrl) {
					//var sel_nav_page_temp = parseInt(rotator_container.children(settings.items + ":visible:first").data('index'), 10),
						prev_index = ((sel_nav_page > 1) ? (sel_nav_page-1) : info.items_count),
						next_index = ((sel_nav_page < info.items_count) ? (sel_nav_page+1) : 1);
					//console.log("проставляем новые хэши кнопкам влево/вправо после перехода на новый слайд...");
					$(settings.prev).attr("href", "#" + prev_index);
					$(settings.next).attr("href", "#" + next_index);
				}
				rotator_container.children(settings.items + '[is_clone=true]').detach();
				rotator_container.css(after_animate_css);
				//console.log(settings.onMoveComplete);
                if (settings.onMoveComplete && typeof(settings.onMoveComplete) == 'function') {
                    settings.onMoveComplete();
                }
				if (settings.useHashUrl) { //хак устраняет баг с быстрым переключением слайдов
					location.href = location.href.replace( /#.*/, '' ) + "#" + sel_nav_page;
				}
                $(wrapper).removeData('animating');
                //console.log("завершена анимация ротатора");
			});
		}/*,
		readURL: function (state) {
			var wrapper = this;
			var is_next = parseInt($(this).siblings('.Active:first').data('page'), 10) < parseInt($(this).data('page'), 10);
			wrapper.rotator('move', state, is_next);
		}*/
	};
	function getPrevPageNumber(page_number, page_count) {
		return (page_number>1) ? (page_number-1) : page_count;
	}
	function getNextPageNumber(page_number, page_count) {
		return (page_number < page_count) ? (page_number+1) : 1;
	}
	function get_fragment( url ) {
		//console.log("sanitizing");
		url = url || location.href;
		return '' + url.replace( /^[^#]*#?(.*)$/, '$1' );
	};
	$.fn.rotator = function (method) {
		if (methods[method]) {
			return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
		} else if (typeof method === 'object' || !method) {
			return methods.init.apply(this, arguments);
		} else {
			$.error('Method ' + method + ' does not exist on jQuery.rotator');
		}
	};
})(jQuery);
