(function($) {
	$.fn.gallery = function(options) {
		var defaults = {
			imagesDir: "images/",
			thumbsDir: "images/",
			xmlUrl: "images.xml",
			showCaptions: true, 
			showThumbs: true,
			autoPlay: true,
			autoPlaySpeed: 6000,
			transitionSpeed: 400,
			imageWidth:107,
			maskWidth:963,
			scrollImages: 3
		};
		
		var options = $.extend(defaults, options);
		var sliderXPos = 0,
			currentImage = 0,
			galleryXML, selector, pluginDiv, main, details, detailsText, detailsLarger, thumbsActions, thumbsSlider, autoPlayInterval;
		
		this.each(function() { 
			$(this).css({ position:'relative' }).html('');
			pluginDiv = $('<div class="akGallery'+(!options.showCaptions ? " akGalleryNoCaptions" : "")+(!options.showThumbs ? " akGalleryNoThumbs" : "")+'"><div class="akGalleryMain"><div class="akGalleryMainDetails"><div class="akGalleryMainDetailsText"></div><a class="akGalleryMainDetailsLarger" href="#"></a></div></div><div class="akGalleryThumbs"><div class="akGalleryThumbsActions"></div><div class="akGalleryThumbsSliderMask"><div class="akGalleryThumbsSlider"></div></div></div></div>').appendTo(this);
			main = $(pluginDiv).find('.akGalleryMain');
			details = $(pluginDiv).find('.akGalleryMainDetails');
			detailsText = $(pluginDiv).find('.akGalleryMainDetailsText');
			detailsLarger = $(pluginDiv).find('.akGalleryMainDetailsLarger');
			thumbsActions = $(pluginDiv).find('.akGalleryThumbsActions');
			thumbsSlider = $(pluginDiv).find('.akGalleryThumbsSlider');
			
			$.ajax({ type:"GET", url:options.xmlUrl+"?r="+Math.random()*1000, dataType:"xml", success:galleryHandler });
		});
		
		function galleryHandler(xml) {
			galleryXML = $(xml).find("album").find('img');
			
			$('<img src="'+options.imagesDir+galleryXML.eq(0).attr("src")+'" alt="" />').appendTo(main);
			
			detailsText.html('<p>'+galleryXML.eq(0).attr('caption')+'&nbsp;</p>');
			
			var rand = Math.random()*1000;
			for(var i=0; i<galleryXML.length; i++) {
				if(!galleryXML.eq(i).attr('tn')) galleryXML.eq(i).attr('tn',galleryXML.eq(i).attr('src'));
			
				var html = new Array();
				html.push('<a class="akGalleryImageContainer',(i==0 ? ' selected' : ''),'" rel="',rand,'" rev="',i,'" href="',options.imagesDir,'/',galleryXML.eq(i).attr('src'),'" title="',galleryXML.eq(i).attr('caption'),'"','>');
				html.push('<img class="color" src="',options.thumbsDir,galleryXML.eq(i).attr('tn'),'" alt="" />');
				html.push('</a>');
				$(html.join('')).appendTo(thumbsSlider);
			};		
			
			$(pluginDiv).find('.akGalleryImageContainer').css({ cursor:'pointer' }).click(thumbClickHandler).hover(thumbOverHandler,thumbOutHandler).not('.selected').css({ opacity:.5 });
			
			if(options.imageWidth*galleryXML.length > options.maskWidth)
				setupActions();
			
			selector = $('<a class="akGalleryThumbsSelector" href="#"></a>').appendTo(thumbsSlider).css({ left:0, zIndex:99 }).click(function() { return false; });
			
			if(galleryXML.length > 1 && options.autoPlay) autoPlayInterval = setTimeout(gotoNextImage, options.autoPlaySpeed);
			_preloadImages();
		};
		
		function _preloadImages() {
			$(galleryXML).each(function(i) {
				var img = new Image();
				img.src = options.imagesDir+galleryXML.eq(i).attr('src');
			});
		};
		
		function gotoNextImage() {
			if(autoPlayInterval) autoPlayInterval = setTimeout(gotoNextImage, options.autoPlaySpeed);
		
			currentImage++;
			if(currentImage >= galleryXML.length) currentImage = 0;
			$(pluginDiv).find('.akGalleryImageContainer').eq(currentImage).trigger("click",true);
		};
		
		function setupActions() {
		$('<a class="thumbsNext" href="#"></a><a class="thumbsPrev disabled" href="#"></a>').appendTo(thumbsActions);
			$(pluginDiv).find('.thumbsNext').click(nextHandler);
			$(pluginDiv).find('.thumbsPrev').click(prevHandler);
		};
	
		function nextHandler(e) {
			$(thumbsActions).find('.thumbsPrev').removeClass('disabled');
			if(-(galleryXML.length*options.imageWidth-options.maskWidth)<sliderXPos-(options.scrollImages*options.imageWidth)) sliderXPos -= (options.scrollImages*options.imageWidth); else sliderXPos = -(galleryXML.length*options.imageWidth-options.maskWidth);
			$(thumbsSlider).animate({ left:sliderXPos }, 450).each(function() {
				if(-(galleryXML.length*options.imageWidth-options.maskWidth)>=sliderXPos) {
					$(e.target).addClass('disabled');
				};
			});
			return false;
		};
		
		function prevHandler(e) {
			$(thumbsActions).find('.thumbsNext').removeClass('disabled');
			if(sliderXPos+(options.scrollImages*options.imageWidth)<0) sliderXPos += (options.scrollImages*options.imageWidth); else sliderXPos = 0;
			$(thumbsSlider).animate({ left:sliderXPos }, 450).each(function() {
				if(sliderXPos>=0) {
					$(e.target).addClass('disabled');
				};
			}); 
			return false;
		};
		
		function adjustDetails() {
			var h = getDetailsHeight();
			$(details).css({ height:h });
			var dlh = (detailsLarger.height()>0 ? detailsLarger.height() : 11);
			detailsLarger.css({ top:(h-dlh)/2 });
		};
		
		function thumbClickHandler(event,skipClearInterval) {
			if(!skipClearInterval) {
				event.preventDefault();
				clearTimeout(autoPlayInterval);
			};
			
			$(pluginDiv).find('.akGalleryImageContainer').not(this).removeClass('selected').animate({ opacity:.5 },options.imageWidth);
			$(this).addClass('selected').animate({ opacity:1 },options.imageWidth);
			
			selector.animate({ left:parseInt(this.rev)*parseInt($(this).outerWidth(true)) });
			
			currentImage = parseInt(this.rev);
			details.stop().animate({ bottom:-(getDetailsHeight()) }, options.transitionSpeed, function() { 
				detailsText.html('<p>'+galleryXML.eq(currentImage).attr('caption')+'&nbsp;</p>');
				adjustDetails();
				$(this).animate({ bottom:0 });
			});
			
			$(main).find('img').stop().fadeOut(options.transitionSpeed, function() { $(this).remove(); });
			var img = new Image();
			$(img).hide().appendTo(main);;
			img.onload = function() {
				$(img).animate({ top:0 },options.transitionSpeed).fadeIn(options.transitionSpeed);
			};
			img.src = options.imagesDir+galleryXML.eq(currentImage).attr('src');
		};
		
		function getDetailsHeight() {
			return $(details).find('p').height()+parseInt($(details).find('p').css('marginTop'))+parseInt($(details).find('p').css('marginBottom'));
		};
		
		function thumbOverHandler() {
			$(this).not(".selected").stop().animate({ opacity:1 }, options.imageWidth);
		};
		
		function thumbOutHandler() {
			$(this).not(".selected").stop().animate({ opacity:.5 }, options.imageWidth);
		};
	};
})(jQuery);
