﻿/** 
/** zoommerMa to funkcja pozwalająca na powiększanie zdjęć w zadany sposób
/** @version 1.0
/** @autor Łukasz Staliś
/** @date 16-11-2009
/** @company MediaAmbassador
/** @rights All rights reserved
/**	
/** need template like this:
/**			
			<a class="jqzoom clearfix" href="to big image" > //must have no style 
				<img style="float: left;" src="to normal image">
			</a>
**/


jQuery.fn.extend({
	zoommerMa: function(type,data){
		var $ = jQuery;
		var manager= $().zoommerMa.manager?$().zoommerMa.manager:($().zoommerMa.manager = new Array());
		var name = "zoommerMa";
		if(!manager[name]){
			
			type = jQuery.extend({
				//all
				id: name,
				selector: $(this).selector,
				style: "default", //default, urban, loop
				width:400, 
				height:400,
				offsetTop:0,
				offsetLeft:0,
				loadingTxt:'Trwa ładowanie...',
				appendDOM: 'body',
				//all trigers
				afterInit:function(callback){ callback(); },
				beforeShow:function(callback){ callback(); },
				afterShow:function(){},
				beforeHide:function(callback){ callback(); },
				afterHide:function(){},
				beforeDestruct:function(callback){ callback(); },
				afterDestruct:function(){}			
			},type);
			
			if(type.style=="urban")manager[name]= new zoommerUrbanClass(type);
			else if(type.style=="loop")manager[name]= new zoommerLoopClass(type);
			else manager[name]= new zoommerClass(type);
			
		} else {
			var obj = manager[name];
			switch(type){
				case 'show':obj.showHandler();break;
				case 'hide':obj.hideHandler();break;
				case 'reload':obj.reload(data);break;
				case 'disable':obj.disable(data);break;
				case 'enable':obj.enable(data);break;
				case 'destruct':obj.destruct(data);break;
			};
			
			return $("#"+name);
			
		};
		function zoommerClass(sets){
			var parent = this;
			this.id = sets.id;
			this.selector = sets.selector;
			this.loadingTxt = sets.loadingTxt;
			this.appendDOM = sets.appendDOM;
			this.width = sets.width;
			this.height = sets.height;
			this.offsetTop = sets.offsetTop;
			this.offsetLeft = sets.offsetLeft;
			//protected vars
			this.linkRef = $(this.selector);
			this.imgRef = this.linkRef.children("img");
			this.zoomRef = null;
			this.zoomImgRef = null;
			this.zoomBoxRef = null;
			this.boxW = 0;
			this.boxH = 0;
			this.infoRef = null;
			this.active = false;
			this.href = '';
			this.src = '';
			this.scale = 1;
			this.iterator = 1;
			this.imgWidth = 0;
			this.imgHeight = 0;
			this.zoomWidth = 0;
			this.zoomHeight = 0;
			this.boxShown = false;
			this.lock =false;
			this.lastX =-1;
			this.lastY =-1;
			this.interval = null;
			//methods
			this.show = function(data){
				this.beforeShow(function(){
					parent.startMove();
					parent.linkRef.addClass('zooming');
					parent.zoomRef.stop().show(0).animate({opacity:1},300,function(){
						parent.infoRef.hide(0);
					});					
					parent.afterShow();
				});
			};
			this.hide = function(data){
				this.beforeHide(function(){
					parent.stopMove();
					parent.linkRef.removeClass('zooming');
					parent.zoomBoxRef.hide();
					parent.zoomRef.stop().animate({opacity:0},350,function(){
						parent.zoomRef.hide(0);
						parent.infoRef.hide(0);
					});			
					parent.afterHide();
				});
			};
			this.move = function(){
				if(parent.lock)return;
				parent.lock =true;
								
				var fromX = parent.lastX-parent.boxW*0.5;
				var fromY = parent.lastY-parent.boxH*0.5;
				
				fromX=fromX<0?0:fromX;
				fromY=fromY<0?0:fromY;
				fromX=(fromX+parent.boxW)>parent.imgWidth?parent.imgWidth-parent.boxW:fromX;
				fromY=(fromY+parent.boxH)>parent.imgHeight?parent.imgHeight-parent.boxH:fromY;
				
				parent.zoomBoxRef.css({top: parseInt(fromY) , left: parseInt(fromX) });
				if(!parent.boxShown&&parent.lastX!=-1)parent.zoomBoxRef.show();
				
				//var fromTop = -fromY/parent.scale;
				//var fromLeft = -fromX/parent.scale;
				
				var fromTop=-parent.lastY/parent.scale+0.5*parent.height;
				var fromLeft=-parent.lastX/parent.scale+0.5*parent.width;
				
				if(fromTop>0)fromTop=0; else if(fromTop<(parent.height-parent.zoomHeight))fromTop = (parent.height-parent.zoomHeight); 
				if(fromLeft>0)fromLeft=0; else if(fromLeft<(parent.width-parent.zoomWidth))fromLeft = (parent.width-parent.zoomWidth); 
				
				parent.zoomImgRef.css({top:parseInt(fromTop),left:parseInt(fromLeft)});
				
				parent.lock =false;
			};
			this.destruct = function(){
				this.beforeDestruct(function(){
					parent.linkRef.unbind('mousemove',parent.moveHandler);
					$(window).unbind('resize',parent.reflesh);
					$(parent.zoomRef).remove();
					$(parent.infoRef).remove();
					$().zoommerMa.manager[this.id] = null;	
					parent.afterDestruct();					
				});					
			};
			//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.moveHandler = function(e){
				var off=parent.linkRef.offset();
				parent.lastX = e.pageX-off.left;
				parent.lastY = e.pageY-off.top;
				
				return false;
			};
			this.showHandler = function(){
				if(parent.active==true)return;
				parent.active=true;
				if(parent.src!=parent.imgRef.attr('src')){
					var img= new Image();
					img.onload=function(){
						parent.imgWidth=this.width;
						parent.imgHeight=this.height;
						parent.src = this.src;
						if(parent.href!=parent.linkRef.attr('href'))parent.reload(); else parent.show();
					};
					img.src= parent.imgRef.attr('src');
					
				} else if(parent.href!=parent.linkRef.attr('href')){
					parent.reload();
				} else {
					parent.show();
				};
				return false;
			};
			this.reload = function(){
				var img=new Image();
				img.onload=function(){
					parent.href=this.src;
					parent.scale=parent.imgWidth/this.width;
					parent.iterator = (1-parent.scale)/parent.scale;
					parent.zoomHeight=this.height;
					parent.zoomWidth=this.width;
					parent.boxW = parseInt(parent.width*parent.scale);
					parent.boxH = parseInt(parent.height*parent.scale);
					parent.zoomImgRef.attr('src',parent.href);
					parent.zoomBoxRef.css({width: parent.boxW-1, height: parent.boxH-1});
					
					if(parent.active==true)parent.show(); else parent.infoRef.hide(0);		
				};
				parent.infoRef.show(0);
				img.src=parent.linkRef.attr('href');
			};
			this.hideHandler = function(){
				if(parent.active==false)return;
				parent.active=false;
				parent.hide();				
				return false;
			};
			this.startMove = function(){
				parent.linkRef.bind('mousemove',parent.moveHandler);
				parent.interval = setInterval(parent.move,30); 
			};
			this.stopMove = function(){
				parent.linkRef.unbind('mousemove',parent.moveHandler);
				clearInterval(parent.interval);
			};
			this.construct = function(sets){
				
				var off=parent.linkRef.offset();
				
				$('<div id="'+this.id+'" class="zoommerMa"><div class="zoommerMaWrap"><img src=""></div></div>').appendTo(this.appendDOM).css({display:"none",opacity:0, top: off.top+this.offsetTop, left: off.left+this.offsetLeft,width: this.width, height: this.height});
				
				$('<div class="zoomerMaBox"></div><p class="zoommerLoading">'+this.loadingTxt+'</p>').appendTo(this.linkRef).css({display:'none'});
				
				this.zoomRef = $("#"+this.id);
				this.zoomImgRef = $("#"+this.id+" img");
				this.zoomBoxRef = $(this.linkRef).find('.zoomerMaBox');
				
				this.zoomBoxRef.css('opacity',0.4);
				
				this.infoRef = $(this.selector+" .zoommerLoading");
						
				this.afterInit(function(){
					$(window).resize(function(){
						var off=parent.linkRef.offset();
						$('#zoommerMa').css({ top: off.top+parent.offsetTop, left: off.left+parent.offsetLeft});
					});				
				});
			};
			this.construct(sets);
		};
		function zoommerLoopClass(sets){
			var parent = this;
			this.id = sets.id;
			this.selector = sets.selector;
			this.loadingTxt = sets.loadingTxt;
			this.appendDOM = sets.appendDOM;
			this.width = sets.width;
			this.height = sets.height;
			this.offsetTop = -(sets.offsetTop+this.height);
			this.offsetLeft = sets.offsetLeft;
			//protected vars
			this.linkRef = $(this.selector);
			this.imgRef = this.linkRef.children("img");
			this.zoomRef = null;
			this.zoomImgRef = null;
			this.infoRef = null;
			this.active = false;
			this.href = '';
			this.src = '';
			this.scale = 1;
			this.stopped = true;
			this.imgWidth = 0;
			this.imgHeight = 0;
			this.zoomWidth = 0;
			this.zoomHeight = 0;
			this.lastPosX = 0;
			this.lastPosY = 0;
			this.lock =false;
			//methods
			this.show = function(data){
				this.beforeShow(function(){
					parent.startMove();
					parent.linkRef.addClass('zooming');
					parent.zoomRef.stop().show(0).animate({opacity:1},300,function(){
						parent.infoRef.hide(0);
					});					
					parent.afterShow();
				});
			};
			this.hide = function(data){
				this.beforeHide(function(){
					parent.stopMove();
					parent.linkRef.removeClass('zooming');
					parent.zoomRef.stop().animate({opacity:0},350,function(){
						parent.zoomRef.hide(0);
						parent.infoRef.hide(0);
					});			
					parent.afterHide();
				});
			};
			this.move = function(x,y){
				if(this.lock)return;
				this.lock =true;
				var off=this.linkRef.offset();
				
				var fromTop=(off.top-y)/this.scale+0.5*this.height;
				var fromLeft=(off.left-x)/this.scale+0.5*this.width;
				var fromX = parseInt(x+this.offsetLeft);
				var fromY = parseInt(y+this.offsetTop);				
				
				
				
				
				if(fromTop>0)fromTop=0; else if(fromTop<(this.height-this.zoomHeight))fromTop = (this.height-this.zoomHeight); 
				if(fromLeft>0)fromLeft=0; else if(fromLeft<(this.width-this.zoomWidth))fromLeft = (this.width-this.zoomWidth); 
				
				this.zoomImgRef.css({top:parseInt(fromTop),left:parseInt(fromLeft)});
				this.zoomRef.css({left:fromX,top:fromY<10?10:fromY});
				this.lock =false;
			};
			this.destruct = function(){
				this.beforeDestruct(function(){
					parent.linkRef.unbind('mousemove',parent.moveHandler);
					parent.zoomRef.unbind('mousemove',parent.moveZoomHandler);
					$(window).unbind('resize',parent.reflesh);
					$(parent.zoomRef).remove();
					$(parent.infoRef).remove();
					$().zoommerMa.manager[this.id] = null;	
					parent.afterDestruct();					
				});					
			};
			//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.moveHandler = function(e){
					parent.move(e.pageX, e.pageY);					
					return false;
			};
			this.moveZoomHandler = function(e){
					var off=parent.linkRef.offset();
					if(off.top<e.pageY&&(off.top+parent.imgHeight)>e.pageY&&off.left<e.pageX&&(off.left+parent.imgWidth)>e.pageX)parent.move(e.pageX, e.pageY);					
					return false;
			};
			this.showHandler = function(){
				if(parent.active==true)return;
				parent.active=true;
				if(parent.src!=parent.imgRef.attr('src')){
					var img= new Image();
					img.onload=function(){
						parent.imgWidth=this.width;
						parent.imgHeight=this.height;
						parent.src = this.src;
						
						if(parent.href!=parent.linkRef.attr('href'))parent.reload(); else parent.show();
					};
					img.src= parent.imgRef.attr('src');
					
				} else if(parent.href!=parent.linkRef.attr('href')){
					parent.reload();
				} else {
					parent.show();
				};
				return false;
			};
			this.reload = function(){
				var img=new Image();
				img.onload=function(){
					parent.href=this.src;
					parent.scale=parent.imgWidth/this.width;
					parent.zoomHeight=this.height;
					parent.zoomWidth=this.width;
					parent.zoomImgRef.attr('src',parent.href);
					
					if(parent.active==true)parent.show(); else parent.infoRef.hide(0);		
				};
				parent.infoRef.show(0);
				img.src=parent.linkRef.attr('href');
			};
			this.hideHandler = function(){
				if(parent.active==false)return;
				parent.active=false;
				parent.hide();				
				return false;
			};
			this.startMove = function(){
				if(!parent.stopped)return;
				parent.stopped=false;
				parent.linkRef.bind('mousemove',parent.moveHandler);
				parent.zoomRef.bind('mousemove',parent.moveZoomHandler);
				
			};
			this.stopMove = function(){
				if(parent.stopped)return;
				parent.stopped=true;
				parent.linkRef.unbind('mousemove',parent.moveHandler);
				parent.zoomRef.unbind('mousemove',parent.moveZoomHandler);
			};
			this.construct = function(sets){
				
				var off=parent.linkRef.offset();
				
				$('<div id="'+this.id+'" class="zoommerMa"><div class="zoommerMaWrap"><img src=""></div></div>').appendTo(this.appendDOM).css({display:"none",opacity:0, top: off.top+this.offsetTop, left: off.left+this.offsetLeft,width: this.width, height: this.height});
				
				$('<p class="zoommerLoading">'+this.loadingTxt+'</p>').appendTo(this.linkRef).css({display:'none'});
				
				this.zoomRef = $("#"+this.id);
				this.zoomImgRef = $("#"+this.id+" img");
				
				
				this.infoRef = $(this.selector+" .zoommerLoading");
						
				this.afterInit(function(){});
			};
			this.construct(sets);
		};
		function zoommerUrbanClass(sets){
			var parent = this;
			this.id = sets.id;
			this.selector = sets.selector;
			this.loadingTxt = sets.loadingTxt;
			this.appendDOM = sets.appendDOM;
			//protected vars
			this.linkRef = $(this.selector);
			this.imgRef = this.linkRef.children("img");
			this.zoomRef = null;
			this.zoomImgRef = null;
			this.infoRef = null;
			this.active = false;
			this.href = '';
			this.src = '';
			this.scale = 1;
			this.iterator = 1;
			this.imgWidth = 0;
			this.imgHeight = 0;
			this.zoomWidth = 0;
			this.zoomHeight = 0;
			this.lock =false;
			//methods
			this.show = function(data){
				this.beforeShow(function(){
					parent.zoomRef.bind('mousemove',parent.moveHandler);
					parent.zoomRef.stop().show(0).animate({opacity:1},300,function(){
						parent.infoRef.hide(0);
					});					
					parent.afterShow();
				});
			};
			this.hide = function(data){
				this.beforeHide(function(){
					parent.zoomRef.unbind('mousemove',parent.moveHandler);
					parent.zoomRef.stop().animate({opacity:0},350,function(){
						parent.zoomRef.hide(0);
						parent.infoRef.hide(0);
					});			
					parent.afterHide();
				});
			};
			this.move = function(x,y){
				if(this.lock)return;
				this.lock =true;
				var off=this.linkRef.offset();
				
				var fromTop=(off.top-y)*this.iterator;
				var fromLeft=(off.left-x)*this.iterator;
				
				if(fromTop>0)fromTop=0; else if(fromTop<(this.imgHeight-this.zoomHeight))fromTop = (this.imgHeight-this.zoomHeight); 
				if(fromLeft>0)fromLeft=0; else if(fromLeft<(this.imgWidth-this.zoomWidth))fromLeft = (this.imgWidth-this.zoomWidth); 
				
				this.zoomImgRef.css({top:parseInt(fromTop),left:parseInt(fromLeft)});
				this.lock =false;
			};
			this.destruct = function(){
				this.beforeDestruct(function(){
					parent.zoomRef.unbind('mousemove',parent.moveHandler);
					$(window).unbind('resize',parent.reflesh);
					$(parent.zoomRef).remove();
					$(parent.infoRef).remove();
					$().zoommerMa.manager[this.id] = null;	
					parent.afterDestruct();					
				});					
			};
			//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.moveHandler = function(e){
					parent.move(e.pageX, e.pageY);					
					return false;
			};
			this.showHandler = function(e){
				if(parent.active==true)return;
				parent.active=true;
				if(parent.src!=parent.imgRef.attr('src')){
					var img= new Image();
					img.onload=function(){
						parent.imgWidth=this.width;
						parent.imgHeight=this.height;
						parent.src = this.src;
						
						parent.zoomRef.css({
							width:this.width,
							height:this.height	
						});
						if(parent.href!=parent.linkRef.attr('href'))parent.reload(); else parent.show();
					};
					img.src= parent.imgRef.attr('src');
					
				} else if(parent.href!=parent.linkRef.attr('href')){
					parent.reload();
				} else {
					parent.show();
				};
				return false;
			};
			this.reload = function(){
				var img=new Image();
				img.onload=function(){
					parent.href=this.src;
					parent.scale=parent.imgWidth/this.width;
					parent.iterator = (1-parent.scale)/parent.scale;
					parent.zoomHeight=this.height;
					parent.zoomWidth=this.width;
					parent.zoomImgRef.attr('src',parent.href);
					
					if(parent.active==true)parent.show(); else parent.infoRef.hide(0);		
				};
				parent.infoRef.show(0);
				img.src=parent.linkRef.attr('href');
			};
			this.hideHandler = function(){
				if(parent.active==false)return;
				parent.active=false;
				parent.hide();				
				return false;
			};
			this.construct = function(sets){
				
				var off=parent.linkRef.offset();
				
				$('<div id="'+this.id+'" class="zoommerMa"><img src=""><span>Zamknij</span></div>').appendTo(this.appendDOM).css({display:"none",opacity:0, top: off.top, left: off.left});
				
				$('<p class="zoommerLoading">'+this.loadingTxt+'</p>').appendTo(this.linkRef).css({display:'none'});
				
				this.zoomRef = $("#"+this.id);
				this.zoomImgRef = $("#"+this.id+" img");
				
				this.infoRef = $(this.selector+" .zoommerLoading");
				
				this.afterInit(function(){
					$(window).resize(function(){
						var off=parent.linkRef.offset();
						$('#zoommerMa').css({ top: off.top, left: off.left});
					});
				});
			};
			this.construct(sets);
		};
		
		
		
	}
});
