/**
* jQuery LightBox
* @name Adaptative LightBox
* @author Łukasz Staliś
* @version 3.0 beta (not compatibile down)
* @date 14.04.2010
* @category jQuery plugin
* @copyright Mediaambassador.pl
*/

jQuery.fn.extend({
	lightboxMa: function(type,data){
		var $ = jQuery;
		var manager= $().lightboxMa.manager?$().lightboxMa.manager:($().lightboxMa.manager = new Array());
		var idLb = idGenerator($(this).selector);
		if(!manager[idLb]){
			
			type = jQuery.extend({
				//all
				id: idLb,
				selector: $(this).selector,
				mode:'default',
				extendShow:false,
				autoShow:false,		
				close:'.lbCloseBtn',
				//lightbox
				items:'.lightbox',
				fitToScreen:true,
				minWidth:200,
				minHeight:200,
				startWidth: 100,
				startHeight: 100,
				//custom
				content:'<h2>lightboxMa popup v2.0</h2><p>The object which trigger initialization process and his cilck event shows popup window <strong>must have id attribute</strong>.</p><p>Also You can use: $(obj).lightboxMa("show") to show popup window and $(obj).lightboxMa("hide") to hide popup window</p><ul><li><dl><dt>mode: "custom", "default"</dt><dd>Custom option shows user definied content and default shows picture lightbox</dd></dl></li><li><dl><dt>elements: ".lightbox" (default)</dt><dd>CSS path to the elements which need to show in lightbox window.</dd></dl></li><li><dl><dt>autoShow: true, false</dt><dd>True option shows automaticly popup after initialization</dd></dl></li><li><dl><dt>close: "#lbCloseBtn"(default)</dt><dd>Reference to the button which will be used to close popup window</dd></dl></li><li><dl><dt>content: "Your content"</dt><dd>User definied content</dd></dl></li><li><dl><dt>beforeInit(ref,callback), afterInit(ref,callback), beforeShow(ref,callback), afterShow(ref), beforeHide(ref,callback), afterHide(ref)</dt><dd>Functions running on scecified time. "ref" is JQuery object which initialized lightbox. "callback" is a function which must be run on the end of animation/operation with parameter "ref".</dd></dl></li></ul><a class="lbCloseBtn" href="#">zamknij</a>',		
				//all trigers
				afterInit:function(obj,callback){ callback(); },
				beforeShow:function(obj,callback){ callback(); },
				afterShow:function(obj){},
				beforeHide:function(obj,callback){ callback(); },
				afterHide:function(obj){},
				beforeDestruct:function(obj,callback){ callback(); },
				afterDestruct:function(obj){}			
			},type);
			
			if(type.mode=="default"){
				manager[idLb]= new lightboxMaClass(type);
			} else {
				manager[idLb]= new popUpClass(type);
			};
			
		} else {
			var obj = manager[idLb];
			switch(type){
				case 'goto':obj.goto(data);break;
				case 'next':obj.next(data);break;
				case 'prev':obj.prev(data);break;
				case 'show':obj.show(data);break;
				case 'hide':obj.hide(data);break;
				case 'destruct':obj.destruct(data);break;
				case 'resize':obj.resize();break;
			}
			
			
			return $("#"+idLb);
			
		};
		
		/** podstawowa klasa dostarczająca mechanizmy lighboxowe w któych mogą być wyświetlane dowolne elementy**/
		function popUpClass(sets){
			//variable parent definied to use in JQuery and callback this function class properties and method
			var parent = this;
			
			this.id = sets.id;
			this.selector = sets.selector;
			this.type = sets.mode;
			this.autoShow =	sets.autoShow;		
			this.close = sets.close;
			this.content =sets.content;
			//protected vars
			this.lock = false;
			//methods
			this.show = function(data){
				function showCallback(){
					$('#'+parent.id).css('visibility','visible');
					parent.afterShow(parent);
				};
				$('#'+parent.id).removeClass("hidden");
				this.resize();
				this.beforeShow(this,showCallback);
			}
			this.hide = function(data){
				function showCallback(){
					$('#'+parent.id).addClass("hidden");
					$('#'+parent.id).css('visibility','hidden');
					parent.afterHide(parent);
					$('#'+parent.id+' .lbBg, #'+parent.id+' .lbBgMoving').height(0).width(0);
				};
				this.beforeHide(this,showCallback);
			}
			this.resize = function(){
							
				var width=$('#'+this.id+' .lbMoving').outerWidth(true);
				var height=$('#'+this.id+' .lbMoving').outerHeight(true);
				
				var widthD=$(document).width();
				
				if($.browser.msie && $.browser.version<7)widthD=$(window).width();
				
				var heightD=$(document).height();
				
				if($('#'+parent.id).hasClass("hidden"))$('#'+parent.id+' .lbBg, #'+parent.id+' .lbBgMoving').height(0).width(0); else $('#'+this.id+' .lbBg, #'+this.id+' .lbBgMoving').css({'height':height>heightD?height:heightD, 'width':width>widthD?width:widthD});

				var left=($(window).width()-width)/2+$(document).scrollLeft();
				var top=($(window).height()-height)/2+$(document).scrollTop();
				if(left<0)left=0;
				if(top<0)top=0;
				
				if((left+width)>$(document).width())left=$(document).width()-width;
				if((top+height)>$(document).height())top=$(document).height()-height;
				
				
				$('#'+this.id+' .lbMoving').css({'left':left,'top':top});
				
			}
			this.destruct = function(){
				$(window).unbind("resize",this.resizeHandler);
				$('#'+this.id+' '+this.close).unbind("click",this.hideHandler);
				if($(this.selector).length!=0)$(this.selector).unbind("click",this.showHandler);
				
				$('#'+this.id).remove();
				$().lightboxMa.manager[this.id] = null;				
			}
			//events Method
			this.afterInit = sets.afterInit;
			this.beforeShow = sets.beforeShow;
			this.afterShow = sets.afterShow;
			this.beforeHide = sets.beforeHide;
			this.afterHide = sets.afterHide;
			this.beforeDestruct = sets.beforeDestruct;
			this.afterDestruct = sets.afterDestruct;
			//event Handlers
			this.hideHandler = function(){
					parent.hide();					
					return false;
			}
			this.showHandler = function(){
					parent.show();					
					return false;
			}
			this.resizeHandler = function(){
					parent.resize();					
					return false;
			} 
			
			this.construct = function(sets){
				$('<div id="'+this.id+'" class="lbMa hidden"><div class="lbBg">&nbsp;</div><div class="lbBgMoving"><div class="lbMoving"><div class="lbMovingTop"><div class="left"><div class="right"><div class="center">&nbsp;</div></div></div></div><div class="lbMovingContent"><div class="left"><div class="right"><div class="lbContent">'+this.content+'</div></div></div></div><div class="lbMovingBottom"><div class="left"><div class="right"><div class="center">&nbsp;</div></div></div></div></div></div></div>').appendTo('body').css('visibility','hidden');
				
				$(window).bind("resize",this.resizeHandler);
				$('#'+this.id+' '+this.close).bind("click",this.hideHandler);
				
				function initCallback(){
					parent.resize();
					if(parent.autoShow)parent.show();
					if($(parent.selector).length!=0)$(parent.selector).bind("click", parent.showHandler);
				}
				
				$('#'+parent.id+' .lbBg, #'+parent.id+' .lbBgMoving').height(0).width(0);
				this.afterInit(this,initCallback);
			}
			this.construct(sets);
		}
		/** lightbox zdjęciowy dziedziczącuy podstawowe funkcjonalności z normalnego lightboxa**/ 
		function lightboxMaClass(sets){
			//variable parent definied to use in JQuery and callback this function class properties and method
			var parent = this;
			//dziedziczenie z klasy popUpClass
			this.inheritForm = popUpClass;
			this.items= sets.items;
			this.extendShow = sets.extendShow;
			this.fitToScreen = sets.fitToScreen;
			this.minWidth = sets.minWidth;
			this.minHeight = sets.minHeight;
			this.startWidth = sets.startWidth;
			this.startHeight = sets.startHeight;
			//protected vars
			this.pictures = new Array();
			this.current = 0;
			// methods
			this.goto = function(data){
				this.lock=true;
				
				$('#'+this.id+' .lbDefaultContent .lbPrevBtn').hide();
				$('#'+this.id+' .lbDefaultContent .lbNextBtn').hide();
				$('#'+this.id+' .lbDefaultContent .lbCloseBtn').hide();
				$('#'+this.id+' .lbDefault').empty();
				$('#'+this.id+' .lbDefaultTitle').remove();
				if($("#"+this.id).css("visibility") != "visible")$('#'+this.id+' .lbDefaultContent').css({width:this.startWidth,height:this.startHeight});
				var img= new Image();
				img.onload=function(){
					var lbW=$('#'+parent.id+' .lbDefaultContent').outerWidth(true);
					var lbH=$('#'+parent.id+' .lbDefaultContent').outerHeight(true);
					var t=$('#'+parent.id+' .lbMoving').css('top');
					var l=$('#'+parent.id+' .lbMoving').css('left');
					var wOffset=$('#'+parent.id+' .lbMoving').outerWidth(true)-lbW;
					var hOffset=$('#'+parent.id+' .lbMoving').outerHeight(true)-lbH;
					var trueW=wOffset+img.width;
					var trueH=hOffset+img.height;
					
					if(!parent.fitToScreen){
						//zabezpieczenie na wypadek końca strony
						var widthD=$(document).width();
						if($.browser.msie && $.browser.version<7)widthD=$(window).width();
						var heightD=$(document).height();
						
						var toTop=parseInt(t)-(img.height-lbH)/2;
						var toLeft=parseInt(l)-(img.width-lbW)/2;
						
						if((toTop+trueH)>heightD)toTop=heightD-trueH;
						if((toLeft+trueW)>widthD)toLeft=widthD-trueW;
						
						if(toTop<0)toTop=0;
						if(toLeft<0)toLeft=0;
						
						$('#'+parent.id+' .lbDefaultContent').removeClass('loading');
						
						$('#'+parent.id+' .lbMoving').animate({top:toTop,left:toLeft},600);
						$('#'+parent.id+' .lbDefaultContent').animate({width:img.width,height:img.height},600,function(){
							
							$('#'+parent.id+' .lbDefault img').css({width:img.width,height:img.height}).show();
							
							if(parent.pictures[data].minTitle!='')$('<div class="lbDefaultTitle"><p>'+parent.pictures[data].minTitle+'</p></div>').appendTo('#'+parent.id+' .lbDefault').css({top:img.height});
							
							if(trueW>widthD||trueH>heightD)parent.resize();						
							if(data!=0)$('#'+parent.id+' .lbDefaultContent .lbPrevBtn').show();
							if(data<(parent.pictures.length-1))$('#'+parent.id+' .lbDefaultContent .lbNextBtn').show();
							$('#'+parent.id+' .lbDefaultContent .lbCloseBtn').show();
							parent.lock=false;
						});
						
					} else {
							var wWindow=$(window).width();
							var hWindow=$(window).height();
							var itemW=wWindow>trueW?img.width:(wWindow-wOffset);
							var itemH=hWindow>trueH?img.height:(hWindow-hOffset);
							if(itemW<parent.minWidth)itemW=parent.minWidth;
							if(itemH<parent.minHeight)itemH=parent.minHeight;
							
							if((itemW/img.width)*img.height>itemH){
								itemW=(itemH/img.height)*img.width;
							} else {
								itemH=(itemW/img.width)*img.height;
							};
							
							itemW= parseInt(itemW);
							itemH= parseInt(itemH);
							
							$('#'+parent.id+' .lbDefaultContent').removeClass('loading');
							$('#'+parent.id+' .lbMoving').animate({top:parseInt(t)-(itemH-lbH)/2,left:parseInt(l)-(itemW-lbW)/2},600);
							
							$('#'+parent.id+' .lbDefaultContent').animate({width:itemW,height:itemH},600,function(){
								
								if(parent.pictures[data].minTitle!='')$('<div class="lbDefaultTitle">'+parent.pictures[data].minTitle+'</div>').appendTo('#'+parent.id+' .lbDefault').css({bottom:-1*$('#'+parent.id+' .lbDefaultTitle').outerHeight(true)});
								
								$('#'+parent.id+' .lbDefault img').css({width:itemW,height:itemH}).show();
								if(data!=0)$('#'+parent.id+' .lbDefaultContent .lbPrevBtn').show();
								if(data<(parent.pictures.length-1))$('#'+parent.id+' .lbDefaultContent .lbNextBtn').show();
								$('#'+parent.id+' .lbDefaultContent .lbCloseBtn').show();
								parent.lock=false;
							});
							
					};
				};
				$('#'+this.id+' .lbDefaultContent').addClass('loading');
				this.resize();
				img.src=this.pictures[data].max;
				$('<img src="'+this.pictures[data].max+'">').appendTo('#'+this.id+' .lbDefault').hide(0);
				this.current=data;
				if($("#"+this.id).css("visibility") != "visible")this.show();
			}
			this.next = function(data){
				if(this.lock)return;
				if(this.current<(this.pictures.length-1))this.goto(parseInt(this.current)+1);
			}
			this.prev = function(data){
				if(this.lock)return;
				if(this.current>0)this.goto(this.current-1);
			}
			//event Handlers
			this.nextHandler = function(){
					parent.next();					
					return false;
			}
			this.prevHandler = function(){
					parent.prev();					
					return false;
			}
			this.gotoHandler = function(event){
					parent.goto(event.data.pos);					
					return false;
			} 
			this.setHandler = function(event){
					parent.current = event.data.pos;					
					return false;
			} 
			this.titleHideHandler  = function(){
				if($('#'+parent.id+' .lbDefaultTitle').text()!='')$('#'+parent.id+' .lbDefaultTitle').stop().animate({bottom: -1*$('#'+parent.id+' .lbDefaultTitle').outerHeight(true)},400);
			}
			this.titleShowHandler  = function(){
				$('#'+parent.id+' .lbDefaultTitle').stop().animate({bottom: -1},400);
			}
			
			this.construct = function(sets){
				
				var afterInit = sets.afterInit;
				sets.afterInit=function(obj,callback){};//zablokowanie zdarzenia końca inicjalizacji
				
							
				//dziedziczenie + włączenie zdarzenia afterInit();
				this.inheritForm(sets);
				this.afterInit = afterInit;
				this.destruct = function(){
					$(window).unbind("resize",this.resizeHandler);
					$('#'+this.id+' '+this.close).unbind("click",this.hideHandler);
					$('#'+this.id+' .lbBgMoving').unbind("click",this.hideHandler);
					$('#'+this.id+' .lbDefaultContent').bind("mouseover",this.titleShowHandler).bind("mouseout",this.titleHideHandler);
					$('#'+this.id+' .lbDefaultContent .lbPrevBtn').unbind("click",this.prevHandler);
					$('#'+this.id+' .lbDefaultContent .lbNextBtn').unbind("click",this.nextHandler);
					if(this.extendShow){
						$(this.items).each(function(i){
							$(this).unbind("click", parent.setHandler);
						});
						if($(this.selector).length!=0)$(this.selector).unbind("click",this.gotoHandler);
					} else {
						$(this.selector).each(function(i){
							$(this).unbind("click", parent.gotoHandler);
						});
					};
					
					$('#'+this.id).remove();
					$().lightboxMa.manager[this.id] = null;
				}
				$("#"+this.id+" .lbContent").replaceWith('<div class="lbDefaultContent"><a href="#" class="lbPrevBtn">poprzednie</a><a href="#" class="lbNextBtn">następne</a><div class="lbDefault"><div class="lbDefaultTitle"></div></div><a href="#" class="lbCloseBtn">zamknij</a></div>');
				if(this.extendShow){
					$(this.items).each(function(i){
						parent.pictures.push({max:$(this).attr("href"),maxTitle:$(this).attr("title"),min:$(this).children('img').attr("src"),minTitle:$(this).children('img').attr("alt")});
						$(this).bind("click",{pos: i}, parent.setHandler);
					});				
				} else {
					$(this.selector).each(function(i){
						parent.pictures.push({max:$(this).attr("href"),maxTitle:$(this).attr("title"),min:$(this).children('img').attr("src"),minTitle:$(this).children('img').attr("alt")});
						$(this).bind("click",{pos: i}, parent.gotoHandler);
					});				
				};
				$('#'+this.id+' .lbDefaultContent .lbPrevBtn').bind("click",this.prevHandler);
				$('#'+this.id+' .lbDefaultContent .lbNextBtn').bind("click",this.nextHandler);
				
				$('#'+this.id+' .lbDefaultContent').bind("mouseover",this.titleShowHandler).bind("mouseout",this.titleHideHandler);
				$('#'+this.id+' '+this.close).bind("click",this.hideHandler);
				$('#'+this.id+' .lbBgMoving').bind("click",this.hideHandler);
				
				
				
				function initCallback(){
					parent.resize();
					if(parent.autoShow)parent.goto(parent.current);
					if($(parent.selector).length!=0 && parent.extendShow)$(parent.selector).bind("click",{pos: parent.current},parent.gotoHandler);
				}
				this.afterInit(this,initCallback);
			}
			this.construct(sets);
		}
		
		/** funkcja generująca za nas id obiektu **/
		function idGenerator(str){
			var exp= new RegExp("[^a-zA-Z0-9]+","g");
			var tpl=str.replace(exp,'');
			return "lbMa_"+tpl;
		}		
	}
});
