function TopFilters($mainElement, options) {
	if (!$mainElement instanceof jQuery) {
		throw new Error('First argument must be type of jQuery');
	}

	var opts = {
		filtersHolderWrapSelector: '.top-filters-holder-wrap',
		filtersHolderSelector: '.top-filters-holder',
		rightNavSelector: '.top-filters-right-nav',
		leftNavSelector: '.top-filters-left-nav',
		filterItemWrapSelector: '.top-filter-item-wrap',
		filterItemSelector: '.filter-item',
		filterItemActiveSelector: '.filter-item-active',
		subCatsLeftSideListSelector: '.sub_cat_list',
		navWrapSelector: '.top-filters-nav',
		navLeftControlSelector: '.top-filters-left-nav',
		navRightControlSelector: '.top-filters-right-nav',
		navLeftControlIconClass: 'icon-arrow-left',
		navRightControlIconClass: 'icon-arrow-right',
		animationSpeed: 700,
		appearControlsAnimationSpeed: 500,
		appearSliderAnimationSpeed: 250,
		filterItemLeftOffset: 50,
		additionItemWidth: 30,
		scrollItemsCount: 3,
		itemsOffset: 3,
		isMobile: false,
		items: []
	};

	var isLocked,
		scrollPosition,
		defaultScrollPosition,
		filterItemsStartLeftPoint,
		maxScrollPosition,
		navigationWidth,
		elementsPositions,
		currentFirstItemIdx,
		isResizeEventsBound = false,
    activeItemId = 0;

	/**
	 * Инициализация слайдера фильтров
	 */
	function _init(options) {
		_destroy();

		for (var key in options) {
			if (options.hasOwnProperty(key)) {
				opts[key] = options[key];
			}
		}

		_makeSlider();
		_bindEvents();

		if (typeof $(opts.leftNavSelector) !== 'undefined' && $(opts.leftNavSelector).length) {
			filterItemsStartLeftPoint = parseInt($(opts.leftNavSelector).offset().left) + opts.filterItemLeftOffset;
		}

		if (typeof $(opts.filtersHolderWrapSelector) !== 'undefined' && $(opts.filtersHolderWrapSelector).length) {
			scrollPosition = defaultScrollPosition = parseInt($(opts.filtersHolderWrapSelector).scrollLeft());
		}
	}

	function _onScreenResize() {
		if (typeof window.reInitTopFiltersTimer !== 'undefined') {
			clearTimeout(window.reInitTopFiltersTimer);
		}

		window.reInitTopFiltersTimer = setTimeout(function() {
			_init(options);
		}, 300);
	}

	function _bindEvents() {
		$mainElement.off('click', opts.rightNavSelector);
		$mainElement.off('click', opts.leftNavSelector);
		$mainElement.off('click', opts.filterItemSelector);
		$mainElement.on('click', opts.rightNavSelector, _scrollRight);
		$mainElement.on('click', opts.leftNavSelector, _scrollLeft);
		$mainElement.on('click', opts.filterItemSelector, _onClickFilterItem);

		if (!isResizeEventsBound) {
			if (opts.isMobile) {
				window.addEventListener("orientationchange", function() {
					_onScreenResize()
				}, false);
			} else {
				$(window).on('resize', function() {
					_onScreenResize()
				});
			}
			isResizeEventsBound = true;
		}
	}

	/**
	 * Возвращает индекс элемента, до которого нужно проскроллить
	 *
	 * @param receivedArgs
	 * @param operation
	 * @private
	 */
	function _getCurrentFirstItemIdx(receivedArgs, operation) {
		var args = Array.prototype.slice.call(receivedArgs, 1, 2),
			needIdx;
		if (args.length && args[0] === parseInt(args[0], 10)) {
			needIdx = parseInt(args[0]) - opts.itemsOffset;
			needIdx = needIdx > 0 ? needIdx : 0;
		} else if (operation === '+') {
			needIdx = currentFirstItemIdx + opts.scrollItemsCount;
		} else if (operation === '-') {
			needIdx = currentFirstItemIdx - opts.scrollItemsCount;
		}

		return needIdx;
	}

	/**
	 * Действия, которые выполнятся при нажатии на кнопку прокрутки/стрелку вправо
	 *
	 * @param e
	 * @private
	 */
	function _scrollRight(e) {
		var el = $(e.target).is('i') ? $(e.target).closest('div') : $(e.target);
		if (!isLocked && !el.hasClass('nav-hidden')) {
			isLocked = true;
			$(opts.leftNavSelector)
				.removeClass('nav-hidden')
				.animate({
					opacity: 1
				}, opts.appearControlsAnimationSpeed);

			currentFirstItemIdx = _getCurrentFirstItemIdx(arguments, '+');

			var elementPosition;
			if (typeof elementsPositions[currentFirstItemIdx] !== 'undefined') {
				elementPosition = elementsPositions[currentFirstItemIdx];
			} else {
				var keys = Object.keys(elementsPositions);
				elementPosition = elementsPositions[keys[keys.length - 1]];
			}

			scrollPosition = elementPosition.left;

			if (scrollPosition >= maxScrollPosition) {
				scrollPosition = maxScrollPosition;

				$(opts.rightNavSelector)
					.addClass('nav-hidden')
					.animate({
						opacity: 0
					}, opts.appearControlsAnimationSpeed);
			}

			$(opts.filtersHolderWrapSelector).animate({
				scrollLeft: scrollPosition
			}, opts.animationSpeed, function() {
				isLocked = false;
			});
		}
	}

	/**
	 * Действия, которые выполнятся при нажатии на кнопку прокрутки/стрелку влево
	 *
	 * @param e
	 * @private
	 */
	function _scrollLeft(e) {
		var el = $(e.target).is('i') ? $(e.target).closest('div') : $(e.target);
		if (!isLocked && !el.hasClass('nav-hidden')) {
			isLocked = true;

			currentFirstItemIdx = _getCurrentFirstItemIdx(arguments, '-');
			currentFirstItemIdx = currentFirstItemIdx < 0 ? 0 : currentFirstItemIdx;

			if (currentFirstItemIdx === 0) {
				$(opts.leftNavSelector)
					.addClass('nav-hidden')
					.animate({
						opacity: 0
					}, opts.appearControlsAnimationSpeed);
			}

			var elementPosition;
			if (typeof elementsPositions[currentFirstItemIdx] !== 'undefined') {
				elementPosition = elementsPositions[currentFirstItemIdx];
			} else {
				var keys = Object.keys(elementsPositions);
				elementPosition = elementsPositions[keys[0]];
			}

			scrollPosition = elementPosition.left;

			if (scrollPosition < maxScrollPosition) {
				if (parseInt($(opts.rightNavSelector).css('opacity')) === 0) {
					$(opts.rightNavSelector)
						.removeClass('nav-hidden')
						.animate({
							opacity: 1
						}, opts.appearControlsAnimationSpeed);
				}
				$(opts.filtersHolderWrapSelector).animate({
					scrollLeft: scrollPosition
				}, opts.animationSpeed, function() {
					if (currentFirstItemIdx === 0) {
						scrollPosition = defaultScrollPosition;
					}
					isLocked = false;
				});
			} else {
				isLocked = false;
			}
		}
	}

	/**
	 * Действия, которые выполняются при клике на элемент фильтра
	 *
	 * @param e
	 * @private
	 */
	function _onClickFilterItem(e) {
		var el = $(e.target),
			  landId = el.data('land-id'),
        landSeo = el.data('land-seo');

		$(opts.filterItemSelector).filter(opts.filterItemActiveSelector).removeClass(opts.filterItemActiveSelector.substring(1));
		el.addClass(opts.filterItemActiveSelector.substring(1));
		$(opts.subCatsLeftSideListSelector).find('[data-land-id="' + landId + '"],[data-subattr-id="' + landId + '"]').trigger('click');

    $('#indexpresearchblock').html('<div style="height: 50px;position:relative;margin-top: 50px;"><div class="preloader__ico preloader__ico_small"></div></div>');

    $.get('index.php?indexcategory=' + landSeo, function(data) {
      $('#indexpresearchblock').html(data);
    });
	}

	/**
	 * Устанавливает активный фильтр и при необходимости скроллит до него
	 * @param itemId
	 */
	function setActiveFilter(itemId) {
		$(opts.filterItemSelector).filter(opts.filterItemActiveSelector).removeClass(opts.filterItemActiveSelector.substring(1));
		var targetItem = $mainElement.find(opts.filterItemSelector + '[data-land-id="' + itemId + '"]'),
			targetItemIdx = targetItem.index();

		if ((currentFirstItemIdx + 3) < targetItemIdx && $(opts.rightNavSelector).length) {
			_scrollRight($(opts.navRightControlSelector), targetItemIdx);
		} else if ($(opts.leftNavSelector).length) {
			_scrollLeft($(opts.navRightControlSelector), targetItemIdx);
		}

		targetItem.addClass(opts.filterItemActiveSelector.substring(1));
	}

	/**
	 * Подготовка и рендеринг слайдера
	 */
	function _makeSlider() {
		var holderWrap = $('<div></div>', {
				'class': opts.filtersHolderWrapSelector.substring(1)
			}),
			filtersHolder = $('<div></div>', {
				'class': opts.filtersHolderSelector.substring(1)
			}),
			itemWrap = $('<div></div>', {
				'class': opts.filterItemWrapSelector.substring(1)
			}),
			itemsCount = Object.keys(opts.items).length;

		if (!itemsCount) {
			console.warn("Elements isn't set to top-filters slider");
			return;
		}

		// Создание элементов слайдера
		for (var i in opts.items) {
			if (opts.items.hasOwnProperty(i)) {
				var additionClass = '';
				if (parseInt(activeItemId) === parseInt(opts.items[i].id)) {
					additionClass = ' ' + opts.filterItemActiveSelector.substring(1);
					activeItemId = null;
				}
				var item = $('<div></div>', {
					'class': opts.filterItemSelector.substring(1) + additionClass,
					'text': typeof opts.items[i].title !== 'undefined' ? opts.items[i].title : opts.items[i].seo,
					'data-land-id': opts.items[i].id,
          'data-land-seo': opts.items[i].seo
				});
				itemWrap.append(item);
			}
		}

		filtersHolder.append(itemWrap);
		holderWrap.append(filtersHolder);
		$mainElement.append(holderWrap);

		var itemsCommonWidth = parseInt($(opts.filterItemWrapSelector).innerWidth()) + (itemsCount * opts.additionItemWidth);
		navigationWidth = parseInt($mainElement.innerWidth());

		if (itemsCommonWidth > navigationWidth) {
			var navWrap = $('<div></div>', {
					'class': opts.navWrapSelector.substring(1)
				}),
				leftNavControl = $('<div></div>', {
					'class': opts.navLeftControlSelector.substring(1)
				}),
				rightNavControl = $('<div></div>', {
					'class': opts.navRightControlSelector.substring(1)
				});

			leftNavControl.append($('<i></i>', {
				'class': opts.navLeftControlIconClass
			}));
			rightNavControl.append($('<i></i>', {
				'class': opts.navRightControlIconClass
			}));
			navWrap.append(leftNavControl).append(rightNavControl);
			$mainElement.append(navWrap);
		} else {
			var needMargin = (navigationWidth - itemsCommonWidth) / 2;
			filtersHolder.css('margin-left', (needMargin + 'px'));
		}

		$mainElement.find(opts.filterItemSelector).each(function(index) {
			var needWidth = parseInt($(this).innerWidth()) + opts.additionItemWidth;
			$(this).css('width', needWidth + 'px');
			var positionLeft = parseInt($(this).position().left) - parseInt($(opts.leftNavSelector).innerWidth()) - parseInt($(this).css('margin-right'));
			elementsPositions[index] = {
				left: positionLeft,
				right: positionLeft + needWidth,
				center: positionLeft + (needWidth / 2),
				width: needWidth
			};
		});

		var lastItemHRPosition = $mainElement.find(opts.filterItemSelector).last().position().left,
			  lastItemWidth = $mainElement.find(opts.filterItemSelector).last().outerWidth();

		// Раскомментировать после того, как будет устранен баг с утечкой памяти при скролле на вложенных элементах,
		//  когда обыкновенный скролл расценивается как свайп
		//
		// if (opts.isMobile) {
		//     $(opts.filtersHolderSelector).css('width', (itemsCommonWidth + 10) + 'px');
		//     $(opts.filtersHolderWrapSelector).css('overflow-x', 'auto');
		// }

		maxScrollPosition = lastItemHRPosition + lastItemWidth - navigationWidth;

		$mainElement.animate({
			opacity: 1
		}, opts.appearSliderAnimationSpeed).css('margin-top', '0');
	}

	function _destroy() {
		$mainElement.css('opacity', 0).empty();
		isLocked = false;
		scrollPosition = 0;
		defaultScrollPosition = 0;
		filterItemsStartLeftPoint = 0;
		maxScrollPosition = 0;
		navigationWidth = 0;
		currentFirstItemIdx = 0;
		elementsPositions = {};

		return this;
	}

	_init(options);

	return {
		destroy: _destroy,
		refresh: _init,
		setActiveFilter: setActiveFilter,
	}
}