// функция инициализирует горизонтальную галерею
// Параметры на входе:
// container - блок, в котором будет листаться галерея
// navClass - класс навигационных кнопок, у каждой кнопки при этом должны быть классы .next и .prev
// cyclic - Циклическая ли галерея (true - да, false - нет)
// scrolling - Использовать ли скроллинг (true - да, false - нет) ЗЫ: надо еще подключать jquery.mousewheel.js
// itemWidth - параметр, который отвечает за то, будет ли ширина одного элемента фиксированной 
// 			   или же она будет тянуться по ширине родительского контейнера, возможные параметры fixed/auto
// blockWidth - блок, по которому надо определять ширину галереи, возможные параметры parent/self (parent - родитель от container, self - по ширине самого container)
// wrapGallery - если определен параметр itemWidth в значение fixed, то указывается враппер для карусели
// staticItemWidth - если определен параметр itemWidth в значение fixed, то указывается ширина элемента галереи
function initHGallery(container, navClass, cyclic, scrolling, itemWidth, blockWidth, wrapGallery, staticItemWidth)
{
	$(container).each(function(){
		var cont = this;
		
		$(cont).find(navClass).removeClass('no-active');
		
		// переводим галерею в состояние 'free'
		$(this).data('state', 'free');
		// установка ширины и количества отображаемых элементов галереи
		setHGalWidth(this, cyclic, itemWidth, blockWidth, wrapGallery, staticItemWidth);
		if (itemWidth == 'auto')
		{
			$(window).resize(function(){
				setHGalWidth(cont, true, itemWidth, blockWidth, wrapGallery, staticItemWidth);
			});
		}
		
		// регистрация обработчиков событий нажатия на кнопки навигации
		if ($(cont).data('countVisible') > $(cont).find('ul li').length)
		{
			$(cont).find(navClass).addClass('no-active');
		}
		$(cont).find(navClass).click(function(){
			if (!$(this).hasClass('no-active'))
			{
				if ($(cont).data('countVisible') < $(cont).find('ul li').length)
				{
					var step = ($(this).hasClass('prev')) ? -1 : (($(this).hasClass('next')) ? 1 : 0);
					if (cyclic)
					{
						moveHGal(cont, step);
					}
					else
					{
						moveNoCyclicHGal(cont, step);
					}
				}
				else
				{
					// иначе сдвигаем список на начало и деактивируем кнопки навигации
					$(cont).find('ul').css({"left": "0px"});
					$(cont).find(navClass).addClass('no-active');
				}
			}
			return false;
		});
		if (scrolling)
		{
			$(cont).bind('mousewheel', function(event, delta){
				if($(cont).data('state') == 'free')
				{
					if (delta > 0)
					{
						curNavClass = '.prev';
					}
					else
					{
						curNavClass = '.next';
					}
					if (!$(cont).find(curNavClass).hasClass('no-active'))
					{
						$(cont).find(curNavClass).trigger('click');
					}
					return false;
				}
			});
		}
	});
}

// функция циклично двигает галерею на одну позицию влево или вправо, в зависимости от шага
function moveHGal(container, step)
{
	if ($(container).data('state') == 'free')
	{
		// переводим галерею в состояние 'busy'
		$(container).data('state', 'busy');
		
		// говорим, что первый элемент по-умолчанию еще не скопирован
		$(container).data('hasCopy', false);
		
		// проверяем, если сдвигаем вправо, то нужно проверить находимся ли мы в конце галереи, если в конце, то скрываем кнопку
		if (step > 0)
		{
			// если количество всех элементов больше отображаемых в карусели ровно на 1, то нужно перекинуть первый элемент еще до анимации,
			// чтобы не было задержки при загрузке
			if (($(container).find('ul li').length - $(container).data('countVisible')) == 1)
			{
				$(container).data('hasCopy', true);
				$(container).find('ul').append('<li>'+$(container).find('ul li:first').html()+'</li>');
			}
		}
		
		// двигаем в нужную сторону галерею и потом устанавливаем последний/первый элемент в начало/конец
		$(container).find('ul').animate(
			{"left" : ((-$(container).data('itemWidth'))-(step * $(container).data('itemWidth')))+"px"},
			"fast",
			function(){
				// если двигали вперед, то первый элемент галереи перекинем в конец
				if (step > 0)
				{
					// если у нас первый элемент уже скопирован в конец, то просто удаляем его
					if ($(container).data('hasCopy'))
					{
						// удаляем первый элемент
						$(container).find('ul li:first').remove();
					}
					else
					{
						// переносим первый элемент в конец списка
						$(container).find('ul li:first').appendTo($(container).find('ul'));
					}
				}
				// если двигали назад, то последний элемент галереи перекинем в начало
				else
				{
					$(container).find('ul li:last').prependTo($(container).find('ul'));
				}
				$(container).find('ul').css({"left" : (-$(container).data('itemWidth'))+"px"});
				$(container).data('state', 'free');
			}
		);
	}
}

// функция нециклично двигает галерею на одну позицию влево или вправо, в зависимости от шага
function moveNoCyclicHGal(container, step)
{
	if ($(container).data('state') == 'free')
	{
		// переводим галерею в состояние 'busy'
		$(container).data('state', 'busy');
		
		// находим позицию галереи
		var leftPos = $(container).find('ul').css('left');
		leftPos = leftPos.replace("px", '');
		leftPos = parseInt(leftPos);
		var commonWidth = $(container).data('itemWidth')*$(container).data('countVisible') - leftPos;
		
		var canMove = false;
		
		// при сдвиге проверяем, можем ли мы еще двигать в эту сторону, если нет, то скрываем соответствующую кнопку
		if ((step > 0) && (($(container).data('allWidth') - commonWidth) >= $(container).data('itemWidth')))
		{
			canMove = true;
		}
		else if((step < 0) && (Math.abs(leftPos) >= $(container).data('itemWidth')))
		{
			canMove = true;
		}
		
		if (canMove)
		{
			// двигаем в нужную сторону галерею и потом устанавливаем последний/первый элемент в начало/конец
			$(container).find('ul').animate(
				{"left" : (leftPos - step*$(container).data('itemWidth'))+"px"},
				"fast",
				function(){
					commonWidth = commonWidth + step*$(container).data('itemWidth');
					leftPos = $(container).find('ul').css('left');
					leftPos = leftPos.replace("px", '');
					leftPos = parseInt(leftPos);
					
					if (($(container).data('allWidth') - commonWidth) >= $(container).data('itemWidth'))
					{
						$(container).find('.next').removeClass('no-active');
					}
					else
					{
						$(container).find('.next').addClass('no-active');
					}
					
					if(Math.abs(leftPos) >= $(container).data('itemWidth'))
					{
						$(container).find('.prev').removeClass('no-active');
					}
					else
					{
						$(container).find('.prev').addClass('no-active');
					}
				}
			);
		}
		else
		{
			if (step > 0)
			{
				$(container).find('.next').addClass('no-active');
			}
			else
			{
				$(container).find('.prev').addClass('no-active');
			}
		}
		$(container).data('state', 'free');
	}
}

// функция устанавливает ширину галереи и количество отображаемых элементов в ней
function setHGalWidth(container, cyclic, itemWidth, blockWidth, wrapGallery, staticItemWidth)
{
	if (itemWidth == 'auto')
	{
		$(container).data('galWidth', $(container).width());
		setHGalItemWidth(container);
	}
	else if (itemWidth == 'fixed')
	{
		var containerWidth = container;
		// по-умолчанию ширина галареи определятеся по ширине контейнера
		if (blockWidth == 'parent')
		{
			containerWidth = $(container).parent();
		}
		$(container).data('galWidth', $(containerWidth).width());
		setHGalItemCount(container, wrapGallery, staticItemWidth);
	}
	// сдвигаем ul на один элемент влево если количество элементов больше 1
	if (($(container).find('ul li').length > $(container).data('countVisible')) && cyclic)
	{
		$(container).find('ul').css({"left" : -$(container).data('itemWidth')+"px"});
	}
	else
	{
		$(container).find('.prev').addClass('no-active');
	}
}

// функция устанавливает ширину элемента li галереи в соответствии с текущей шириной контейнера
function setHGalItemWidth(container)
{
	// устанавливаем ширину галереи для li элементов
	$(container).find('ul li').width($(container).data('galWidth'));
	// устанавливаем ширину одного элемента в галерее
	$(container).data('itemWidth', $(container).data('galWidth'));
	// устанавливаем количество отображаемых в галерее элементов
	$(container).data('countVisible', 1);
}

// функция устанавливает ширину враппера галереи и устанавливает количество выводимых элементов в галерее в зависимости от текущей ширины контейнера
function setHGalItemCount(container, wrapGallery, staticItemWidth)
{
	var maxCount = Math.floor($(container).data('galWidth') / staticItemWidth);
	// устанавливаем ширину одного элемента в галерее
	$(container).data('itemWidth', staticItemWidth);
	// устанавливаем количество отображаемых в галерее элементов
	$(container).data('countVisible', maxCount);
	$(container).find(wrapGallery).width(maxCount*staticItemWidth);
	// установим общую длину галереи
	$(container).data('allWidth', $(container).find('ul li').length * staticItemWidth);
}




// функция инициализирует вертикальную галерею
// Параметры на входе:
// container - блок, в котором будет листаться галерея
// navClass - класс навигационных кнопок, у каждой кнопки при этом должны быть классы .next и .prev
// cyclic - Циклическая ли галерея (true - да, false - нет)
// scrolling - Использовать ли скроллинг (true - да, false - нет)
// itemHeight - параметр, который отвечает за то, будет ли ширина одного элемента фиксированной 
// 			   или же она будет тянуться по ширине родительского контейнера, возможные параметры fixed/auto
// blockHeight - блок, по которому надо определять ширину галереи, возможные параметры parent/self (parent - родитель от container, self - по ширине самого container)
// wrapGallery - если определен параметр itemHeight в значение fixed, то указывается враппер для карусели
// staticItemHeight - если определен параметр itemHeight в значение fixed, то указывается ширина элемента галереи
function initVGallery(container, navClass, cyclic, scrolling, itemHeight, blockHeight, wrapGallery, staticItemHeight)
{
	$(container).each(function(){
		var cont = this;
		
		$(cont).find(navClass).removeClass('no-active');
		
		// переводим галерею в состояние 'free'
		$(this).data('state', 'free');
		// установка ширины и количества отображаемых элементов галереи
		setVGalHeight(this, cyclic, itemHeight, blockHeight, wrapGallery, staticItemHeight);
		if (itemHeight == 'auto')
		{
			$(window).resize(function(){
				setVGalHeight(cont, true, itemHeight, blockHeight, wrapGallery, staticItemHeight);
			});
		}
		
		// регистрация обработчиков событий нажатия на кнопки навигации
		if ($(cont).data('countVisible') > $(cont).find('ul li').length)
		{
			$(cont).find(navClass).addClass('no-active');
		}
		$(cont).find(navClass).click(function(){
			if (!$(this).hasClass('no-active'))
			{
				
				if ($(cont).data('countVisible') < $(cont).find('ul li').length)
				{
					var step = ($(this).hasClass('prev')) ? -1 : (($(this).hasClass('next')) ? 1 : 0);
					if (cyclic)
					{
						moveVGal(cont, step);
					}
					else
					{
						moveNoCyclicVGal(cont, step);
					}
				}
				else
				{
					// иначе сдвигаем список на начало и деактивируем кнопки навигации
					$(cont).find('ul').css({"top": "0px"});
					$(cont).find(navClass).addClass('no-active');
				}
			}
			return false;
		});
		if (scrolling)
		{
			$(cont).bind('mousewheel', function(event, delta){
				if($(cont).data('state') == 'free')
				{
					if (delta > 0)
					{
						curNavClass = '.prev';
					}
					else
					{
						curNavClass = '.next';
					}
					if (!$(cont).find(curNavClass).hasClass('no-active'))
					{
						$(cont).find(curNavClass).trigger('click');
					}
					return false;
				}
			});
		}
	});
}

// функция двигает галерею на одну позицию вверх или вниз, в зависимости от шага
function moveVGal(container, step)
{
	if ($(container).data('state') == 'free')
	{
		// переводим галерею в состояние 'busy'
		$(container).data('state', 'busy');
		
		// говорим, что первый элемент по-умолчанию еще не скопирован
		$(container).data('hasCopy', false);
		
		// проверяем, если сдвигаем вниз, то нужно проверить количество элементов в галерее и количество отображаемых элементов
		if (step > 0)
		{
			// если количество всех элементов больше отображаемых в карусели ровно на 1, то нужно перекинуть первый элемент еще до анимации,
			// чтобы не было задержки при загрузке
			if (($(container).find('ul li').length - $(container).data('countVisible')) == 1)
			{
				$(container).data('hasCopy', true);
				$(container).find('ul').append('<li>'+$(container).find('ul li:first').html()+'</li>');
			}
		}
		// двигаем в нужную сторону галерею и потом устанавливаем последний/первый элемент в начало/конец
		$(container).find('ul').animate(
			{"top" : ((-$(container).data('itemHeight'))-(step * $(container).data('itemHeight')))+"px"},
			"fast",
			function(){
				// если двигали вперед, то первый элемент галереи перекинем в конец
				if (step > 0)
				{
					// если у нас первый элемент уже скопирован в конец, то просто удаляем его
					if ($(container).data('hasCopy'))
					{
						// удаляем первый элемент
						$(container).find('ul li:first').remove();
					}
					else
					{
						// переносим первый элемент в конец списка
						$(container).find('ul li:first').appendTo($(container).find('ul'));
					}
				}
				// если двигали назад, то последний элемент галереи перекинем в начало
				else
				{
					$(container).find('ul li:last').prependTo($(container).find('ul'));
				}
				$(container).find('ul').css({"top" : (-$(container).data('itemHeight'))+"px"});
				$(container).data('state', 'free');
			}
		);
	}
}

// функция нециклично двигает галерею на одну позицию вверх или вниз, в зависимости от шага
function moveNoCyclicVGal(container, step)
{
	if ($(container).data('state') == 'free')
	{
		// переводим галерею в состояние 'busy'
		$(container).data('state', 'busy');
		
		// находим позицию галереи
		var topPos = $(container).find('ul').css('top');
		topPos = topPos.replace("px", '');
		topPos = parseInt(topPos);
		var commonHeight = $(container).data('itemHeight')*$(container).data('countVisible') - topPos;
		
		var canMove = false;
		
		// при сдвиге проверяем, можем ли мы еще двигать в эту сторону, если нет, то скрываем соответствующую кнопку
		if ((step > 0) && (($(container).data('allHeight') - commonHeight) >= $(container).data('itemHeight')))
		{
			canMove = true;
		}
		else if((step < 0) && (Math.abs(topPos) >= $(container).data('itemHeight')))
		{
			canMove = true;
		}
		
		if (canMove)
		{
			// двигаем в нужную сторону галерею и потом устанавливаем последний/первый элемент в начало/конец
			$(container).find('ul').animate(
				{"top" : (topPos - step*$(container).data('itemHeight'))+"px"},
				"fast",
				function(){
					commonHeight = commonHeight + step*$(container).data('itemHeight');
					topPos = $(container).find('ul').css('top');
					topPos = topPos.replace("px", '');
					topPos = parseInt(topPos);
					
					if (($(container).data('allHeight') - commonHeight) >= $(container).data('itemHeight'))
					{
						$(container).find('.next').removeClass('no-active');
					}
					else
					{
						$(container).find('.next').addClass('no-active');
					}
					
					if(Math.abs(topPos) >= $(container).data('itemHeight'))
					{
						$(container).find('.prev').removeClass('no-active');
					}
					else
					{
						$(container).find('.prev').addClass('no-active');
					}
				}
			);
		}
		else
		{
			if (step > 0)
			{
				$(container).find('.next').addClass('no-active');
			}
			else
			{
				$(container).find('.prev').addClass('no-active');
			}
		}
		$(container).data('state', 'free');
	}
}

// функция устанавливает высоту галереи и количество отображаемых элементов в ней
function setVGalHeight(container, cyclic, itemHeight, blockHeight, wrapGallery, staticItemHeight)
{
	if (itemHeight == 'auto')
	{
		$(container).data('galHeight', $(container).height());
		setVGalItemHeight(container);
	}
	else if (itemHeight == 'fixed')
	{
		var containerHeight = container;
		// по-умолчанию ширина галареи определятеся по ширине контейнера
		if (blockHeight == 'parent')
		{
			containerHeight = $(container).parent();
		}
		$(container).data('galHeight', $(containerHeight).height());
		setVGalItemCount(container, wrapGallery, staticItemHeight);
	}
	// сдвигаем ul на один элемент влево если количество элементов больше 1
	if (($(container).find('ul li').length > $(container).data('countVisible')) && cyclic)
	{
		$(container).find('ul').css({"top" : -$(container).data('itemHeight')+"px"});
	}
	else
	{
		$(container).find('.prev').addClass('no-active');
	}
}

// функция устанавливает высоту элемента li галереи в соответствии с текущей шириной контейнера
function setVGalItemHeight(container)
{
	// устанавливаем  галереи для li элементов
	$(container).find('ul li').height($(container).data('galHeight'));
	// устанавливаем высоту одного элемента в галерее
	$(container).data('itemHeight', $(container).data('galHeight'));
	// устанавливаем количество отображаемых в галерее элементов
	$(container).data('countVisible', 1);
}

// функция устанавливает высоту враппера галереи и устанавливает количество выводимых элементов в галерее в зависимости от текущей ширины контейнера
function setVGalItemCount(container, wrapGallery, staticItemHeight)
{
	var maxCount = Math.floor($(container).data('galHeight') / staticItemHeight);
	// устанавливаем высоту одного элемента в галерее
	$(container).data('itemHeight', staticItemHeight);
	// устанавливаем количество отображаемых в галерее элементов
	$(container).data('countVisible', maxCount);
	$(container).find(wrapGallery).height(maxCount*staticItemHeight);
	
	// установим общую высоту галереи
	$(container).data('allHeight', $(container).find('ul li').length * staticItemHeight);
}
