$(document).ready(function() {
	$('#slideshow').gallery();
});

var IMG_CONTAINER_WIDTH = 100,
	IMG_CONTAINER_HEIGHT= 75,
	IMG_OPACITY_NO = 0.1,
	IMG_OPACITY_HO = 1,
	IMG_BORDER_WIDTH = 75,
	IMG_BORDER_HEIGHT = 75;

(function($) {
	$.fn.gallery = function() {
		
		return this.each(function() {
			
			var $this = $(this);
			$galleries = $this.find('.image-dir');
			$controls = $this.parent().find('#controls');
			$corte = $controls.find(".corte");
			$next = $controls.find('.next');
			$prev = $controls.find('.prev');
			$up = $controls.find('.up');
			$down = $controls.find('.down');
			$close = $controls.find(".close");

			var hasNext = function(obj) {
				return obj.next('.image').length;
			}
			
			var hasPrev = function(obj) {
				return obj.prev('.image').length;
			}
			
			var hasUp = function(obj) {
				return obj.parent().prev('.image-dir').length;
			}
			
			var hasDown = function(obj) {
				return obj.parent().next('.image-dir').length;
			}
			
			var setTop = function(obj) {
				var $height = obj.outerHeight(true),
					index = obj.parent().index(),
					height = 0;
				for (var i = 0; i < index; i++) {
					height -= getMaxHeightOfGallery($galleries.eq(i)) + 50;
				}
				height += ((screenHeight() - $height)/2);
				$this.animate({'top': height + 'px'});
			};
			
			var setLeft = function(obj) {
				var $width = obj.outerWidth(true),
					index = obj.index(),
					width = 0,
					imgs = obj.parent().find('.image');
				for (var i = 0; i < index; i++) {
					width -= imgs.eq(i).outerWidth(true);
				}

				var fill = (getMaxWidth() - obj.parent().width()) / 2;
				width -= fill;

				width += ((screenWidth() - $width) / 2);
				$this.animate({'left': width + 'px'});
			}
			
			var setTopLeft = function(obj) {
				var $height = obj.outerHeight(true),
					index1 = obj.parent().index(),
					height = 0;
				for (var i = 0; i < index1; i++) {
					height -= getMaxHeightOfGallery($galleries.eq(i)) + 50;
				}
				height += ((screenHeight() - $height)/2);

				var $width = obj.outerWidth(true),
					index2 = obj.index(),
					width = 0,
					imgs = obj.parent().find('.image');
				for (var i = 0; i < index2; i++) {
					width -= imgs.eq(i).outerWidth(true);
				}

				var fill = (getMaxWidth() - obj.parent().width()) / 2;
				width -= fill;

				width += ((screenWidth() - $width) / 2);
				$this.stop().animate({'left': width + 'px', 'top': height + 'px'});
			};
			
			var maximize = function(obj) {
				$this
					.css({
						position: 'absolute',
						overflow: 'visible',
						top: 0,
						left: 0,
						marginTop: 0
					})
					.addClass("max");

				$galleries.css({
					marginBottom: '50px'
				});

				$controls.find("li").fadeIn();
				$controls.css("margin-left", "-257px");

				
				$galleries.each(function() {
					var $gal = $(this),
					$imgs = $gal.find('.image');
					$imgsCount = $gal.find(".image").length;

					var galWidth = 0;
						
					$imgs.each(function() {
						maximizeImage($(this));
						$(this).css({
							opacity: IMG_OPACITY_NO,
							marginRight: '50px'
						});
					
						galWidth += $(this).find("img").width();

						if (! $(this).find("p").length) {
						var subjectText = $(this).attr("data-subject");
						var subject = $("<p/>").text(subjectText).appendTo($(this));
						subject.css("width", $(this).width());
						}

						$(this).unbind('click').unbind('mouseover').unbind('mouseout');
						$(this).click(function() {
							maxImgClick($(this));
						});
					});
				
					imgMargin = $imgsCount * 50;
					$gal.css("width", galWidth + imgMargin + 5);
				});
				
				obj.css({opacity: IMG_OPACITY_HO});
				
				resizeContainer();
				
				setTop(obj);
				setLeft(obj);
				
				next(obj);
				prev(obj);
				up(obj);
				down(obj);
				close();
			};
			
			var minimize = function(obj) {
				$this.css({
					position: 'static',
					left: '0',
					top: '0',
					overflow: 'hidden',
					width: 'auto',
					height: 'auto'
				});

				$this.removeClass("max");
				
				$galleries.css({
					marginBottom: '10px'
				});

				$galleries.each(function() {
					var $gal = $(this),
					$imgs = $gal.find('.image');
					$imgsCount = $gal.find(".image").length;

					var galWidth = 0;
						
					$imgs.each(function() {

						minimizeImage($(this));

						galWidth += $(this).find("img").width();
						/*
						 * CLICK HANDLING
						 */
						$(this)
							/*
							.mouseover(function() {
								$(this).find('img').css({opacity: IMG_OPACITY_HO});
							})
							.mouseout(function() {
								$(this).find('img').css({opacity: IMG_OPACITY_NO});
							})
							*/
							.click(function() {
								$(this).addClass('cur');
								maximize($(this));
							}).
							removeClass("cur")
							.css({
								opacity: IMG_OPACITY_HO,
								marginRight: '10px'
							})
							.find("img").css({opacity: IMG_OPACITY_HO});
					});
					
					imgMargin = $imgsCount * 11;
					$gal.css("width", galWidth + imgMargin + 1);
				});

				var posTop = ($(window).height() - $this.height()) / 2;
				$this.css("margin-top", posTop + "px");
				
				$up.fadeOut();
				$down.fadeOut();
				$prev.fadeOut();
				$next.fadeOut();
				$close.fadeOut();
				
				$controls.css("margin-left", "-137px");
			};
			
			var maximizeImage = function(img) {
				var $img = img,
					$width = $img.attr('data-width'),
					$height = $img.attr('data-height'),
					$w = 0,
					$h = 0;

				/*
				if (maxImageWidth() < maxImageHeight()) {
					$w = maxImageWidth();
					$h = ($w / $width) * $height;
				}
				else {
					$h = maxImageHeight();
					$w = ($h / $height) * $width;
				}
				*/

				$h = 500;
				$w = ($h / $height) * $width;

				$img.css({
					width: $w + 'px',
					height: $h + 'px'
				});
				$img.find('img').css({
					width: $w + 'px',
					height: $h + 'px'
				});
			};

			var minimizeImage = function(img) {
				
				var $img = img;
				
				$width = $img.attr('data-width');
				$height = $img.attr('data-height');
				$w = (IMG_CONTAINER_HEIGHT / $height) * $width;
				
				$img.css({
					width: $w + 'px',
					height: IMG_CONTAINER_HEIGHT + 'px'
				});
				$img.find('img').css({
					width: $w + 'px',
					height: IMG_CONTAINER_HEIGHT + 'px'
				});

				$img.find("p").remove();
			}
			
			var screenWidth = function() {
				return $(window).width();
			};
			
			var screenHeight = function() {
				return $(window).height();
			};
			
			var maxImageWidth = function() {
				return screenWidth() - (2 * IMG_BORDER_WIDTH);
			};
			
			var maxImageHeight = function() {
				return screenHeight() - (2 * IMG_BORDER_HEIGHT);
			};
			
			/**
			 * Gets max width of images in all rows
			 */
			var getMaxWidth = function() {
				var $width = 0;
				$galleries.each(function() {
					var $gal = $(this),
						$imgs = $gal.find('.image'),
						width = 0;
					$imgs.each(function() {
						width += $(this).outerWidth(true);
					});
					if (width > $width) {
						$width = width;
					}
				});
				return $width;
			};
			
			/**
			 * Get max height of gallery
			 */
			var getMaxHeightOfGallery = function(gal) {
				var $imgs = gal.find('.image'),
					height = 0;
				$imgs.each(function() {
					imgHeight = $(this).outerHeight(true);
					if (imgHeight > height) {
						height = imgHeight;
					}
				});
				return height;
			};
			
			/**
			 * Gets sum of heights
			 */
			var getMaxHeight = function() {
				var $height = 0;
				$galleries.each(function() {
					var $gal = $(this);
					$height += getMaxHeightOfGallery($gal);
				});
				return $height;
			};
			
			/**
			 * Resizes the container
			 */
			var resizeContainer = function() {
				var h = getMaxHeight() + parseInt($galleries.eq(0).css('margin-bottom')) * 2 * $galleries.length;
				//var w = getMaxWidth() + parseInt($galleries.eq(0).css('margin-left')) * 2 * $galleries.length;
				var w = getMaxWidth();				
				
				$this.css({
					width: w + 'px',
					height: h + 'px'
				});
			};
			
			var unbindControls = function() {
				$down.unbind('click');
				$up.unbind('click');
				$prev.unbind('click');
				$next.unbind('click');
			};

			// Arrow keys
			$(document).keydown(function(e) {
				
				var obj = $this.find(".cur");

				// Up
				if (e.which == 38) {
					if (hasUp(obj)) {
						var newObj = getNextUp(obj);
						doSlide(obj, newObj);
					}

					return false;
				}	
				// Down	
				else if (e.which == 40) {
					if (hasDown(obj)) {
						var newObj = getNextDown(obj);
						doSlide(obj, newObj);
					}

					return false;
				}
				// Next
				else if (e.which == 39) {
					
					if (hasNext(obj)) {
						doSlide(obj, obj.next());
					}

					return false;
				}
				// Prev
				else if (e.which == 37) {
					if (hasPrev(obj)) {
						doSlide(obj, obj.prev());
					}

					return false;
				}
				// Esc (close)
				else if (e.which == 27) {
					minimize($this);
					return false;
				}
			});
			
			// Get next up
			var getNextUp = function(obj) {
				var dirUp = obj.parent().prev('.image-dir');
				var objLeft = obj.position().left + (obj.outerWidth(true) / 2);
				
				var fill = (getMaxWidth() - dirUp.width()) / 2;

				var objWidth = fill;
				dirUp.find(".image").each(function() {
					objWidth += $(this).outerWidth(true);

					if (objWidth > objLeft) {
						newObj = $(this);

						return false;
					}
				});

				if (objWidth < objLeft) {
					newObj = dirUp.find(".image:last");
				}
				
				return newObj;
			}

			// Get next down
			var getNextDown = function(obj) {
				var dirDown = obj.parent().next('.image-dir');
				var objLeft = obj.position().left + (obj.outerWidth(true) / 2);

				var fill = (getMaxWidth() - dirDown.width()) / 2;

				var objWidth = fill;
				dirDown.find(".image").each(function() {
					objWidth += $(this).outerWidth(true);

					if (objWidth > objLeft) {
						newObj = $(this);

						return false;
					}
				});
				
				if (objWidth < objLeft) {
					newObj = dirDown.find(".image:last");
				}

				return newObj;

			}
			
			// Executes the slide
			var doSlide = function(obj, newObj) {
				obj
					.removeClass('cur')
					.find('img').animate({opacity: IMG_OPACITY_NO})
					.find("p").remove();
				newObj
					.addClass('cur')
					.css({opacity: IMG_OPACITY_HO});
				newObj.find('img').animate({opacity: IMG_OPACITY_HO});
					
				$this.find('.image p').addClass("inactive");

				newObj.find("p").removeClass("inactive");
				
				unbindControls();
				up(newObj);
				down(newObj);
				next(newObj);
				prev(newObj);
				setTopLeft(newObj);
			}
		
			// Next button	
			var next = function(obj) {
				if (hasNext(obj)) {
					$next.removeClass("off");
					$next.click(function() {
						var newObj = obj.next();
						doSlide(obj, newObj);
					});
				}
				else {
					$next.addClass("off");
				}
			};
			
			// Prev button
			var prev = function(obj) {
				if (hasPrev(obj)) {
					$prev.removeClass("off");
					$prev.click(function() {
						var newObj = obj.prev();
						doSlide(obj, newObj);
					});
				}
				else {
					$prev.addClass("off");
				}
			};

			// Up button	
			var up = function(obj) {
				if (hasUp(obj)) {
					$up.removeClass("off");
					$up.click(function() {
						var newObj = getNextUp(obj);	
						doSlide(obj, newObj);
					});
				}
				else {
					$up.addClass("off");
				}
			};
		
			// Down button	
			var down = function(obj) {
				if (hasDown(obj)) {
					$down.removeClass("off");
					$down.click(function() {
						
						var newObj = getNextDown(obj);
						doSlide(obj, newObj);
					});
				}
				else {
					$down.addClass("off");
				}
			};

			// Image click
			var maxImgClick = function(obj) {
				if (! obj.hasClass("cur")) {
					var newObj = obj;
					var oldObj = $this.find(".cur");

					doSlide(oldObj, newObj);
				}
			}

			// Close
			var close = function(obj) {
				$close.click(function() {
					minimize($this);
				}); 
			}

			// About
			$corte.find("h1").mouseover(function() {
				$corte.find("#about").fadeIn();
				
				$(window).bind("ontouchstart", function() {
					$corte.find("#about").fadeOut();
				});
			});

			$corte.mouseleave(function() {
				$corte.find("#about").fadeOut();
			});

			$(window).resize(function() {

				if (! $this.hasClass("max")) {
					var posTop = ($(window).height() - $this.height()) / 2;
					$this.css("margin-top", posTop + "px");
				}
			});
			
			/*
			 * GALLERIES
			 */
			$galleries.each(function() {
				var $gal = $(this),
				$imgs = $gal.find('.image');

				$imgsCount = $gal.find(".image").length;

				var galWidth = 0;
				
				/*
				 * IMAGES
				 */
				$imgs.each(function() {
					var $img = $(this),
						$width = $img.attr('data-width'),
						$height = $img.attr('data-height');
				
					
					$w = (IMG_CONTAINER_HEIGHT / $height) * $width;

					galWidth += $w;
					
					var img = $img.find("img");

					img.css({'width': $w + 'px', 'height': IMG_CONTAINER_HEIGHT + 'px'});
					$img.css({'width': $w + 'px', 'height': IMG_CONTAINER_HEIGHT + 'px'});

					//img.css({opacity: IMG_OPACITY_NO});

					img.fadeIn();
					$img.find(".loader").fadeOut(400);
					
					/*
					 * CLICK HANDLING
					 */
					$img
						/*
						.mouseover(function() {
							$(this).find('img').css({opacity: IMG_OPACITY_HO});
						})
						.mouseout(function() {
							$(this).find('img').css({opacity: IMG_OPACITY_NO});
						})
						*/
						.click(function() {
							$(this).addClass('cur');
							maximize($(this));
							//$galleries.find('.image').css({opacity: IMG_OPACITY_HO});
						});
				});
				
				imgMargin = $imgsCount * 10;
				$gal.css("width", galWidth + imgMargin + 1);

				var posTop = ($(window).height() - $this.height()) / 2;
				$this.css("margin-top", posTop + "px");

				if ($.browser.msie && $.browser.version < 8) {
					$galleries.eq(0).css("margin-top", posTop + "px");
				}
			});
		});
	}
}) (jQuery);

