(function($)
{
	$.fn.shadowGallery = function(options)
	{
		options = $.extend({ }, $.fn.shadowGallery.defaults, options);
		return this.each(function()
		{
			$this = $(this);
			
			if (options.thumbnails)
			{
				// Set up thumbnails.
				var images = $this.filter('img').each(function()
				{
					// First pass; immediately as function is called. We do this a) so that at least
					// something has been done until the images have loaded and b) because Firefox
					// doesn't fire the 'load' event when navigating back.
					renderThumbnail(this, options.links);
					$(this).show();
					
					// Second pass: when image has loaded. This ensures that the width/height calculations
					// have been done correctly.
					$(this).load(function()
					{
						renderThumbnail(this, options.links);
					});
				});
			}
			
			if (options.shadowbox)
			{
				// Add Shadowbox relations.
				var container = $this.parent();
				if (!container.is('a'))
				{
					$this.wrap('<a href="' + $this.attr('src') + '"></a>');
					container = $this.parent();
				}
				
				var links = container.attr('rel', 'shadowbox[' + options.galleryId + ']');
				Shadowbox.setup($.makeArray(links), options.shadowboxOptions);
			}
			
			if ((options.links || options.shadowbox) && options.fade)
			{
				// Add hover-fade to images.
				images.css('opacity', options.defaultOpacity);
				images.hover(function()
				{
					$(this).fadeTo(options.fadeSpeed, options.hoverOpacity);
				}, function()
				{
					$(this).fadeTo(options.fadeSpeed, options.defaultOpacity);
				});
			}
		});
	};
	
	$.fn.shadowGallery.defaults =
	{
		links: true,
		fade: true,
		thumbnails: true,
		shadowbox: true,
		shadowboxOptions: { },
		defaultOpacity: 0.75,
		hoverOpacity: 1,
		fadeSpeed: 'fast',
		galleryId: 'shadow-gallery'
	};
	
	$.fn.renderThumbnails = function()
	{
		return this.filter('img').each(function()
		{
			renderThumbnail(this, false);
		});
	};
	
	function renderThumbnail(image, links)
	{
		image = $(image);
		var container = image.parent();
		if (links)
		{
			if (container.is('a:not(.thumbnail-scaled)'))
			{
				// Don't bother generating thumbnails if a (non-generated) link's already provided.
				return;
			}
			
			if (!container.is('a.thumbnail-scaled'))
			{
				// Generate a link to surround the image.
				image.wrap('<a href="' + image.attr('src') + '"></a>');
				container = image.parent().addClass('thumbnail-scaled');
			}
		}
		else
		{
			if (!container.is('.thumbnail-scaled'))
			{
				// Generate an inert wrapper.
				image.wrap('<div></div>');
				container = image.parent().addClass('thumbnail-scaled');
			}
		}
		
		container.css('overflow', 'hidden');
		
		// Generate scaled thumbnails. Thanks Galleria!
		var containerWidth = container.width();
		var containerHeight = container.height();
		var imageWidth = image.width();
		var imageHeight = image.height();
		var width = Math.ceil(imageWidth / imageHeight * containerHeight);
		var height = Math.ceil(imageHeight / imageWidth * containerWidth);
		if (imageWidth / imageHeight < containerWidth / containerHeight)
		{
			if (!isNaN(height))
			{
				image.css({ height: 'auto', width: containerWidth, marginTop: - (height - containerHeight) / 2, marginLeft: 0 });
			}
		}
		else
		{
			if (!isNaN(width))
			{
				image.css({ width: 'auto', height: containerHeight, marginLeft: - (width - containerWidth) / 2, marginTop: 0 });
			}
		}
	}
})(jQuery);