$.easing.backThatEaseOut	= function (x, t, b, c, d, s) {
		if (s == undefined) s = 3;
		return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
	};

var Gallery	= function (images, categories) {
	var self	= this;
	
	
	self.config		= {
		animate: {
			from: {width: 116, height: 154, left: 10, top: 10, effect: 'backThatEaseOut'},
			to: {width: 136, height: 174, left: 0, top: 0, effect: ''},
			effect: 'easeOutBack',
			duration: 1400
		},
		container: '#gallery',
		loader: '#loading',
		perpage: 21,
		tmpl: {
			slide: $('#tmpl-slide').html (),
			figure: $('#tmpl-figure').html ()
		},
		
	};
	
	self.pagination	= {
		current: 0,
		prevPage: 'header a.prev',
		nextPage: 'header a.next'
			
	};

	self.container	= $(self.config.container);

	(
		function () {
			
			self.loader	= $(self.config.loader);
			
			self.pagination.prevPage	= $(self.pagination.prevPage).bind ('click',
				function (e) {
					e.preventDefault ();
					Gallery.prevPage ();
				}
			);
			
			self.pagination.nextPage	= $(self.pagination.nextPage).bind ('click',
				function (e) {
					e.preventDefault ();
					Gallery.nextPage ();
				}
			);
			
			self.container.delegate ('figure', 'mouseenter',
				function (e) {
					self.enlarge ($(this).find ('img'));
				}
			);
	
			self.container.delegate ('figure', 'mouseleave',
				function (e) {
					self.delarge ($(this).find ('img'));
				}
			);
						
			function __fancyBoxOpen (currentArray, i, currentOpts) {
				var isYoutube	= /vimeo/i.test (currentOpts.href);
				
				
				if (isYoutube) {
					$('#fancybox-content').html ('Laden..');
					 $.getJSON ('http://vimeo.com/api/oembed.json?url=' + currentOpts.href + '&autoplay=true&callback=?',
					 	function (data) {
							var div	= '<div style="width: ' + data.width + 'px; height: ' + data.height + 'px;">' + data.html + '</div>';
							$('#fancybox-content').html (div);
							$('#fancybox-content').width (data.width).height (data.height);
							
						
							$(window).trigger ('resize.fb');
							$('#fancybox-wrap').width (data.width);
						}
					);
					
				}
				
			};
			function __fancyBoxStart () { $(document).data ('fancy.open', true); };
			function __fancyBoxEnd () { $(document).data ('fancy.open', false); };
			function __titleFormat (title, currentArray, i, currentOpts) {
				
				$('#fancybox-left-ico').css ('opacity', 1);
				$('#fancybox-right-ico').css ('opacity', 1);

				if (i == 0) {
					$('#fancybox-left-ico').css ('opacity', 0);
				}
				
				if ((i + 1) == currentArray.length) {
					$('#fancybox-right-ico').css ('opacity', 0);
				}
				
				
				
			}
						
						
						
			self.container.delegate ('a', 'click',
				function (e) {
					e.preventDefault ();
					
					var images	= [],
						width, height, index = 0, href = this.getAttribute ('href');
					
					for (var i = 0, l = self.currentImages.length; i < l; i++) {

						if (href == self.currentImages[i].big) {
							index	= i;
						}
						
						images.push (self.currentImages[i].big);
					}

					$.fancybox (images, {
							index: index,
							overlayColor: '#fff',
							padding: 0,
							type: 'image',
							autoScale: true,
							autoDimensions: true,
							speedIn : 300,
							overlayOpacity: 0.9,
							showNavArrows: false,
							onComplete: __fancyBoxOpen,
							onStart: __fancyBoxStart,
							onClosed: __fancyBoxEnd,
							titleFormat: __titleFormat
						}
					);


				}
			);
	
		}
	)();
	
	self.images			= images;
	self.currentImages	= images;

	self.enlarge	= function (el) {
		var $el	= $(el);

		$el.stop ().animate (self.config.animate.to, 300, self.config.animate.to.effect);
	};
	
	self.delarge	= function (el) {
		var $el	= $(el);

		$el.stop (false, true).animate (self.config.animate.from, 500, self.config.animate.from.effect);
	};
	
	self.filter	= function (cat) {

		if ($.type (cat) != 'array') {
			cat	= [cat];
		}

		images	= $.map (self.images,
			function (image) {
				if ($.inArray (image.category, cat) !== -1) {
					return image;
				}
			}
		);
		
		images.sort (self.__randSort);
		
		self.__initialize (images);
	};
	
	self.__randSort	= function () {
		return (Math.round(Math.random())-0.5);
	}

	
	self.buildPage	= function (images) {
		var _self	= self;

		var html	= $.map (images,
			function (image) {
				return _self.config.tmpl.figure.replace (/\$link/, image.big)
				.replace (/\$src/, image.thumb)
				.replace (/\$category/, image.category);
			}
		).join ('');
		
		return self.config.tmpl.slide.replace (/\$content/, html);
	}
	
	self.build	= function (images) {
		
		images	= images || self.images || [];
		
		var i = 0, pages = [], perPage = self.config.perpage,
			pageCount	= Math.ceil (images.length / perPage);



		for ( ; i < pageCount; i++) {
			var start = i * perPage,
				_images	= images.slice (start, start + perPage);

			pages.push (self.buildPage (_images));
		}
		
		return pages;
		
	}
	
	self.preload	= function (images, cb) {
		images	= images || self.images || [];

		if (!images.length) {
			return false;
		}
		
		self.preload.queue		= 0;
		self.preload.finished	= 0;
		
		function __isFinished () {
			self.preload.finished++;
			
			if (self.preload.finished == self.preload.queue) {
				if ($.isFunction (cb)) {
					
					cb (images);
				}
			}
		}
		
		$.each (images,
			function (i, image) {
				
				self.preload.queue++;
				
				var img	= new Image ();
				img.onload	= __isFinished;
				img.src		= image.thumb;
			}
		);
	}
	
	self.initialize	= function (images) {
		images	= images || self.images || [];

		if (!images.length) {
			return false;
		}

		images.sort (self.__randSort);


		self.preload (images,
			function () {
				
				self.filter (categories);
				
				//self.__initialize (images);
			}
		);
	}
	
	self.__initialize	= function (images) {
		images	= images || self.images || [];

		if (!images.length) {
			return false;
		}
		
		if (self.loader.length) {
			self.loader.fadeOut ();
		}
		
		self.currentImages	= images;
		
		
		self._pages				= self.build (images);
		self.pagination.current	= 0;
		var $page	= $(self._pages[0]).addClass ('current')

		self.container	= $(self.container).html ($page);
		self.__pageAdded.call ($page);
	}
	
	self.nextPage	= function () {

		var $current	= self.container.children ('.slide');
		
		if ($current.is (':animated')) {
			return null;
		}
		
		
		
		if ((self.pagination.current + 1) < self._pages.length) {
			self.pagination.current++;
			
			var $new		= $(self._pages[self.pagination.current]),
				left		= self.container.width ();
			
			$new.css ({left: left});
			
			self.container.append ($new);
			self.__pageAdded.call ($new);

			$new.animate ({left: 0}, self.config.animate.duration, self.config.animate.effect);
			$current.animate ({left: 0 - left}, self.config.animate.duration, self.config.animate.effect, self.__pageAnimCompleted);
		} else {
			return false;
		}
	}
		
	self.prevPage	= function () {
		var $current	= self.container.children ('.slide');
		
		if ($current.is (':animated')) {
			return null;
		}


		if ((self.pagination.current - 1) >= 0) {
			self.pagination.current--;
			
			var $new		= $(self._pages[self.pagination.current]),
				left		= self.container.width ();
			
			$new.css ({left: 0 - left});
			
			self.container.append ($new);
			self.__pageAdded.call ($new);
			
			$new.animate ({left: 0}, self.config.animate.duration, self.config.animate.effect);
			$current.animate ({left: left}, self.config.animate.duration, self.config.animate.effect, self.__pageAnimCompleted);
		} else {
			return false;
		}
		
	}
	
	self.__pageAnimCompleted	= function () {
		$(this).remove ();
		
		
	}
	
	
	self.__pageAdded	= function () {
		if (self.pagination.current == (self._pages.length - 1)) {
			self.pagination.nextPage.removeClass ('active');
		} else {
			self.pagination.nextPage.addClass ('active');
		}
		
		if (self.pagination.current == 0) {
			self.pagination.prevPage.removeClass ('active');
		} else {
			self.pagination.prevPage.addClass ('active');
		}
		
	}
		
		
	self.initialize ();
}

jQuery (
	function () {
		
		var $window	= $(window),
			$document	= $(document);
		
		var $info		= $('#info'),
			$contact	= $('#contact');
		
		var $cb		= $('input:checkbox'),
			$div	= $(''),
			$nav	= $('nav'),
			img		= '<div class="checkbox"/>';
		
		
		function getCats () {
			return $cb.map (
				function () {
					return parseInt (this.value, 10);
				}
			).get ();
		}
		
		function __checkedCats () {
			return $cb.map (
				function () {
					if (this.checked) {
						return parseInt (this.value, 10);
					}
				}
			).get ();
		}
		
		
		
		window.Gallery	= new window.Gallery (imagelist,__checkedCats ());
		
		function loadInfo () {
			$info.fadeIn ();
			$document.bind ('click.info', closeInfo);
		}
		
		function loadContact () {
			$contact.fadeIn ();
			$document.bind ('click.contact', closeContact);
		}
		
		function closeInfo (e) {
			
			if (e && e.preventDefault) {
				var $target	= $(e.target);

				if (!$target.closest ('.col').length) {
					$document.unbind ('click.info');
					$info.fadeOut ();
					location.hash	= '/home';
				}
			} else {

			}
		}
		
		function closeContact (e) {
			if (e && e.preventDefault) {
				var $target	= $(e.target);
				
				if (!$target.closest ('.col').length) {
					$document.unbind ('click.contact');
					$contact.fadeOut ();
					location.hash	= '/home';
				}
			} else {

			}
		}
		
		function chooseCategories (cats) {

			for (var i = 0, l = cats.length; i < l; i++) {
				cats[i]	= parseInt (cats[i], 10);
			}


			Gallery.filter (cats);
			
			$('div.checkbox').each (
				function () {
					var $c	= $(this),
						$this	= $c.data ('checkbox');
						
					if ($.inArray (parseInt ($this.val (), 10), cats) == -1) {
						$this.prop ('checked', false);
						$c.removeClass ('checked');
					} else {
						$this.attr ('checked', true);
						$c.addClass ('checked');
					}
				}
			);
	
		}
		
		$('#home-link').bind ('click',	
			function () {
				chooseCategories (getCats ());
				location.hash	= '/home';
			}
		);

		$window.bind ('hashchange',
			function () {

				var path	= location.hash.substr (1),
					rCats	= /^\/categories\/([\d,]+)$/;
				if (path === '/info') {
					loadInfo ();
				} else if (path === '/contact') {
					loadContact ();
				} else if (rCats.test (path)) {
					closeInfo ();
					closeContact ();
					chooseCategories (rCats.exec (path)[1].split (','));
				}
			}
		);
		
		/* Arrow keys for slides */
		$document.data ('fancy.open', false);
		
		$document.bind ('keydown',
			function (e) {

				if ($document.data ('fancy.open') != true) {
					if (e.which == 39) {
						Gallery.nextPage ();
					}
					
					if (e.which == 37) {
						Gallery.prevPage ();
					}
				}
			}
		);

		$('#gallery').touchwipe ({
				wipeLeft: function() {
					Gallery.nextPage ();
				},
				wipeRight: function() {
					Gallery.prevPage ();
				},
				min_move_x: 30,
				preventDefaultEvents: false
			}
		);
		
		$document.touchwipe ({
				wipeLeft: function() {
					if ($document.data ('fancy.open') == true) {
						$.fancybox.next ();
					}
				},
				wipeRight: function() {
					if ($document.data ('fancy.open') == true) {
						$.fancybox.prev ();
					}
				},
				min_move_x: 30,
				preventDefaultEvents: false
			}
		);
		
		
		
		
		
		function __checkbox () {
			var $c		= $(this),
				$this	= $c.data ('checkbox');

			if ($cb.filter (':checked').length == 1 && $c.is ('.checked')) {

			} else {
				$c.toggleClass ('checked');
				
				if ($c.hasClass ('checked')) {
					$this.prop ('checked', true);
				} else {
					$this.prop ('checked', false);
				}
				
				location.hash	= '/categories/' + __checkedCats ().join (',');
				
			}
		}
		
		$cb.each (
			function () {
				var $c		= $(img),
					$this	= $(this);
				
				
				
				$this.css ('visibility', 'hidden');
				
				if ($this.is (':checked')) {
					$c.addClass ('checked');
				}
				
				$c.data ('checkbox', $this)
				.css ('position', 'absolute')
				.bind ('click', __checkbox)
				.appendTo (this.parentNode);
				
			}
		);
		
		
		
		if (location.hash != '') {

			$window.trigger ('hashchange');
		}
		
	}
);


