(function($) {
	
	$.zoomShowcase = function(data) {
		
		var list = [],
		images = [],
		links = [],
		infos = [],
		
		easing = data.easing,
		target = data.linkTarget,
		imgWidth = data.imageWidth,
		imgHeight = data.imageHeight,
		totalWidth = data.bannerWidth,
		sideOpacity = data.sideOpacity,		
		randomize = data.randomizeItems,
		speed = data.animationSpeed,
		delay = data.autoPlayDelay,
		quarters = data.backZoom,
		halves = data.sideZoom,
		auto = data.autoPlay,
		
		halfW = (imgWidth * halves) | 0,
		halfH = (imgHeight * halves) | 0,
		quarterW = (imgWidth * quarters) | 0,
		quarterH = (imgHeight * quarters) | 0,
		halfWidth = (totalWidth * 0.5) | 0,
		halfHeight = (imgHeight * 0.5) | 0,
				
		items = $("#zoom-gallery > ul > li"),
		leg = items.length,
		readyToFire = false,
		isHovering = false,
		isRunning = false,
		grabOnce = true,
		iLeg = leg - 1,
		counter = 0,
		isOn = 0,
				
		toLeft,
		toBack,
		toRight,
		toCenter,
		preloader,
		conList,
		tCount,
		direct,
		infoOn,
		store,
		extraW,
		extraH,
		timer,
		zoomer,
				
		rightX = totalWidth - halfW,
		centerX = halfWidth - ((imgWidth * 0.5) | 0),
		backX = halfWidth - ((quarterW * 0.5) | 0),
				
		sideY = halfHeight - ((halfH * 0.5) | 0),
		backY = halfHeight - ((quarterH * 0.5) | 0);
		
		init(data.bannerWidth);
		
		data = null;
		halves = null;
		quarters = null;
		
		function init(totalWidth) {
				
			if(leg > 3) {
				
				var img, txt, titles, ar, pos, aligns, positions, styles, k = leg, tempList = [], tempImages = [], tempInfos = [], tempLinks = [];
					
				zoomer = $("#zoom-gallery");
				preloader = zoomer.find(".preloader");
						
				if(preloader.length) {
							
					preloader.css({
								
						left: halfWidth - ((parseInt(preloader.attr("width"), 10) * 0.5) | 0), 
						top: halfHeight - ((parseInt(preloader.attr("height"), 10) * 0.5) | 0),
						display: "block"
								
					});
							
				}
				
				zoomer.css("height", imgHeight + 20);
				zoomer.find("ul").css("display", "block");
					
				items.each(function(i) {
							
					tempList[i] = $(this).css({position: "absolute", backgroundColor: "#000"}).hide();
					img = $("<img />").css({position: "absolute", top: 0, left: 0}).load(imgLoaded).appendTo($(this));
							
					tempImages[i] = img;
					$(this).data("image", img);
					
					ul = $(this).find("ul");
					
					if(ul.length) {
						
						ul.attr("title") ? tempLinks[i] = ul.attr("title") : tempLinks[i] = 0;
						
						if(ul.attr("class")) {
						
							aligns = ul.attr("class").toLowerCase();
							(aligns.search("-") !== -1) ? aligns = aligns.split("-")[1] : aligns = "left";
							
						}
						else {
						
							aligns = "left";
							
						}
						
					}
					else {
					
						tempLinks[i] = 0;
						aligns = "left";
						
					}
					
					txt = $(this).find("li");
					
					if(txt.length) {
								
						titles = [];
						positions = [];
						styles = [];
								
						txt.each(function(j) {
									
							if(txt.html() != "") {
								
								if($(this).attr("class")) {
									
									pos = $(this).attr("class").toLowerCase();
									
									if(pos.search("x") !== -1) {
										
										ar = $(this).attr("class").split("x");
										
										titles[j] = $(this).html();
										positions[j] = {x: parseInt(ar[0], 10), y: parseInt(ar[1], 10)};
										styles[j] = {color: $(this).css("color"), backgroundColor: $(this).css("background-color")};
										
									}
									else {
										
										titles[j] = 0;
										positions[j] = 0;
										styles[j] = 0;
										
									}
									
								}
								else {
								
									titles[j] = 0;
									positions[j] = 0;
									styles[j] = 0;
									
								}
										
							}
							else {
									
								titles[j] = 0;
								positions[j] = 0;
								styles[j] = 0;
										
							}
										
						});
						
								
						tempInfos[i] = {content: titles, position: positions, style: styles, align: aligns};
								
					}
					else {
								
						tempInfos[i] = 0;
								
					}
					
					ul.empty();
	
				});
				
				if(!randomize) {
					
					list = tempList;
					images = tempImages;
					links = tempLinks;
					infos = tempInfos;
								
				}
							
				else {
					
					var shuf = [], shuf2 = [], shuf3 = [], shuf4 = [], placer, iOn;
							   
					for(var i = 0; i < leg; i++) {
						
						shuf[i] = tempList[i];
						shuf2[i] = tempImages[i];
						shuf3[i] = tempLinks[i];
						shuf4[i] = tempInfos[i];
						
					}
									
					while(shuf.length > 0) { 
									
						placer = (Math.random() * shuf.length) | 0;
						iOn = list.length;
						
						list[iOn] = shuf[placer];
						images[iOn] = shuf2[placer];
						links[iOn] = shuf3[placer];
						infos[iOn] = shuf4[placer];
						
						shuf.splice(placer, 1);
						shuf2.splice(placer, 1);
						shuf3.splice(placer, 1);
						shuf4.splice(placer, 1);
									
					}
					
				}
				
				while(k--) {
					
					switch(k) {
								
						case 0: 
									
							list[k].css({left: centerX, top: 0, width: imgWidth, height: imgHeight, zIndex: 3});
							images[k].attr("width", imgWidth).attr("height", imgHeight);
									
						break;
								
						case 1:
									
							list[k].css({left: rightX, top: sideY, width: halfW, height: halfH, zIndex: 1});
							images[k].css("opacity", sideOpacity).attr("width", halfW).attr("height", halfH);
								
						break;
								
						case iLeg:
									
							list[k].css({left: 0, top: sideY, width: halfW, height: halfH, zIndex: 2});
							images[k].css("opacity", sideOpacity).attr("width", halfW).attr("height", halfH);
								
						break;
								
						default:
									
							list[k].css({left: backX, top: backY, width: quarterW, height: quarterH, xIndex: 0});
							images[k].attr("width", quarterW).attr("height", quarterH);
									
					}
					
					images[k].attr("src", list[k].attr("title"));
					list[k].removeAttr("title");
					
				}
				
			}
			else {
					
				alert("ZoomShowcase requires at least 4 images to work correctly");
						
			}

		}
				
		function imgLoaded(event) {
				
			event.stopPropagation();
					
			if(counter < iLeg) {
						
				counter++;
						
			}
			else {
				
				if(preloader) preloader.remove();
						
				list[0].fadeTo(500, 1, fadeSides);
						
				counter = null;
				preloader = null;
						
			}
					
		}
				
		function fadeSides() {
			
			toRight = 1;
			toLeft = iLeg;
					
			list[toRight].fadeTo(500, 1);
			list[toLeft].fadeTo(500, 1, addClicks);
					
		}
				
		function addClicks() {
				
			list[1].css("cursor", "pointer").mouseenter(over).mouseleave(out);
			list[iLeg].css("cursor", "pointer").mouseenter(over).mouseleave(out);
					
			var i = leg;		
			while(i--) list[i].show();

			if(auto) $("#zoom-gallery").mouseenter(enterMouse).mouseleave(exitMouse);

			addEvents();
			leg = null;
					
		}
		
		function enterMouse(event) {
			
			isHovering = true;
			if(timer) clearTimeout(timer);
			
		}
		
		function exitMouse(event) {
			
			isHovering = false;
			if(readyToFire) timer = setTimeout(clickRight, delay);
			
		}
				
		function over(event) {
					
			$(this).data("image").fadeTo(250, 1);
					
		}
				
		function out(event) {
					
			$(this).data("image").stop(true, true).fadeTo(250, sideOpacity);
					
		}
		
		$.zoomShowcase.goLeft = function() {
		
			clickLeft();
			
		}
		
		$.zoomShowcase.goRight = function() {
		
			clickRight();
			
		}
		
		$.zoomShowcase.isReady = function() {
		
			return isRunning;
			
		}
				
		function clickLeft(event) {
				
			if(timer) clearTimeout(timer);
			readyToFire = false;
				
			toCenter = (isOn > 0) ? isOn - 1 : iLeg,
			toLeft = (toCenter > 0) ? toCenter - 1 : iLeg;
			toBack = (isOn < iLeg) ? isOn + 1 : 0,
			toRight = isOn;
					
			list[toCenter].unbind("click", clickLeft);
			list[toBack].unbind("click", clickRight);
					
			list[toLeft].css("z-index", 1);
			list[toRight].css("z-index", 2);
					
			animate();
					
		}
				
		function clickRight(event) {

			if(timer) clearTimeout(timer);
			readyToFire = false;
			
			toCenter = (isOn < iLeg) ? isOn + 1 : 0,
			toLeft = isOn,
			toBack = (isOn > 0) ? isOn - 1 : iLeg,
			toRight = (toCenter < iLeg) ? toCenter + 1 : 0;
					
			list[toCenter].unbind("click", clickRight);
			list[toBack].unbind("click", clickLeft);
					
			list[toLeft].css("z-index", 2);
			list[toRight].css("z-index", 1);
					
			animate();
					
		}
				
		function animate() {
			
			list[isOn].css("cursor", "auto").unbind("click", gotoURL);
			
			isOn = toCenter;
			isRunning = true;		
			
			if(store != null) {
				
				while(store.length) {
					
					store[0].stop();
					store[0].data("child").stop();
					store[0].removeData("child");
					store[0].empty();
					store[0].remove();
					store.shift();
					
				}
					
				store = null;
				conList = null;
				
			}
					
			list[toBack].unbind("mouseenter", over).unbind("mouseleave", out).css({zIndex: 0, cursor: "auto"}).animate({left: backX, top: backY, width: quarterW, height: quarterH}, speed, easing);
			images[toBack].animate({width: quarterW, height: quarterH}, speed, easing);
					
			list[toLeft].css("cursor", "pointer").mouseenter(over).mouseleave(out).animate({left: 0, top: sideY, width: halfW, height: halfH}, speed, easing);
			images[toLeft].animate({width: halfW, height: halfH, opacity: sideOpacity}, speed, easing);
					
			list[toRight].css("cursor", "pointer").mouseenter(over).mouseleave(out).animate({left: rightX, top: sideY, width: halfW, height: halfH}, speed, easing);
			images[toRight].animate({width: halfW, height: halfH, opacity: sideOpacity}, speed, easing);
			
			list[toCenter].unbind("mouseenter", over).unbind("mouseleave", out).css({zIndex: 3, cursor: "auto"}).animate({left: centerX, top: 0, width: imgWidth, height: imgHeight}, speed, easing);
			images[toCenter].stop(true, true).animate({width: imgWidth, height: imgHeight, opacity: 1}, speed, easing, addEvents);
					
		}
				
		function addEvents() {
				
			list[toRight].click(clickRight);
			list[toLeft].click(clickLeft);	
			
			if(links[isOn] !== 0) list[isOn].css("cursor", "pointer").click(gotoURL);
			isRunning = false;
			
			if(infos[isOn] !== 0) {	
				
				conList = infos[isOn];
				tCount = conList.content.length - 1;
				direct = conList.align;
				store = [];
				infoOn = 0;
				showContent();
				
			}
			else {
				showDone();
			}	
					
		}
		
		function gotoURL() {
			
			(target = "_parent") ? window.location = links[isOn] : window.open(links[isOn]);
				
		}
		
		function showDone() {
		
			if(auto && !isRunning && !isHovering) {
				
				timer = setTimeout(clickRight, delay);
					
			}
			
			readyToFire = true;
			
		}
				
		function showContent() {
			
			if(isRunning) return;
			
			var cont = conList.content[infoOn];
					
			if(cont === 0) {
						
				if(infoOn < tCount) {
					infoOn++;
					showContent();
				}
				else {
					showDone();
				}
						
				return;
						
			}
			
			var info = $("<div />").addClass("zoom-gallery-info-text").appendTo(zoomer),
			inside = $("<span />").html(cont).appendTo(info),
			iWide,
			func, 
			obj, 
			w2,
			w, 
			h;
						
			if(grabOnce) {
							
				extraW = parseInt(info.css("padding-left"), 10) + parseInt(info.css("padding-right"), 10);
				extraH = parseInt(info.css("padding-top"), 10) + parseInt(info.css("padding-bottom"), 10);
				grabOnce = false;
							
			}
						
			h = info.height();
			w = w2 = info.width();
			
			inside.css({width: w - extraW, height: h});
						
			info.css(conList.style[infoOn]).css({
							 
				left: (direct === "left") ? centerX + conList.position[infoOn].x : centerX + imgWidth - conList.position[infoOn].x - extraW, 
				top: conList.position[infoOn].y,
				opacity: 1,
				width: 0,
				height: h
							
			}).data("child", inside).find("a").each(function() {
							
				$(this).css(conList.style[infoOn]);
							
			});
						
			store[infoOn] = info;
					
			if(infoOn < tCount) {
				infoOn++;
				func = showContent;
			}
			else {
				func = showDone;
			}
					
			if(direct === "left") {
				
				info.animate(
				
					{width: w},
					250,
					func
				
				);
						
			}
			else {
				
				inside.css({position: "relative", left: -w2}).animate({left: 0}, 250);
				
				info.animate(
				
					{left: centerX + imgWidth - conList.position[infoOn].x - w - extraW, width: w},
					250,
					func
				
				);

			}
						
		}
		
	}
	
})(jQuery);










