(function($){
	$.fn.site_gallery = function(options) {
		var defaults = {
			// Set the class name to be applied to the swapped gallery element.
			css_class: "site-gallery",
			// Set the number of columns. 0 is free flow. 2 or higher will provide a divisions for each row.
			columns: 3
		};
		// Overwite defaults if options were sent.
		var options = $.extend(defaults, options);
		// Create an initialising function that creates some dependant variables.
		var init = function()
		{
			// Create a class used on the wrapper to indicate a the number of columns.
			options.columns_class = options.css_class + '-columns-' + options.columns;
			// Create a class used on the wrapper to indicate a the number of columns.
			options.new_row_class = options.css_class + '-row'; 
		}
		// Initialise the dependant variables.
		init();
		// Prepare an array for images.
		my_images = [];
		// Create a swap image function.
		var swap_image = function()
		{
			// Create an image to later check when it has loaded.
			my_images[my_images.length] = {image:new Image(), class_name: ''};
			// Add the source to the image.
			my_images[my_images.length - 1].image.src = $(this).attr('href');
			// Create a unique class name.
			var img_class = options.css_class + '-' + $('*').index(this) + '-img-' + (my_images.length - 1);
			// Add the image class to the array object.
			my_images[my_images.length - 1].class_name = img_class;
			// Replace the link with an image.
			$(this).replaceWith('<img class="' + img_class + '" src="' + $(this).attr('href') + '" alt="' + $(this).text() + '" />');
		}
		return this.each(function() {
			var wrapper = this;
			// Check if the wrapper is an unordered or ordered list.
			if (this.tagName.search(/ul|ol/gi) != -1)
			{
				// State if play: ul li a
				// Process the list.
				$('li', this).find('a:first').each(function() {
					// Check for images.
					if ($(this).attr('href').search(/\.jpeg$|\.jpg$|\.png$|\.gif$/gi) != -1)
					{
						// Process images.
						$(this).each(swap_image);

					}
					// Check for other stuff like swf here is possible, but not coded.
				});
				
				// State of play: ul li img
				
				// Check if 2 or more columns has been specified.
				if (options.columns > 1)
				{
					// Prepare an array for items.
					var item_array = [];
					// Replace each list item with its contents wrapped in div.[css_class]-item div.[css_class]-item-inner and div.[css_class]-item-inner-2.
					$('li', this).each(function() {
						$(this).wrap('<div class="' + options.css_class + '-item"><div class="' + options.css_class + '-item-inner"><div class="' + options.css_class + '-item-inner-2"></div></div></div>').before($(this).contents().clone(true)).remove();
					});
					
					// State of play: ul div.[css_class]-item div.[css_class]-item-inner div.[css_class]-item-inner-2 img
					
					// Get the item divs.
					var items = $('> div', this);
					var length = items.length;
					// Set a row counter.
					var a = 0;
					// Iterate over the item indexes at the start of each column.
					for (var i = 0; i < length; i = i + options.columns)
					{
						// Determine the end of row item index.
						var end = i + options.columns - 1;
						if (end > length - 1)
						{
							end = length - 1;
						}
						// Append a new row div to the wrapper.
						$(this).append('<div class="' + options.new_row_class + '"></div>');
						// Iterate through each column item in the row.
						for (var j = i; j < end + 1; j++)
						{
							// Append each column item to the newly created row div.
							$('div.' + options.new_row_class, this).eq(a).append(items.eq(j));

						}
						// Advance the row counter.
						a++;
					}
					// State of play: ul div.[css_class]-row div.[css_class]-item div.[css_class]-item-inner div.[css_class]-item-inner-2 img
				}
				else
				{
					// To do.
				}
				// Set the new class name for the wrapper.
				var css_class = options.css_class;
				// Check if the class name is the same as the old one.
				if ($(this).hasClass(css_class))
				{
					// Wrapper and default css class the same. Append a string to distinguish the two then apply the class.
					css_class += '-jquery';
				}
				// Prepare a columns class.
				var columns_class = '';
				// Check if 2 or more columns has been specified.
				if (options.columns > 1)
				{
					// Set the columns class.
					columns_class = ' ' + options.columns_class;
				}
				// Combine the classes into the class attribute.
				class_attr = ' class="' + css_class + columns_class + '"';
				// Replace the wrapper with its contents and wrap it with div.[css_class][columns_css]
				$(this).wrap('<div' + class_attr + '></div>').before($(this).contents().clone(true)).remove();
				
				// State of play: div.[css_class][columns_css] div.[css_class]-row div.[css_class]-item div.[css_class]-item-inner div.[css_class]-item-inner-2 img
				
				// Apply a class for portrait image on the image. Only possible once the images are loaded.
				// Two window events because of browser compatibility.
				$(window).load(function() {
					// Iterate over the images array.
					for (i = 0; i < my_images.length; i++)
					{
						//alert(my_images[i].image.width + ' ' + my_images[i].image.height);
						// Check if the width is less than the height.
						if (my_images[i].image.width < my_images[i].image.height)
						{
							// Apply the class name [css_class]-portrait.
							$('img.' + my_images[i].class_name).addClass(options.css_class + '-portrait');
						}
					}
					return true;
				});
				$(window).ready(function() {
					// Iterate over the images array.
					for (i = 0; i < my_images.length; i++)
					{
						// Check if the width is less than the height.
						if (my_images[i].image.width < my_images[i].image.height)
						{
							// Apply the class name [css_class]-portrait.
							$('img.' + my_images[i].class_name).addClass(options.css_class + '-portrait');
						}
					}
					return true;
				});

			}
			else
			{
				// Do nothing.
			}
		});
	}
})(jQuery);
