(function($) {

	function mD(){
		var arg = arguments;
		var p = arg[0];
		if(arg[1]==undefined) var contents = ""; // ==undefined, damit 0 auch als content gilt (wichtig bei z.b. countern)
		else {
			argArr = $.makeArray(arg);
			argArr.shift();
			var contents = argArr.join("");
		}
		var cssClass = p.cl? ' class="' + p.cl + '"' : ''; //buginfo: naming nicht "class" wg. IE bug
		var id = p.id? ' id="'+p.id+'"' : '';
		var posStr = p.pos? 'position:'+p.pos+';' : '';
		var hiddenStr = p.hid? 'display:none;' : '';
		var style = posStr!="" || hiddenStr!=0? ' style="'+posStr+hiddenStr+'"' : '';
		return '<div'+id+cssClass+style+'>'+contents+'</div>';
	}

	function mI(src,cssClass,alt,id){
		cssClass = cssClass? ' class="'+cssClass+'"' : ''; //buginfo: naming nicht "class" wg. IE bug
		alt = alt? ' alt="'+alt+'"' : '';
		id = id? ' id="'+id+'"' : '';
		return '<img src="'+src+'"'+cssClass+alt+id+' />';
	}	
	
	$.fn.lightBox = function(set) {
		set = jQuery.extend({
			overlayBgColor: '#000000',
			overlayOpacity: 0.8,
			imageBlank:	'trans.gif',
			containerBorderSize: 2,
			containerResizeSpeed: 400,
			slideshowTimeout: false,
			slideshowRunning: false, 
			slideshowTime: 3, //sekunden
			imageArray: [],
			activeImage:0
		},set);
		
		// Caching the jQuery object with all elements matched
		var jQueryMatchedObj = this; // This, in this context, refer to jQuery object

		//--- Initializing the plugin calling the start function
		function _initialize(e) {
			_start(this,jQueryMatchedObj); 
			return false; //prevent <a href> call
		}
		
		function getBigImgSrc(obj){
			var thumbnailSrc = obj.getAttribute('src');
			return thumbnailSrc.replace("thumb_","big_").replace(".png",".jpg");
		}
		
		function getBigImgTitle(obj){
			return obj.getAttribute('alt');
		}
		
		// --- Start the jQuery lightBox plugin
		function _start(objClicked,jQueryMatchedObj) {
			$('embed, object, select').css({'visibility':'hidden'}); 
			_set_interface(); //create the markup structure; style some elements; assign events in some elements
			set.imageArray.length = 0; // Unset total images in imageArray
			set.activeImage = 0; // Unset image active information
			if(jQueryMatchedObj.length==1) { // We have an image set? Or just an image? Let´s see it.
				set.imageArray.push([getBigImgSrc(objClicked),getBigImgTitle(objClicked),objClicked]);
			} else { 
				for(var i=0;i<jQueryMatchedObj.length;i++){
					set.imageArray.push([getBigImgSrc(jQueryMatchedObj[i]),getBigImgTitle(jQueryMatchedObj[i]),jQueryMatchedObj[i]]);
				}
			}
			while(set.imageArray[set.activeImage][2]!=objClicked) set.activeImage++;
			setImageToView(); // Call the function that prepares image exibition
		}

		function _set_interface() {
			//---Apply the HTML markup into body tag
			var newMarkup =
				mD({id:'LB_Overlay'})+
				mD({id:'LB_Popup'},
					mD({id:'LB_PopInner'},
					mD({id:'LB_ImgBox'},
						mD({id:'LB_Loading'},
							mD({cl:'Preload_preloaderLB'},
								mI('img/preloader_lightbox.gif','Preload_imgPreloaderAni'))),
						mD({id:'LB_ImgBoxInner'},
							mD({id:'LB_ImgBoxImgBox'},
								'<img id="LBImg">',
								mD({id:'LB_Bar_Meta'},
									mD({id:'LB_Bar_MetaInner'},
										'<table id="LB_Bar_MetaTable"><tr><td>',
										mD({id:'LB_ImgdetailsCaption'}),
										'</td><td id="LB_ImgdetailsCurrNumber">',
										"</td></tr></table>"))))),
					mD({id:'LB_ControlBox'},
						'<table id="LB_Tab_Controls"><tr><td id="LB_Tab_Controls_CM"></td>',
						'<td id="LB_Tab_Controls_Navi">',
						mD({id:'LB_Area_Navi'},
							mI("img/icon_lb_arrow_prev_lo.png","iActObj","previous","LB_BtnPrev"),						
							mD({id:'LB_PlayNavi'},
								mI('img/icon_lb_play_lo.png','iActObj',"start slideshiw",'LB_BtnPlay'),
								mD({id:'LB_BtnPause',hid:true},
									mI('img/icon_lb_pause_lo.png','iActObj idImgBtnPause',"stop slideshow"))),
							mI("img/icon_lb_arrow_next_lo.png","iActObj","next img","LB_BtnNext")),
						'</td><td id="LB_Tab_Controls_Close">',
						mI('img/icon_lb_close_lo.png','iActObj',"close gallery",'LB_BtnClose'),
						"</td></tr></table>")));

			$('body').append(newMarkup);
			XTN.reinitImgRollovers();
			
			// Style overlay and show it
			$('#LB_Overlay').css({
				backgroundColor:set.overlayBgColor,
				opacity:set.overlayOpacity
			}).fadeIn();
			set.calcMarginTop = getVerticalMargin(); //save
			$('#LB_Popup').top(set.calcMarginTop).show(); // Calculate top and left offset for the LB_Popup div object and show it
			$('#LB_Loading,#LB_BtnClose').bind("click",_finish);
			$('#LB_BtnPlay').bind("click",startSlideShow);
			$('#LB_BtnPause').bind("click",stopSlideShow);
			$(window).bind("resize",handleWinResize);
			$("#LB_ImgBoxImgBox")
			.bind("mouseenter",function(){set.mouseIsOverImg=true;}) //bind (for toggling the bars correct)
			.bind("mouseleave",function(){set.mouseIsOverImg=false;}); //bind (for toggling the bars correct)
		}
		
		function getVerticalMargin(){
			var winHeight = $(window).height();
			//bei <500 höhe viewport gibts nur 5 pixel, sonst zus. 1/10 von winHeight-300
			return winHeight>500? ((winHeight-300)/10)+5 : 5;
		}
		
		function handleWinResize(e){
			//setzte LB_Popup zu neu errechnetem spacing-top:
			set.calcMarginTop = getVerticalMargin(); //save
			$('#LB_Popup').top(set.calcMarginTop);
			
			//resize Image/Container (nur wenn img sichtbar, d.h. geladen)
			var LBImg = $("#LBImg");
			if(LBImg.is(":visible")){
				var origImgDim = LBImg.data("origDimensions");
				var calcImgDim = getCalcImageDimensions(origImgDim.realImgWidth,origImgDim.realImgHeight);
				//--- set dimensions
				//#LB_ImgBoxImgBox wurde auch gesized weil mit margin bei animation bug kam...
				LBImg.add("#LB_ImgBoxImgBox").css({width:calcImgDim.zielImgWidth,height:calcImgDim.zielImgHeight}); //force dimensions (egal ob scaled oder nicht)			
				$("#LB_ImgBox").css({width:calcImgDim.zielBoxWidth,height:calcImgDim.zielBoxHeight});
				$("#LB_ControlBox").css({width:calcImgDim.zielControlboxWidth});
			}
		}
		
	 	// Prepares image exibition; doing a image´s preloader to calculate it´s size
		function setImageToView() { // show the loading
			$("#LB_ImgBoxImgBox").unbind("mouseenter",showImgBars).unbind("mouseleave",hideImgBars);
			$('#LB_Loading').show(); // Show the loading
			$('#LB_ImgBox').bind("click",_finish); //while loading: klick to close
			$('#LBImg,#LB_ControlBox,#LB_ImgdetailsCurrNumber,#LB_Bar_Meta,#LB_Area_Navi').hide(); // Hide some elements
			//---Image preload process
			$("<img />").bind("load",function(){
				var newImgObj = $(this);
				//info: use .attr("width") instead of .width() to read real non-DOM image dimensions
				$('#LBImg').attr('src',set.imageArray[set.activeImage][0]);
				resizeContainerImageBox(newImgObj.attr("width"),newImgObj.attr("height")); // Perfomance an effect in the image container resizing it
				newImgObj.remove();
			}).attr("src",set.imageArray[set.activeImage][0]);
		}
		
		function getCalcImageDimensions(realImgWidth,realImgHeight){
			var MBHeight = 26;
			var controlBarHeight = 50; /* ca., inkl. margin-top zum bild */
			var availViewportHeight = $(window).height() - MBHeight - (set.calcMarginTop*2) - controlBarHeight - (set.containerBorderSize*2); //calcMarginTop*2: gleicher wert benutzt für marginBot
			var availViewportWidth = $(window).width() - (set.containerBorderSize*2);
			var viewportRatio = availViewportWidth/availViewportHeight;
			var imgRatio = realImgWidth/realImgHeight;
			var zielImgWidth = realImgWidth; //default
			var zielImgHeight = realImgHeight; //default
			if(imgRatio>viewportRatio){ //bild würde begrenzt durch max viewport-breite
				if(realImgWidth>availViewportWidth){ //bild zu groß: skalieren
					zielImgWidth = availViewportWidth;
					zielImgHeight = realImgHeight*(zielImgWidth/realImgWidth);
				}
			} else { //bild würde begrenzt durch max viewport-höhe
				if(realImgHeight>availViewportHeight){ //bild zu groß: skalieren
					zielImgHeight = availViewportHeight;
					zielImgWidth = realImgWidth*(zielImgHeight/realImgHeight);
				}
			}
			var zielBoxWidth = zielImgWidth + (set.containerBorderSize*2);
			var zielBoxHeight = zielImgHeight + (set.containerBorderSize*2);
			var zielControlboxWidth = zielImgWidth<300? 300 : zielImgWidth; //controlbar min. 300px
			return {
				zielImgHeight:zielImgHeight,
				zielImgWidth:zielImgWidth,
				zielBoxWidth:zielBoxWidth,
				zielBoxHeight:zielBoxHeight,
				zielControlboxWidth:zielControlboxWidth
			};
		}
		
		// Perfomance an effect in the image container resizing it
		function resizeContainerImageBox(realImgWidth,realImgHeight){
			var calcImgDim = getCalcImageDimensions(realImgWidth,realImgHeight);
			//--- Animate/set dimensions
			$("#LBImg")
			.data("origDimensions",{realImgWidth:realImgWidth,realImgHeight:realImgHeight}) //save (for resize-handler)
			//#LB_ImgBoxImgBox wurde auch gesized weil mit margin bei animation bug kam...
			.add("#LB_ImgBoxImgBox").css({width:calcImgDim.zielImgWidth,height:calcImgDim.zielImgHeight}); //force dimensions (egal ob scaled oder nicht)			
			$("#LB_ImgBox").animate({width:calcImgDim.zielBoxWidth,height:calcImgDim.zielBoxHeight},set.containerResizeSpeed,function(){
				showImage();
			});
			$("#LB_ControlBox").css({width:calcImgDim.zielControlboxWidth});
		}
		
		//--- Show the prepared image
		function showImage() {
			$('#LB_ImgBox').unbind("click",_finish); //end: while loading click to close
			$('#LB_Loading').hide();
			$('#LBImg').fadeIn(function() {
				updateImageMeta();
				updateNavigation();
				$('#LB_ControlBox').fadeIn(300);
			});
			if(set.slideshowRunning) set.slideshowTimeout = window.setTimeout(triggerNextImage,set.slideshowTime*1000);
			_preload_neighbor_images();
		}
		
		//--- Slideshow
		function startSlideShow(){
			$('#LB_BtnPlay').hide(); //wechsel button zu "Pause"
			$('#LB_BtnPause').show();
			set.slideshowRunning = true;
			set.slideshowTimeout = window.setTimeout(triggerNextImage,set.slideshowTime*1000); //initial waiting (on "play" press)
		}
		
		function stopSlideShow(){
			$('#LB_BtnPause').hide(); //wechsel button zu "Play"
			if(set.imageArray.length>1) $("#LB_BtnPlay").show();	
			window.clearTimeout(set.slideshowTimeout); //stop timeout
			set.slideshowRunning = false;
		}
	
		//--- Show the image information
		function updateImageMeta() {
			var i = set.activeImage;
			set.imageArray[i][1] = getBigImgTitle(jQueryMatchedObj[i]);
			$('#LB_ImgdetailsCaption').html(set.imageArray[i][1]);
			if(set.imageArray.length>1){ //If we have a image set: display 'Image X of X' and provide slideshow-btns
				//---image counter:
				$('#LB_ImgdetailsCurrNumber').html('<b>'+(i+1)+'</b> / '+set.imageArray.length).show();
				//---image navi
				$("#LB_Area_Navi").show();
				if(!set.slideshowRunning) $("#LB_BtnPlay").show();	
			}
			//show metabar only on hover: bind here
			$("#LB_ImgBoxImgBox")
			.bind("mouseenter",showImgBars)
			.bind("mouseleave",hideImgBars);
			if(set.mouseIsOverImg) showImgBars(); //trigger (eventhadling geht nicht auomatisch, wenn mouse bei loading über imgBox war)
		}

		function showImgBars(){
			$("#LB_Bar_Meta").tglFadeIn(300);
		}
		
		function hideImgBars(){
			$("#LB_Bar_Meta").tglFadeOut(300);
		}

		//--- Display the button navigations
		function updateNavigation() {
			// Show the next/prev button, if we have an image set
			if(set.imageArray.length) {
				// Show the images button for Next buttons
				$('#LB_BtnPrev').unbind("click").bind('click',function() {
					if(set.slideshowRunning) stopSlideShow();
					triggerPrevImage();
					return false;
				});
				// Show the images button for Next buttons
				$('#LB_BtnNext').unbind("click").bind('click',function() {
					if(set.slideshowRunning) stopSlideShow();
					triggerNextImage();
					return false;
				});
			}
		}
		
		function triggerPrevImage(){
			set.activeImage = set.activeImage==0? set.imageArray.length-1 : set.activeImage-1;
			setImageToView();
		}
		
		function triggerNextImage(){
			set.activeImage = set.activeImage==set.imageArray.length-1? 0 : set.activeImage+1;
			setImageToView();
		}

		//--- Preload prev and next images being showed
		function _preload_neighbor_images() {
			if ( (set.imageArray.length -1) > set.activeImage ) {
				var objNext = new Image();
				objNext.src = set.imageArray[set.activeImage + 1][0];
			}
			if ( set.activeImage > 0 ) {
				var objPrev = new Image();
				objPrev.src = set.imageArray[set.activeImage -1][0];
			}
		}

		//Remove jQuery lightBox plugin HTML markup
		function _finish() {
			stopSlideShow();
			//unbinds
			$(window).unbind("resize",handleWinResize);
			$('#LB_Popup').remove();
			$('#LB_Overlay').fadeOut(300,function(){
				$('#LB_Overlay').remove();
			});
			$('embed, object, select').css({'visibility':'visible'}); // Show some elements to avoid conflict with overlay in IE. These elements appear above the overlay.
		}
		
		function ___pause(ms) {
			var date = new Date(); 
			var curDate = null;
			do { curDate = new Date(); }
			while ( curDate - date < ms);
		}

		// Return the jQuery object for chaining. The unbind method is used to avoid click conflict when the plugin is called more than once
		return this.unbind("click.lightbox").bind("click.lightbox",_initialize); //arbeite mit namespace , dh. bind("click.namespace",xxx), später unbind("click.namespace")
	};
})(jQuery); // Call and execute the function immediately passing the jQuery object