﻿/*
 * jQuery rvnGallery v1.1
 
 * Copyright 2011, Krukowski Bartłomiej
 * http://dev.sirkruk.com
 * Licensed under GPL Version 2
	
 * Date: 2011.04.02
 */
(function(jQuery) {
	
	//domyślne ustawienia
	var rvnGalleryDefaults = {
		effect: 'random', //efekt przejść
		verticalSlices: 10, //ilość pasków pionowych
		horizontalSlices: 8, //ilość pasków poziomych
		delay: 5000, //czas opóźnień pomiędzy kolejnymi animacjami
		animSpeed: 600, //czas animacji
		sliceDelay: 50, //czas opóźnień między animacją kolejnych pasków
		backgroundColor: '#ffffff', //kolor tła
		slider: true, //automatyczny pokaz slajdów
		captionOpacity: 0.8, //przezroczystość paska z tekstem
		navButtons: true
	}
	
	//stała definiująca klucz dostępu do zmiennych danej galerii
	var RVN_DATA_KEY = 'http://dev.sirkruk.com';	
	
	//tablica animacji
	var rvnAnim = {
		alternatelyRight: function(slices, animSpeed, sliceDelay){
			var s = slices.filter('.vertical');
			s.filter(':even').each(function(){
				jQuery(this).css({
					top: 0,
					left: 0,
					opacity: 0,
					width: jQuery(this).parent().width()
				});
			});
			s.filter(':odd').each(function(){
				jQuery(this).css({
					bottom: 0,
					left: 0,
					opacity: 0,
					width: jQuery(this).parent().width()
				});
			});
			var i = 0;
			s.each(function(){
				var self = jQuery(this);
				setTimeout(function(){ self.animate({height: self.parent().height(), opacity: 1}, animSpeed); }, sliceDelay*i);
				i++;
			});
			return animSpeed + sliceDelay*i;
		},
		alternatelyLeft: function(slices, animSpeed, sliceDelay){
			slices.reverse();
			return rvnAnim.alternatelyRight(slices, animSpeed, sliceDelay);
		},
		alternatelyBottom: function(slices, animSpeed, sliceDelay){
			var s = slices.filter('.horizontal');
			s.filter(':even').each(function(){
				jQuery(this).css({
					left: 0,
					top: 0,
					opacity: 0,
					height: jQuery(this).parent().height()
				});
			});
			s.filter(':odd').each(function(){
				jQuery(this).css({
					right: 0,
					top: 0,
					opacity: 0,
					height: jQuery(this).parent().height()
				});
			});
			var i = 0;
			s.each(function(){
				var self = jQuery(this);
				setTimeout(function(){ self.animate({width: self.parent().width(), opacity: 1}, animSpeed); }, sliceDelay*i);
				i++;
			});
			return animSpeed + sliceDelay*i;
		},
		alternatelyTop: function(slices, animSpeed, sliceDelay){
			slices.reverse();
			return rvnAnim.alternatelyBottom(slices, animSpeed, sliceDelay);
		},
		blindsRight: function(slices, animSpeed, sliceDelay, back){
			var c = (back)?'right':'left';
			var s = slices.filter('.vertical');
			s.each(function(){
				jQuery(this).css({
					top: 0,
					height: jQuery(this).parent().height()
				}).css(c, 0);
			});
			var i = 0;
			s.each(function(){
				var self = jQuery(this);
				setTimeout(function(){ self.animate({width: self.parent().width()}, animSpeed) }, sliceDelay*i);
				i++;
			});
			return animSpeed + sliceDelay*i;
		},
		blindsLeft: function(slices, animSpeed, sliceDelay){
			slices.reverse();
			return rvnAnim.blindsRight(slices, animSpeed, sliceDelay, true);
		},
		blindsBottom: function(slices, animSpeed, sliceDelay, back){
			var c = (back)?'bottom':'top';
			var s = slices.filter('.horizontal');
			s.each(function(){
				jQuery(this).css({
					left: 0,
					width: jQuery(this).parent().width()
				}).css(c, 0)
			});
			var i = 0;
			s.each(function(){
				var self = jQuery(this);
				setTimeout(function(){ self.animate({height: self.parent().height()}, animSpeed) }, sliceDelay*i);
				i++;
			});
			return animSpeed + sliceDelay*i;
		},
		blindsTop: function(slices, animSpeed, sliceDelay){
			slices.reverse();
			return rvnAnim.blindsBottom(slices, animSpeed, sliceDelay, true);
		},
		tiersBottomRight: function(slices, animSpeed, sliceDelay, t){
			var c = (t)?'bottom':'top';
			var s = slices.filter('.vertical');
			s.each(function(){
				jQuery(this).css({
					left: 0,
					opacity: 0,
					width: jQuery(this).parent().width()
				}).css(c, 0);
			});
			var i = 0;
			s.each(function(){
				var self = jQuery(this);
				setTimeout(function(){ self.animate({height: self.parent().height(), opacity: 1}, animSpeed) }, sliceDelay*i);
				i++;
			});
			return animSpeed + sliceDelay*i;
		},
		tiersBottomLeft: function(slices, animSpeed, sliceDelay){
			slices.reverse();
			return rvnAnim.tiersBottomRight(slices, animSpeed, sliceDelay);
		},
		tiersTopRight: function(slices, animSpeed, sliceDelay){
			return rvnAnim.tiersBottomRight(slices, animSpeed, sliceDelay, true);
		},
		tiersTopLeft: function(slices, animSpeed, sliceDelay){
			slices.reverse();
			return rvnAnim.tiersTopRight(slices, animSpeed, sliceDelay);
		},
		tiersRightBottom: function(slices, animSpeed, sliceDelay, t){
			var c = (t)?'right':'left';
			var s = slices.filter('.horizontal');
			s.each(function(){
				jQuery(this).css({
					top: 0,
					opacity: 0,
					height: jQuery(this).parent().height()
				}).css(c, 0);
			});
			var i = 0;
			s.each(function(){
				var self = jQuery(this);
				setTimeout(function(){ self.animate({width: self.parent().width(), opacity: 1}, animSpeed) }, sliceDelay*i);
				i++;
			});
			return animSpeed + sliceDelay*i;
		},
		tiersRightTop: function(slices, animSpeed, sliceDelay){
			slices.reverse();
			return rvnAnim.tiersRightBottom(slices, animSpeed, sliceDelay);
		},
		tiersLeftBottom: function(slices, animSpeed, sliceDelay){
			return rvnAnim.tiersRightBottom(slices, animSpeed, sliceDelay, true);
		},
		tiersLeftTop: function(slices, animSpeed, sliceDelay){
			slices.reverse();
			return rvnAnim.tiersLeftBottom(slices, animSpeed, sliceDelay);
		},
		alphaRectRight: function(slices, animSpeed, sliceDelay){
			var s = slices.filter('.vertical');
			s.each(function(){
				jQuery(this).css({
					width: jQuery(this).parent().width(),
					height: jQuery(this).parent().height(),
					left: 0,
					top: 0,
					opacity: 0
				});
			});
			var i = 0;
			s.each(function(){
				var self = jQuery(this);
				setTimeout(function(){ self.animate({opacity: 1}, animSpeed), sliceDelay*i }, sliceDelay*i);
				i++
			});
			return animSpeed + sliceDelay*i;
		},
		alphaRectLeft: function(slices, animSpeed, sliceDelay){
			slices.reverse();
			return rvnAnim.alphaRectRight(slices, animSpeed, sliceDelay);
		},
		alphaRectBottom: function(slices, animSpeed, sliceDelay){
			var s = slices.filter('.horizontal');
			s.each(function(){
				jQuery(this).css({
					width: jQuery(this).parent().width(),
					height: jQuery(this).parent().height(),
					left: 0,
					top: 0,
					opacity: 0
				});
			});
			var i = 0;
			s.each(function(){
				var self = jQuery(this);
				setTimeout(function(){ self.animate({opacity: 1}, animSpeed), sliceDelay*i }, sliceDelay*i);
				i++
			});
			return animSpeed + sliceDelay*i;
		},
		alphaRectTop: function(slices, animSpeed, sliceDelay){
			slices.reverse();
			return rvnAnim.alphaRectBottom(slices, animSpeed, sliceDelay);
		},
		fade: function(slices, animSpeed, sliceDelay){
			var s = slices.filter('.vertical');
			s.each(function(){
				jQuery(this).css({
					width: jQuery(this).parent().width(),
					height: jQuery(this).parent().height(),
					left: 0,
					top: 0,
					opacity: 0
				});
			});
			s.animate({opacity: 1}, animSpeed);
			return animSpeed;
		},
		teethVertical: function(slices, animSpeed, sliceDelay){
			var s = slices.filter('.vertical');
			s.filter(':even').each(function(){
				jQuery(this).css({
					width: jQuery(this).parent().width(),
					left: 0,
					top: 0
				});
			});
			s.filter(':odd').each(function(){
				jQuery(this).css({
					width: jQuery(this).parent().width(),
					left: 0,
					bottom: 0
				});
			});
			s.each(function(){
				jQuery(this).animate({height: jQuery(this).parent().height()}, animSpeed);
			});
			return animSpeed;
		},
		teethHorizontal: function(slices, animSpeed, sliceDelay){
			var s = slices.filter('.horizontal');
			s.filter(':even').each(function(){
				jQuery(this).css({
					height: jQuery(this).parent().height(),
					left: 0,
					top: 0
				});
			});
			s.filter(':odd').each(function(){
				jQuery(this).css({
					height: jQuery(this).parent().height(),
					right: 0,
					top: 0
				});
			});
			s.each(function(){
				jQuery(this).animate({width: jQuery(this).parent().width()}, animSpeed);
			});
			return animSpeed;
		},
		newTiersBottomRight: function(slices, animSpeed, sliceDelay, t, u){
			var c = (t)?'bottom':'top';
			var d = (u)?'right':'left';
			var s = slices.filter('.vertical');
			s.each(function(){
				jQuery(this).css({
					opacity: 0,
					width: 0
				}).css(c, 0).css(d, 0);
			});
			var i = 0;
			s.each(function(){
				var self = jQuery(this);
				setTimeout(function(){ self.animate({width: self.parent().width(), height: self.parent().height(), opacity: 1}, animSpeed) }, sliceDelay*i);
				i++;
			});
			return animSpeed + sliceDelay*i;
		},
		newTiersBottomLeft: function(slices, animSpeed, sliceDelay){
			slices.reverse();
			return rvnAnim.newTiersBottomRight(slices, animSpeed, sliceDelay, false, true);
		},
		newTiersTopRight: function(slices, animSpeed, sliceDelay){
			return rvnAnim.newTiersBottomRight(slices, animSpeed, sliceDelay, true);
		},
		newTiersTopLeft: function(slices, animSpeed, sliceDelay){
			slices.reverse();
			return rvnAnim.newTiersBottomRight(slices, animSpeed, sliceDelay, true, true);
		},
		newTiersRightBottom: function(slices, animSpeed, sliceDelay, t, u){
			var c = (t)?'right':'left';
			var d = (u)?'bottom':'top';
			var s = slices.filter('.horizontal');
			s.each(function(){
				jQuery(this).css({
					opacity: 0,
					height: 0
				}).css(c, 0).css(d, 0);
			});
			var i = 0;
			s.each(function(){
				var self = jQuery(this);
				setTimeout(function(){ self.animate({width: self.parent().width(), height: self.parent().height(), opacity: 1}, animSpeed) }, sliceDelay*i);
				i++;
			});
			return animSpeed + sliceDelay*i;
		},
		newTiersRightTop: function(slices, animSpeed, sliceDelay){
			slices.reverse();
			return rvnAnim.newTiersRightBottom(slices, animSpeed, sliceDelay, false, true);
		},
		newTiersLeftBottom: function(slices, animSpeed, sliceDelay){
			return rvnAnim.newTiersRightBottom(slices, animSpeed, sliceDelay, true);
		},
		newTiersLeftTop: function(slices, animSpeed, sliceDelay){
			slices.reverse();
			return rvnAnim.newTiersRightBottom(slices, animSpeed, sliceDelay, true, true);
		}
	}
	
	//pomocnicza tablica nazw animacji (jest generowana automatycznie)
	var rvnAnimName = [];
	for(var i in rvnAnim){
		rvnAnimName[rvnAnimName.length] = i;
	}
	
	//zwraca wybraną animację
	function rvnGetAnimName(name){
		if (name instanceof Array){
			return name[Math.floor(Math.random()*name.length)];
		} else if (name == 'random') {
			return rvnAnimName[Math.floor(Math.random()*rvnAnimName.length)];
		} else {
			return name;
		}
	}
	
	function rvnSetLink(gallery, href){
		jQuery('.rvnLink', gallery).attr('href', href).
		css({
			visibility: href!=''?'visible':'hidden'
		});
	}
	
	function rvnSetCaption(gallery, caption){
		jQuery('.rvnCaption', gallery).css({display: (caption!='')?'block':'none'}).text(caption);
	}
	
	function rvnGalleryRunning(gallery){
		return jQuery('.rvnSlice:animated', gallery).length>0;
	}
	
	function rvnSetImage(gallery, index){
		var settings = gallery.data(RVN_DATA_KEY);
		jQuery('.rvnImg', gallery).css({
			backgroundImage:	settings.images[index].src,
			'background-position':	Math.round((settings.width-settings.images[index].width)/2)+'px '+Math.round((settings.height-settings.images[index].height)/2)+'px'
		});
	}
	
	//animuj!
	function rvnAnimate(gallery, n, auto){
		//zabezpieczenie dla ie - jeśli animacja nie zdążyła się skończyć a idzie następna, to zatrzymaj aktualną
		if (auto) jQuery('.rvnSlice', gallery).stop();
		
		//jeśli już animuje to zakończ funkcję
		if (rvnGalleryRunning(gallery)) return;
	
		var settings = gallery.data(RVN_DATA_KEY);
		
		clearTimeout(settings.timer);
		
		//ustawienie aktywnego obrazka w tle
		rvnSetImage(gallery, settings.index);
		
		//pobranie indexu
		var index;
		if ((typeof(n) === 'undefined') || (n == 'next'))
			index = settings.index + 1;
		else if (n == 'prev')
			index = settings.index - 1;
		else
			index = n;
			
		//poprawienie wartości indexu jeśli nie mieści się w przedziale
		if (index >= settings.images.length)
			index = 0;
		else if (index < 0)
			index = settings.images.length - 1;
		
		//wyzerowanie właściwości pasków
		var slices = jQuery('.rvnSlice', gallery);
		slices.css({width: 0, height: 0, left: 'auto', top: 'auto', right: 'auto', bottom: 'auto', opacity: 1});
		
		//ustawienie/usunięcie odsyłacza
		rvnSetLink(gallery, settings.images[index].href);
		//podpis obrazka
		rvnSetCaption(gallery, settings.images[index].alt);
		
		var leftMov = Math.round((settings.width-settings.images[index].width)/2);
		var topMov = Math.round((settings.height-settings.images[index].height)/2);
		
		//konfiguracja pasków pionowych
		var i = 0;
		var s_width = Math.round(settings.width/settings.verticalSlices);
		slices.filter('.vertical').each(function(){
			jQuery(this).css({
				backgroundImage: settings.images[index].src,
				backgroundPosition: (leftMov-s_width*i)+'px '+topMov+'px'
			});
			i++;
		});
			
		//konfiguracja pasków poziomych
		var i = 0;
		var s_height = Math.round(settings.height/settings.horizontalSlices);
		slices.filter('.horizontal').each(function(){
			jQuery(this).css({
				backgroundImage: settings.images[index].src,
				backgroundPosition: leftMov+'px '+(topMov-s_height*i)+'px'
			});
			i++;
		});
			
		var animTime = rvnAnim[rvnGetAnimName(settings.effect)](slices, settings.animSpeed, settings.sliceDelay);
		
		//automatyczny pokaz slajdów
		if (settings.slider)
			settings.timer = setTimeout(function(){rvnAnimate(gallery, 'next', true);}, animTime+settings.delay );
		
		settings.index = index;
		gallery.data(RVN_DATA_KEY, settings);
	}
	
	//tworzenie pasków poziomych
	function rvnCreateVerticalLayout(gallery){
		var settings = gallery.data(RVN_DATA_KEY);
		var s_width = Math.round(settings.width/settings.verticalSlices);
		for (i=0; i<settings.verticalSlices; i++){
			if (i < settings.verticalSlices - 1){
				gallery.append('<div class="rvnVerticalLayout"><div class="rvnSlice vertical"></div></div>').
				children('.rvnVerticalLayout:last').css({
					left: s_width*i+'px',
					width: s_width,
					height: settings.height
				});
			} else {
				gallery.append('<div class="rvnVerticalLayout"><div class="rvnSlice vertical"></div></div>').
				children('.rvnVerticalLayout:last').css({
					left: s_width*i+'px',
					width: settings.width - s_width*i,
					height: settings.height
				});
			}
		}
	}
	
	//tworzenie pasków pionowych
	function rvnCreateHorizontalLayout(gallery){
		var settings = gallery.data(RVN_DATA_KEY);
		var s_height = Math.round(settings.height/settings.horizontalSlices);
		for (i=0; i<settings.horizontalSlices; i++){
			if (i < settings.horizontalSlices - 1){
				gallery.append('<div class="rvnHorizontalLayout"><div class="rvnSlice horizontal"></div></div>').
				children('.rvnHorizontalLayout:last').css({
					top: s_height*i+'px',
					height: s_height,
					width: settings.width
				});
			} else {
				gallery.append('<div class="rvnHorizontalLayout"><div class="rvnSlice horizontal"></div></div>').
				children('.rvnHorizontalLayout:last').css({
					top: s_height*i+'px',
					height: settings.height - s_height*i,
					width: settings.width
				});
			}
		}
	}
	
	//inicjowanie galerii (funkcja wywoływana z funkcji wtyczki)
	function rvnGalleryInit(gallery){
		//pobranie ustawień
		var settings = gallery.data(RVN_DATA_KEY);
		settings.width = gallery.width();
		settings.height = gallery.height();
		
		//pobranie informacji o obrazkach (wysokość, szerokość, tytuł, opis)
		var images = [];
		gallery.children('img, a').each(function(){
			var image = {};
			var child = jQuery(this);
			image['href'] = (child.is('a')?child.attr('href'):'');
			if (child.is('a'))
				child = child.children('img:first');
			image['src'] 	= 'url(' + child.attr('src') + ')';
			image['width']	= child.width();
			image['height']	= child.height();
			//image['alt']	= child.attr('alt');
			image['alt'] = child.hasClass('hideCaption')?'':child.attr('alt');
			
			images[images.length] = image;
		});
		
		//wygenerowanie pasków
		rvnCreateVerticalLayout(gallery);
		rvnCreateHorizontalLayout(gallery);
		
		//ustawienie wartości do zapisania
		settings.index = 0;
		settings.images = images;
		settings.running = false;
		settings.timer = false;
		
		//warstwa odpowiadająca za obrazek znajdujący się pod paskami
		gallery.prepend('<div class="rvnImg"></div>');
		
		//warstwa odpowiadająca za link
		gallery.append('<a class="rvnLink"></a>');
		
		//dodanie przycisków nawigacyjnych
		if (settings.navButtons){
			gallery.append('<div class="btnPrev"></div>');
			gallery.append('<div class="btnNext"></div>');
			var btnTop = Math.round((settings.height - jQuery('.btnPrev', gallery).height())/2);
			jQuery('.btnPrev, .btnNext', gallery).css({top: btnTop});
			gallery.hover(
				function(){
					jQuery('.btnPrev, .btnNext', gallery).css({visibility: 'visible'});
				}, function(){
					jQuery('.btnPrev, .btnNext', gallery).css({visibility: 'hidden'});
				}
			);
			jQuery('.btnPrev', gallery).click(function(){ rvnAnimate(gallery, 'prev'); });
			jQuery('.btnNext', gallery).click(function(){ rvnAnimate(gallery, 'next'); });
		}
		
		//warstwa odpowiedzialna za wyświetlanie podpisów obrazków
		gallery.append('<div class="rvnCaption"></div>');
		jQuery('.rvnCaption', gallery).css({opacity: settings.captionOpacity});
		
		//ustawienie koloru i obrazka
		jQuery('.rvnImg', gallery).css({backgroundColor: settings.backgroundColor});
		jQuery('.rvnSlice', gallery).css({backgroundColor: settings.backgroundColor});
		rvnSetImage(gallery, 0);
		
		//ustawienie/usunięcie odsyłacza
		rvnSetLink(gallery, settings.images[settings.index].href);
		//podpis obrazka
		rvnSetCaption(gallery, settings.images[settings.index].alt);
		
		gallery.data(RVN_DATA_KEY, settings);
		
		if (settings.slider)
			settings.timer = setTimeout(function(){rvnAnimate(gallery);}, settings.delay);
			
		gallery.data(RVN_DATA_KEY, settings);
	}
	
	//inicjowanie galerii (funkcja wtyczka do jquery)
	jQuery.fn.rvnGallery = function(options){
		return this.each(function(){
			var gallery = jQuery(this);
			gallery.data(RVN_DATA_KEY, jQuery.extend({}, rvnGalleryDefaults, options));
			rvnGalleryInit(gallery);
		});
	}
	
	//odwraca kolejność elementów tablicy
	jQuery.fn.reverse = Array.prototype.reverse;
	
})(jQuery);
