﻿/** Inbox v1.0 - Lightbox gallery for jQuery - (c) 2009 Ondrej Drkula, Inexes
		Based on Slimbox2 ((c) 2007-2009 Christophe Beyls <http://www.digitalia.be>, MIT-style license) */

(function($) {
	var win = $(window), options, images, activeImage = -1, activeURL, firstImage, prevImage, nextImage,
				lastImage, compatibleOverlay, middle, centerWidth, centerHeight, ie6 = !window.XMLHttpRequest,
				operaFix = window.opera && (document.compatMode == "CSS1Compat") && ($.browser.version >= 9.3),
				documentElement = document.documentElement, preload = {}, preloadPrev = new Image(),
				preloadNext = new Image(), overlay, toolbar, navigation, center, image, preview, firstLink,
				prevLink, slideLink, nextLink, lastLink, closeLink, counter, description, slider, running;

	/* Initialization */
	$(function() {
		$("body").append($([
						overlay = $('<div id="ibOverlay" />')[0],
						center = $('<div id="ibCenter" />')[0]]).css('display', 'none'));
		image = $('<div id="ibImage" />').appendTo(center).append(
						preview = $('<div />').css('position', 'relative')[0])[0];
		toolbar = $('<div id="ibTooolbar" />').appendTo(center).append([
						navigation = $('<div id="ibNavigation" />').appendTo(center).append([
								firstLink = $('<a id="ibFirstLink" />').click(first)[0],
								prevLink = $('<a id="ibPrevLink" />').click(previous)[0],
								slideLink = $('<a id="ibSlideLink" />').click(slideshow)[0],
								nextLink = $('<a id="ibNextLink" />').click(next)[0],
								lastLink = $('<a id="ibLastLink" />').click(last)[0]])[0],
						counter = $('<span id="ibCounter" />')[0],
						closeLink = $('<a id="ibCloseLink" />').click(close)[0]])[0];
		description = $('<div id="ibDescription" /><div style="clear: both;" />').appendTo(center)[0];
	});

	/* API */
	$.inbox = function(_images, startImage, _options) { // Open Inbox with the specified parameters
		options = $.extend({
			loop: false, 				// Allows to navigate between first and last images
			overlayOpacity: 0.8, 			// 1->opaque, 0->transparent (color is in the CSS file)
			overlayFadeDuration: 400, 		// Duration of the overlay fade-in and fade-out animations (in milliseconds)
			resizeDuration: 400, 			// Duration of each of the box resize animations (in milliseconds)
			resizeEasing: 'swing', 			// 'swing' is jQuery's default easing
			initialSize: { x: 250, y: 250 }, 	// Initial size of the image box (array of width and height in pixels)
			maxEImgSize: { x: 600, y: 600 }, 	// Maximal size of external image (array of width and height in pixels)
			videoSize: { x: 560, y: 453 }, 		// Video size (array of width and height in pixels)
			minWidth: 350, 				// Minimal center box width (in pixels)
			imageFadeDuration: 400, 		// Duration of the image fade-in animation (in milliseconds)
			slideshowDelay: 3000, 			// Delay between 2 images during slideshow (in milliseconds)
			descriptionMaxHeight: 80, 		// Maximal height of the description box (in pixels)
			navigationHeight: 31, 			// Height of the navigation box (in pixels)
			counterText: 'Image {x} from {y}', 	// False will disable counter text for image groups
			closerText: 'Close', 			// Text for close button
			firstText: 'First', 			// Text for first button
			prevText: 'Previous', 			// Text for previous button
			slideshowPlayText: 'Run slideshow', 	// Text for slideshow play button
			slideshowPauseText: 'Pause slideshow', 	// Text for slideshow pause button
			nextText: 'Next', 			// Text for next button
			lastText: 'Last', 			// Text for last button
			closeKeys: [27, 88, 67], 		// Array of keycodes to close inbox, (esc, 'x', 'c')
			firstKeys: [70, 90], 	 		// Array of keycodes to navigate to the first image ('f', 'z')
			prevKeys: [37, 80], 			// Array of keycodes to navigate to the previous image (left arrow, 'p')
			nextKeys: [39, 68, 78], 		// Array of keycodes to navigate to the next image (right arrow, 'd', 'n')
			lastKeys: [75, 76], 			// Array of keycodes to navigate to the last image ('k', 'l')
			slideshowKeys: [83], 			// Array of keycodes to play/pause slideshow ('s')
			fixImagePosition: false, 		// Set position of ibCenter (true->fixed, false->absolute)
			enablePreviewImageClick: true, 		// Enable the preview image to click for close
			enableOverlayClick: false, 		// Enable the overlay to click for close
			enableSlideshow: false, 		// Enable slideshow all photos
			displayNavigation: true, 		// Switch the navigaton visibility (true->show, false->hide)
			displayDescription: true		// Switch the description visibility (true->show, false->hide)
		}, _options);

		if (typeof _images == 'string') { _images = [[_images, startImage]]; startImage = 0; }
		middle = win.scrollTop() + ((operaFix ? documentElement.clientHeight : win.height()) / 2);
		centerWidth = options.initialSize.x; centerHeight = options.initialSize.y;
		$(center).css({
			top: Math.max(0, middle - (centerHeight / 2)),
			width: centerWidth, height: centerHeight,
			marginLeft: -centerWidth / 2
		}).show();
		compatibleOverlay = (ie6 || (overlay.currentStyle && (overlay.currentStyle.position != 'fixed')));
		if (compatibleOverlay) { overlay.style.position = 'absolute'; }
		$(overlay).css('opacity', options.overlayOpacity).fadeIn(options.overlayFadeDuration);
		position(); setup(1); images = _images; options.loop = (options.loop && (images.length > 1));
		firstImage = 0; lastImage = images.length - 1; running = false;
		return changeImage(startImage);
	};

	/*
	@param options:	Optional options object
	@param linkMapper:	Optional function(element, index) returning 
	an array containing 4 elements: image URL, image caption, image description and image class
	@param linksFilter:	Optional function(element, index) returning true (is in image collection) 
	or false (not in collection). 'this' refers to the element that was clicked.
	*/
	$.fn.inbox = function(_options, linkMapper, linksFilter) {
		linkMapper = (linkMapper || (function(el) {
			return [el.href, el.title, $(el).parent().parent().find('.description').eq(0).html(), el.className];
		}));
		//linksFilter = (linksFilter || (function() { return true; }));
		linksFilter = (linksFilter || (function(el) { return (this == el) || ((this.rel.length > 8) && (this.rel == el.rel)); }));
		var links = this;
		return links.unbind('click').click(function() {
			var link = this, startIndex = 0, filteredLinks, i = 0, length;
			filteredLinks = $.grep(links, function(el, i) { return linksFilter.call(link, el, i); });
			for (length = filteredLinks.length; i < length; ++i) {
				if (filteredLinks[i] == link) { startIndex = i; }
				filteredLinks[i] = linkMapper(filteredLinks[i], i);
			}
			return $.inbox(filteredLinks, startIndex, _options);
		});
	};

	/* Internal functions */
	function position() {
		var l = win.scrollLeft(), w = operaFix ? documentElement.clientWidth : win.width(); $(center).css("left", l + (w / 2));
		if (compatibleOverlay) { $(overlay).css({ left: l, top: win.scrollTop(), width: w, height: win.height() }); }
	}
	function setup(open) {
		try {
			$('object').add(ie6 ? 'select' : 'embed').each(function(index, el) {
				if (open) { $.data(el, 'inbox', el.style.visibility); } el.style.visibility = open ? 'hidden' : $.data(el, 'inbox');
			});
		} catch (err) { }
		var fn = open ? 'bind' : 'unbind'; win[fn]('scroll resize', position); $(document)[fn]('keydown', keyDown);
	}
	function keyDown(event) {
		var code = event.keyCode, fn = $.inArray;
		if (fn(code, options.closeKeys) >= 0) { return close(); }
		if (fn(code, options.nextKeys) >= 0) { return next(); }
		if (fn(code, options.prevKeys) >= 0) { return previous(); }
		if (!(options.loop)) {
			if (fn(code, options.firstKeys) >= 0) { return first(); }
			if (fn(code, options.lastKeys) >= 0) { return last(); }
		}
		if ((options.enableSlideshow) && (fn(code, options.slideshowKeys) >= 0)) { return slideshow(); }
		return false;
	}
	function first() {
		if (activeImage != firstImage) { return changeImage(firstImage); }
		return false;
	}
	function previous() {
		return changeImage(prevImage);
	}
	function next() {
		if (options.loop) { return changeImage(nextImage); }
		if (activeImage < lastImage) { return changeImage(nextImage); }
		if (running) { slideshowPause(); }
		return false;
	}
	function last() {
		if (activeImage != lastImage) { return changeImage(lastImage); }
		return false;
	}
	function slideshowPlay() {
		running = true;
		if (options.displayNavigation) { $(slideLink).addClass('pause').attr('title', options.slideshowPauseText); }
		if (!(options.loop) && (activeImage > firstImage)) { next(); }
		if (options.loop) { next(); }
		slider = setInterval(next, options.slideshowDelay);
	}
	function slideshowPause() {
		running = false;
		if (options.displayNavigation) { $(slideLink).removeClass('pause').attr('title', options.slideshowPlayText); }
		clearInterval(slider);
	}
	function slideshow() {
		if (running) { slideshowPause(); return false; }
		if (!(options.loop) && (activeImage == lastImage)) { first(); } slideshowPlay();
	}
	function changeImage(imageIndex) {
		if (imageIndex >= 0) {
			activeImage = imageIndex;
			activeURL = images[activeImage][0];
			prevImage = (activeImage || (options.loop ? images.length : 0)) - 1;
			nextImage = ((activeImage + 1) % images.length) || (options.loop ? 0 : -1);
			stop(); center.className = 'ibLoading';
			preload = new Image(); preload.alt = images[activeImage][1]; preload.className = images[activeImage][3];
			preload.onload = animateBox; preload.src = activeURL;
		}
		return false;
	}
	function setSize(size) {
		$(image).css('backgroundImage', 'none'); $(preview).width(size.x).height(size.y);
	}
	function resizeMedia() {
		$(image).find('object, embed').width(options.videoSize.x).height(options.videoSize.y);
	}
	function animateBox() {
		$(center).css('position', (options.fixImagePosition ? 'fixed' : 'absolute'));
		$(image).css({ backgroundImage: 'url(' + activeURL + ')', visibility: 'hidden', display: "" });
		var externalDoc = '', imgWidth = preload.width, imgHeight = preload.height;
		if (preload.className) {
			switch (preload.className) { // switch types of document
				case 'eImg':
					{
						if ((preload.width > options.maxEImgSize.x) || (preload.height > options.maxEImgSize.y)) {
							var ratio = preload.width / preload.height;
							if (preload.width > options.maxEImgSize.x) {
								imgWidth = options.maxEImgSize.x; imgHeight = preload.height / ((ratio > 0) ? ratio : (1 / ratio));
							}
							if (preload.height > options.maxEImgSize.y) {
								imgHeight = options.maxEImgSize.y; imgWidth = imgWidth / ((ratio > 0) ? ratio : (1 / ratio));
							}
						}
						setSize({ x: imgWidth, y: imgHeight });
						externalDoc = '<img src="' + preload.src + '" alt="' + preload.alt + '" width="' + imgWidth + '" height="' + imgHeight + '" />';
						if (options.enablePreviewImageClick) {
							$(preview).html($('<a title="' + options.closerText + '" style="display:block;width:' + $(preview).width() + 'px;height:' +
							$(preview).height() + 'px;">' + externalDoc + '</a>').click(close)[0]);
						} else { $(preview).html(externalDoc); }
						break;
					}
				case 'swf': case 'flv': case 'url': case 'code':
					{
						imgWidth = options.videoSize.x; imgHeight = options.videoSize.y; setSize(options.videoSize);
						setTimeout(function() { $(preview).html('<div class="movie">' + $(images[activeImage][2]).eq(0).html() + '</div>'); resizeMedia(); }, 300);
						break;
					}
				default: break;
			}
		} else {
			$(preview).width(imgWidth).height(imgHeight);
			if (options.enablePreviewImageClick) {
				$(preview).html($('<a title="' + options.closerText + '" style="display:block;width:' + $(preview).width() +
					'px;height:' + $(preview).height() + 'px;" />').click(close)[0]);
			}
		}
		if (prevImage >= 0) { preloadPrev.src = images[prevImage][0]; }
		if (nextImage >= 0) { preloadNext.src = images[nextImage][0]; }
		var imgBorder = parseInt($(image).css('border-width'));
		var ie6Border = (isNaN(imgBorder) ? 0 : (imgBorder * 2));
		centerWidth = ((ie6 ? (imgWidth + ie6Border) : image.offsetWidth) > options.minWidth ? (ie6 ? (imgWidth + ie6Border) : image.offsetWidth) : options.minWidth);
		centerHeight = (ie6 ? (imgHeight + ie6Border) : image.offsetHeight);
		if (options.enableOverlayClick) { $(overlay).css('cursor', 'pointer').click(close); }
		if (options.displayNavigation) {
			centerHeight += options.navigationHeight;
			$(image).css('top', (options.navigationHeight + 'px'));
			$(toolbar).height(options.navigationHeight);
			if (prevImage < 0) { $([firstLink, prevLink]).addClass('disabled'); }
			if (nextImage < 0) { $([nextLink, lastLink]).addClass('disabled'); }
			if (!(options.loop)) {
				$(firstLink).attr('title', options.firstText); $(lastLink).attr('title', options.lastText);
			} else { $([firstLink, lastLink]).remove(); }
			$(prevLink).attr('title', options.prevText); $(nextLink).attr('title', options.nextText);
			$(closeLink).attr('title', options.closerText);
			$(slideLink).attr('title', (running ? options.slideshowPauseText : options.slideshowPlayText));
			$(counter).html((((images.length > 1) && options.counterText) || '').replace(/{x}/, activeImage + 1).replace(/{y}/, images.length));
		} else { $(toolbar).remove(); }
		if (options.displayDescription) {
			$(description).html(images[activeImage][2] || "");
			$(description).find('.code').remove();
			centerHeight += $(description).outerHeight(true) + 20;
		} else { $(description).remove(); }
		if (!(options.enableSlideshow)) { $(slideLink).remove(); }
		var top = Math.max(0, middle - (centerHeight / 2));
		if (center.offsetHeight != centerHeight) { $(center).animate({ height: centerHeight, top: top }, options.resizeDuration, options.resizeEasing); }
		if (ie6) { $(center).css('background', $(center).css('background-color')); }
		if (center.offsetWidth != centerWidth) { $(center).animate({ width: centerWidth, marginLeft: -(centerWidth / 2) }, options.resizeDuration, options.resizeEasing); }
		$(center).queue(function() {
			if (options.displayDescription) { $(description).css('top', (imgHeight + /**/10/**/ + ($.browser.msie ? (ie6Border / 2) : 0) + 'px')).show(); }
			$(image).css({ display: 'none', visibility: '', opacity: '' }).fadeIn(options.imageFadeDuration);
		});
	}
	function stop() {
		preload.onload = null; preload.src = preloadPrev.src = preloadNext.src = activeURL;
		$([center, image]).stop(true); $(image).hide();
		if (options.displayDescription) { $(description).hide(); }
		if (options.displayNavigation) { $([firstLink, prevLink, nextLink, lastLink]).removeClass('disabled'); }
	}
	function close() {
		if (running) { slideshowPause(); } // stop slideshow
		$(image).find('.movie').eq(0).remove(); // stop flvplayer
		if (activeImage >= 0) {
			stop(); activeImage = prevImage = nextImage = -1; $(center).hide();
			$(overlay).stop().fadeOut(options.overlayFadeDuration, setup);
		}
		return false;
	}
})(jQuery);

// onload initialization
jQuery(function($) {
	$('a[rel^="lightbox"]').each(function() {
		if ($(this).hasClass('swf') || $(this).hasClass('flv')) { // swf and flv tunning
			var video;
			if ($.browser.msie) {
				video = '<object style="visibility: visible;" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="425" height="344">';
				video += '<param name="movie" value="' + ($(this).hasClass('flv') ? (appWWWRoot + 'FlvPlayer/FlvPlayer.swf?movieURL=') : '') + $(this).attr('href');
				video += '"><param name="allowscriptaccess" value="always"><param name="allowfullscreen" value="true"></object>';
			} else {
				video = '<object type="application/x-shockwave-flash" data="' + ($(this).hasClass('flv') ? (appWWWRoot + 'FlvPlayer/FlvPlayer.swf?movieURL=') : '') + $(this).attr('href');
				video += '" width="425" height="344" /><!--<![endif]--></object>';
			}
			$(this).parent().parent().find('.description').eq(0).prepend('<div class="code">' + video + '</div>');
			$(this).attr('href', $(this).find('img').eq(0).attr('src'));
		}
		if ($(this).hasClass('url')) { // external url tunning
			$(this).parent().parent().find('.description').eq(0).prepend('<div class="code"><a href="' + $(this).attr('href') + '" class="oembed"></a></div>');
			$(this).attr('href', $(this).find('img').eq(0).attr('src'));
			try {
				$(this).parent().parent().find('.description .code a.oembed').eq(0).oembed();
			} catch (err) {
				$(this).attr('class', 'eImg');
				$(this).attr('href', 'Design/Unknown.gif');
			}
		}
		if ($(this).hasClass('code')) { $(this).attr('href', $(this).find('img').eq(0).attr('src')); } // html code tunning
	});
});

