/*!
 * Умееет показывать таблицу постранично + умеет сворачивать/разворачивать (по клику на триггер).
 * Добавляет к таблице в футер строку с триггером сворачивания и ссылками на страницы.
 *
 * Usage:
 * $('table').tpaginator([params]);		// init
 * $('table').tpaginator('destroy');	// destroy
 *
 * params:
 *	pagenum				- начальная страница					(по умолчанию - 1)
 *	collapsed			- сколлапшено изначально или нет		(по умолчанию - true)
 *	linesPerPage		- количество строк на страницу			(по умолчанию - 10)
 *	linesCollapsed		- количество строк в свернутом виде		(по умолчанию - 4)
 *	textTrigger			- текст в триггера в развернутом виде	(по умолчанию - hide)
 *	textTriggerCollapsed- текст в триггера в свернутом виде		(по умолчанию - view more)
 *  lastTrClass         - класс навешиваемый на последнюю показываемую стоку - (по умолчанию - last)
 *
 * Requires:
 *  - jQuery 1.7+
 */
(function ($) {

	var pluginName = 'tpaginator';

	// Настройки по умолчанию
	var defaultData = {
		pagenum : 1,
		collapsed : true,
		linesPerPage : 10,
		linesCollapsed : 4,
		textTrigger : 'hide',
		textTriggerCollapsed : 'view more',
		lastTrClass : 'last'
	};

	// Обработчики событий
	var eventHandlers = {
		// При клике на циферку
		onLinkClick : function (e) {
			var num = $(this).html();
			curTop = e.data.$crumbs.offset().top - $(window).scrollTop();
			// При клике на '<<'
			if (num == '&lt;&lt;') {
				num = 1
					// При клике на '>>'
			} else if (num == '&gt;&gt;') {
				num = e.data.c.pagemax
			};
			pmethods.setState(e.data, parseInt(num), false);
			$(window).scrollTop(e.data.$crumbs.offset().top - curTop);
			return false;
		},
		// При клике на more/hide
		onMoreClick : function (e) {
			pmethods.toggle(e.data);
			return false;
		}
	}

	// Методы
	var pmethods = {
		// Ограничивает значение value
		constraint : function (value, min, max) {
			return Math.min(max, (Math.max(value, min)));
		},

		// Инициализация
		init : function (data) {

			// Все пересчитываеются, здесь написаны что бы NetBeans подсказки выдавал
			data.c = {
				colsnum : 3,
				rowcount : 100,
				pagemax : 10,
				pagenum : 1,
				collapsed : false
			};

			// Берем из опций стартовую страницу и сколлапшено или нет
			data.c.pagenum = data.s.pagenum;
			data.c.collapsed = data.s.collapsed;

			// Футер, куда сложим строку со страницами и кнопкой экпанда
			data.$foot = data.$this.children('tfoot');
			// Если футера нет добавляем
			if (data.$foot.size() == 0)
				data.$foot = data.$this.append('<tfoot class="js-tpaginator-foot"></tfoot>').children().last();

			// Добавляем разметку
			data.$foot.append(
				'<tr class="js-tpaginator-tr">' +
				'<td><a href="#" class="js-tpaginator-trigger"></a></td>' +
				'<td class="js-tpaginator-crumbs" colspan="' + (data.c.colsnum - 1) + '"></td>' +
				'</tr>');
			data.$crumbs = data.$foot.find('.js-tpaginator-crumbs');
			data.$trigger = data.$foot.find('.js-tpaginator-trigger');

			// jQuery-объект со всеми строками
			data.$rows = data.$this.children('tbody').children('tr');

			// Считаем состояние
			// Кол-во колонок в таблице
			data.c.colsnum = data.$this.children('thead').children('tr').first().children('td').size();
			// Общее количество строк
			data.c.rowcount = data.$rows.size();
			// Количество страниц
			data.c.pagemax = Math.ceil(data.c.rowcount / data.s.linesPerPage);

			pmethods.showState(data);

			// Навешиваем события
			data.$crumbs.on('click.' + pluginName, 'a', data, eventHandlers.onLinkClick);
			data.$trigger.on('click.' + pluginName, data, eventHandlers.onMoreClick);
		},

		// Возвращает html для crubs'ов \для текущего состояния
		renderCrumbs : function (data) {
			var cur,
			crumbs;
			if (data.c.pagemax > 7) {

				cur = pmethods.constraint(data.c.pagenum, 2, data.c.pagemax - 1);

				crumbs = [cur - 1, cur, cur + 1];

				if (cur > 4)
					crumbs.unshift('.');
				if (cur == 4)
					crumbs.unshift(2);
				if (cur > 2)
					crumbs.unshift(1);

				if (cur < data.c.pagemax - 3)
					crumbs.push('.');
				if (cur == data.c.pagemax - 3)
					crumbs.push(data.c.pagemax - 1);
				if (cur < data.c.pagemax - 1)
					crumbs.push(data.c.pagemax);

				// Иначе показываем все
			} else {
				crumbs = [];
				for (var i = 1; i <= data.c.pagemax; i++)
					crumbs.push(i);
			}

			// Добавляем '<<' в начало списка страниц
			crumbs.unshift('<<');
			// Добавляем '>>' в конец списка страниц
			crumbs.push('>>');

			var html = '';
			// Если всего одна страница, то пусто
			if (data.c.pagemax > 1) {
				for (var i = 0, l = crumbs.length; i < l; i++) {
					var num = crumbs[i];
					html += (num != '.')
					 ? ' <a href="#"' + (num == data.c.pagenum ? ' class="current"' : '') + '>' + num + '</a> '
					 : ' <span>...</span> ';
				}
			}
			return html;
		},

		// Меняет скрывает/показывает полную версию
		toggle : function (data) {
			pmethods.setState(data, data.c.pagenum, !data.c.collapsed);
		},

		// Выставляет state, если что-то при этом поменялось - вызывает showState
		setState : function (data, pagenum, collapsed) {
			var newPagenum = pmethods.constraint(pagenum, 1, data.c.pagemax),
			newCollapsed = !!collapsed;
			if ((newCollapsed != data.c.collapsed) || (newPagenum != data.c.pagenum)) {
				data.c.pagenum = newPagenum;
				data.c.collapsed = newCollapsed;
				pmethods.showState(data);
			}
		},

		// Показывает текущее состояние
		showState : function (data) {

			// Индексы с которого по который показывать
			var showFrom = (data.c.pagenum - 1) * data.s.linesPerPage, // не включительно
			showTo = showFrom + (data.c.collapsed ? data.s.linesCollapsed : data.s.linesPerPage);

			// Ставим/убираем класс collapsed на/с таблицы
			data.$this.toggleClass('collapsed', data.c.collapsed);
			// прячем всё, показываем нужный кусок
			data.$rows.removeClass(data.s.lastTrClass).hide()
			.slice(showFrom, showTo).show().last().addClass(data.s.lastTrClass);
			// Ставим текст триггера, показываем/ не показываем
			data.$trigger.text(data.c.collapsed ? data.s.textTriggerCollapsed : data.s.textTrigger)
			.toggle(data.c.rowcount > data.s.linesCollapsed);
			// Рендерим ссылки
			data.$crumbs.html(pmethods.renderCrumbs(data)).toggle(!data.c.collapsed);
		},

		// Вызвать, и всё вернется на круги своя
		destroy : function (data) {
			data.$rows.show().last().addClass(data.s.lastTrClass);
			data.$foot.children('.js-tpaginator-tr').remove();
			data.$foot.filter('.js-tpaginator-foot').remove();
			data.$crumbs.off('click.' + pluginName);
			data.$trigger.off('click.' + pluginName);
		}
	}

	// Публичные методы
	var methods = {
		init : function (options) {
			return this.each(function () {
				var $this = $(this),
				data = $this.data(pluginName);
				if (!data) {
					if (typeof textTriggerLocalize !== "undefined") {
						defaultData.textTrigger = textTriggerLocalize
					};
					if (typeof textTriggerCollapsedLocalize !== "undefined") {
						defaultData.textTriggerCollapsed = textTriggerCollapsedLocalize
					};
					data = {
						_id : pluginName + Math.floor(Math.random() * 999999)
					};
					data.$this = $this;
					data.s = $.extend(true, {}, defaultData, options);
					pmethods.init(data);
				}
				$this.data(pluginName, data);
			});
		},
		destroy : function () {
			return this.each(function () {
				var $this = $(this),
				data = $this.data(pluginName);
				if (data) {
					pmethods.destroy && pmethods.destroy(data);
					$this.removeData(pluginName);
				}
			})
		}
	};

	// Подключение плагина
	$.fn[pluginName] = 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.' + pluginName);
		}
	};

})(jQuery);

$(function () {

	initMenu();
	initTables();
	scrollSpy();
	$('#print').click(function () {
		window.print()
	});

});

/**
 * Обеспечивает переключение меню при прокрутке страниц
 */
function scrollSpy() {
	$(window)
	.on('scroll', function (event) {
		var top = $(window).scrollTop();
		var delta = -125;

		$('.block').each(function () {
			var position = $(this).position();

			if (top >= (position.top + delta) && top <= (position.top + $(this).height() + delta)) {
				$('a', '#primary-links').removeClass('active');
				$('a[href="#' + $(this).attr('id') + '"]', '#primary-links').addClass('active');
			}

		});
	});
}

/**
 * Обеспечивает работу меню навигации
 */
function initMenu() {
	/**
	 * клика по пунктам меню
	 */
	$('a', '#primary-links')
	.on('click', function () {
		// определяем требуемый блок
		var id = $(this).attr('href');

		// координаты блока
		var offset = $(id).offset();

		// прокручиваем страницу
		$.scrollTo((offset.top - 80), 500);

		return false;
	});

}

/**
 *
 */
function initTables() {
	$('table.standart').tpaginator();
}
