/*
 * Lightbox
 * Reusable custom jQuery lightbox
 *
 * @author Zach Waugh <zwaugh@gmail.com>
 * @version 0.8
 * @requires center() plugin
 *
 * Last Updated: 6/16/10
 * 
 * TODO:
 * - animate between gallery images
 * - provide defaults/options
 */

(function($)
{
	var useAjax = false;
	var resizeTimer = null;
	
	$.fn.lightbox = function()
	{	
		return $(this).live('click', init);
	};
	
	
	/**
	 * Initialize the lightbox
	 */
	function init(event)
	{
		var source = $(this).attr('href');
		
		// Check if pointing another element
		if (source.substring(0, 1) == '#')
		{
		 	showLightbox($(source).html());
		}
		else if (source.substring(0, 7) == 'http://' || source.substring(0, 1) == '/')
		{
			// Check if URL is pointing to an image
			if (isImage(source))
			{
				loadImage($(this));
			}
			else
			{
				// Load the contents via AJAX or into an iframe
				if (useAjax)
				{
					$.get(source, function (html)
					{
						showLightbox(html);
					});
				}
				else
				{
					showLightbox('<iframe width="960" height="680" src="' + source + '"></iframe>');
				}
			}

		}
		else
		{
			showLightbox('ERROR');
		}
		
		return false;
	}


	/**
	 * Perform actual creation and display of lightbox
	 * @param {String} content - HTML to put in lightbox
	 * @param {object} size - size of image
	 */
	function showLightbox(content, size, state)
	{
		// If lightbox already visible, just update content area
		if ($('#lightbox').length > 0)
		{
			$('#lightbox').data('state', state);
			if (size !== undefined)
			{
				$('#lightbox').css({width: size.width + 20});
				$('#lightbox_content').css({width: size.width});
			}
		
			$('#lightbox_content').html(content);
			$('#lightbox').center();
		}
		else
		{
			var html = '<div id="lightbox_overlay" style="opacity: 0;"></div>';
			html += '<div id="lightbox" style="display:none; width:' + (size.width + 20) + 'px;">';
			
			html += '<div id="lightbox_top">';
			html += '<a href="#" class="previous"></a>';
			html += '<a href="#" class="next"></a>';
			html += '</div>';
			
			if (size !== undefined)
			{
				html += '<div id="lightbox_content" style="width:' + size.width + 'px;">';
			}
			else
			{
				html += '<div id="lightbox_content">';
			}
			
			html += content;
			html += '</div>';
			// html += '<a href="#" id="lightbox_previous" class="previous" style="opacity: 0;">prev</a>';
			// html += '<a href="#" id="lightbox_next" class="next" style="opacity: 0;">next</a>';
			html += '<a href="#" id="lightbox_close" title="Close">close</a>';
			html += '</div>';

			$('body').append(html);
			$('#lightbox a.previous, #lightbox a.next').live('click', loadGalleryImage);
			//$('#lightbox').mouseenter(showControls).mouseleave(hideControls);
			$('#lightbox').data('state', state);
			$('#lightbox_close').click(closeLightbox);
			$('#lightbox_overlay').one('click', closeLightbox);
			$('#lightbox_overlay').animate({opacity: 0.75}, 250);
			$('#lightbox').center().fadeIn(250);
			$(document).bind('keydown.lightbox', keyboardListener);
		}

		$(window).bind('resize.lightbox', resizeWindow);
	}


	/**
	 * Close lightbox if ESC key is pressed
	 * @param {jQuery Event Object} event
	 */
	function keyboardListener(event)
	{
		if (event.which == 27)
		{
			closeLightbox(event);
		}
	}


	/**
	 * Load an image based on href of link
	 * @param {jQuery Object} element
	 */
	function loadImage(element)
	{
		var url = element.attr('href');
		var title = element.attr('title');
		var gallery = element.attr('rel');
		var gallery_images = [];
		var state = {gallery: gallery};
		
		// Check if photo is part of collection
		if (gallery !== '')
		{
			gallery_images = $('a[rel=' + gallery + ']');
		}
		
		var image = new Image();
		
		image.onload = function()
		{
			// Resize image to make sure it's not bigger than window
			var size = resizeImage(image.width, image.height);
			
			var html = '<img src="' + url + '" width="' + size.width + '" height="' + size.height + '" alt="" />';
			html += '<div id="lightbox_bottom">';
			html += '<p class="title">' + title + '</p>';
			
			if (gallery_images.length > 0)
			{
				var current = gallery_images.index(element) + 1;
				var previous = (current == 0) ? gallery_images.length : current - 1;
				var next = (current == gallery_images.length) ? 1 : current + 1;
				state.currentIndex = current;
				state.previousIndex = previous;
				state.nextIndex = next;
			}
			else
			{
				$('#lightbox').unbind('mouseenter mouseleave');
			}
			
			html += '</div>';
			
			showLightbox(html, size, state);
		}
		
		image.src = url;
	}


	/**
	 * Load next/previous image from a gallery
	 * @param {jQuery Event Object} event
	 */
	function loadGalleryImage(event)
	{
		var state = $('#lightbox').data('state');
		var gallery = $('a[rel=' + state.gallery + ']');
	
		if ($(this).hasClass('previous'))
		{
			loadImage(gallery.eq(state.previousIndex - 1));
		}
		else if ($(this).hasClass('next'))
		{
			loadImage(gallery.eq(state.nextIndex - 1));
		}
		
		return false;
	}
	
	
	function showControls()
	{
		$('#lightbox_previous, #lightbox_next').stop().animate({opacity: 1});
	}
	
	
	function hideControls()
	{
		$('#lightbox_previous, #lightbox_next').stop().animate({opacity: 0});
	}
	
	
	/**
	 * Hide lightbox and remove from DOM, unbind event handlers
	 * @param {jQuery Event Object} event
	 */
	function closeLightbox(event)
	{
		// Unbind event handlers outside #lightbox
		$(window).unbind('resize.lightbox');
		$(document).unbind('keydown.lightbox');
		
		// Fade out and remove from DOM
		$('#lightbox, #lightbox_overlay').fadeOut(250, function()
		{
			$(this).remove();
		});
		
		return false;
	}


	/**
	 * Resize an image to ensure it's not bigger than window
	 * @param {Object} size - object with images width and height
	 */
	function resizeImage(width, height)
	{
		var windowWidth = $(window).width();
		var windowHeight = $(window).height();
		var ratio = 1;
		var padding = 200;
		var imgWidth = width, imgHeight = height;
	
		if ((width + padding) > windowWidth && (height + padding) > windowHeight)
		{
			if (width > height)
			{
				ratio = imgHeight / imgWidth;
				imgWidth = windowWidth - padding;
				imgHeight = ratio * imgWidth;
				
				if ((imgHeight + padding) > windowHeight)
				{
					imgHeight = windowHeight - padding;
					imgWidth = imgHeight / ratio;
				}
			}
			else
			{
				ratio = imgWidth / imgHeight;
				imgHeight = windowHeight - padding;
				imgWidth = ratio * imgHeight;
				
				if ((imgWidth + padding) > windowWidth)
				{
					imgWidth = windowWidth - padding;
					imgHeight = imgWidth * ratio;
				}
			}
		}
		else if ((width + padding) >= windowWidth)
		{
			ratio = imgHeight / imgWidth;
			imgWidth = windowWidth - padding;
			imgHeight = ratio * imgWidth;
		}
		else if ((height + padding) >= windowHeight)
		{
			ratio = imgWidth / imgHeight;
			imgHeight = windowHeight - padding;
			imgWidth = ratio * imgHeight;
		}

		return {width: parseInt(imgWidth), height: parseInt(imgHeight)};
	}


	/**
	 * Check if a url points to an image
	 * a bit hacky but it works in 99% of cases, as long as image has an extension
	 * @param {String} url
	 */
	function isImage(url)
	{
		return /(.png|.jpg|.jpeg|.gif|.tiff|.bmp)/.test(url.toLowerCase());
	}


	/**
	 * Handle window resize event
	 */
	function resizeWindow()
	{
		if (resizeTimer)
		{
			clearTimeout(resizeTimer);
		}
		
		resizeTimer = setTimeout(resizeLightbox, 100);
	}


	/**
	 * Recenter lightbox as window is resized
	 */
	function resizeLightbox()
	{
		$('#lightbox').center();
	}
})(jQuery);
