/*!
 * jQuery gzoom 0.1
 * 2009 Giovanni Battista Lenoci <gianiaz@gianiaz.net>
 * 
 * Based on minizoomPan plugin of Gian Carlo Mingati Version: 1.0 (18-JUNE-2009) http://www.gcmingati.net/wordpress/wp-content/lab/jquery/minizoompan/
 * Inspiration from jquery lightbox plugin http://leandrovieira.com/projects/jquery/lightbox/
 * Dual licensed under the MIT and GPL licenses:
 * http://www.opensource.org/licenses/mit-license.php
 * http://www.gnu.org/licenses/gpl.html
 *
 * Requires:
 * jQuery v1.3.2 or later
 * jQuery ui.core.js v.1.7.1
 * jQuery ui.slider.js v.1.7.1
 * 
 */


jQuery.fn.gzoom = function(settings) {
	settings = jQuery.extend({
  	sW: 10, // small image width
  	sH: 10, // small image height
  	lW: 20, // large image width
  	lH: 20, // large image height
  	step : 5,
  	frameColor: "#ffffff",
  	frameWidth: 1,
  	re : /thumbs\//, 
  	replace : '',  
  	debug : false,
  	overlayBgColor : '#000',
    overlayOpacity:0.8,
    containerBorderSize: 10, 
    containerResizeSpeed : 400,
  	loaderContent: "loading...",  // plain text or an image tag eg.: "<img src='yoursite.com/spinner.gif' />"
  	lightbox: false,
  	zoomIcon : "" // icon url, if not empty shown on the right-top corner of the image
	}, settings);

	return this.each(function(){
	  
	  var swapped = false;
	  var mousedown = false;		// ISL
	  var startX, startY;			// ISL
	  
		var $div = jQuery(this).css({width: settings.sW, height: settings.sH, border: settings.frameWidth+"px solid "+settings.frameColor, overflow:'hidden'}).addClass("minizoompan");
		$div.wrap('<div class="gzoomwrap"></div>').css({ width:settings.sW });
		var ig = $div.children().css({position: "relative"});
		
		$div.bind("mousedown", function(event){		// Added drag mode by ISL
			mousedown = (jQuery.browser.msie) ? !mousedown : true;
			if (mousedown) {
				startX = event.pageX;
				startY = event.pageY;
				$div.css('cursor', 'move');
			} else {
				$div.css('cursor', 'auto');
			}
			return false;							// prevent drag 
		});
				
		$div.mouseup(function() {					// ISL
			if (!jQuery.browser.msie) {
				$div.css('cursor', 'auto');
				mousedown = false;
			}
		});
		
		$div.mouseout(function() {					// ISL
			$div.css('cursor', 'auto');
			mousedown = false;
		});
		
		jQuery(window).bind("load", function() {
	  		ig.width(settings.sW); 
  			ig.height(settings.sH); 
		});
		
		
		//jQuery("<span class='loader'>"+settings.loaderContent+"<\/span>").insertBefore(ig);	// comment out by ISL
		if(settings.zoomIcon != '' && settings.lightbox) {
		  var $zoom = jQuery('<img class="zoomIcon" src="'+settings.zoomIcon+'" alt="view larger" />').insertBefore(ig);
		  $zoom.load(function() {
  		  $zoom.css({'left':(settings.sW - $zoom.width())+'px'}).show();
		  });
		  $zoom.click(function() {
		    drawIface();
		  });
		} else if(settings.lightbox) {
			$div.click(function() {
			  drawIface();
			});
			$div.css({'cursor':'pointer'}); 
		}
		
		var $plus = jQuery('<div class="ui-icon ui-icon-circle-plus gzoombutton">&nbsp;</div>').insertAfter($div);
		var $slider = jQuery('<div class="gzoomSlider"></div>').insertAfter($div).css({width:(settings.sW-42)+'px'});
		var $minus = jQuery('<div class="ui-icon ui-icon-circle-minus gzoombutton">&nbsp;</div>').insertAfter($div);
						
		$plus.click(function() {
		  valore = parseInt($slider.slider('value')) + settings.step;
		  $slider.slider('value', valore);
		});
		
		$minus.click(function() {
		  valore = parseInt($slider.slider('value')) - settings.step;
		  $slider.slider('value', valore);
		});
		
		$slider.slider({value:0,
		            		min: 0,
		            		max: 100,
		            		step: settings.step, 
                    change: function(event, ui) { 
                    
                      if(!swapped) {
	              				var hiSrc = ig.attr("src").replace(settings.re, settings.replace);
	              				swapImage(ig, hiSrc);
	              				$div.children("span.loader").fadeIn(250);
	                      swapped = true;
	                    }
	                    
                      val = ui.value;

                      newWidth = settings.sW+((settings.lW-settings.sW)*val)/100;
                      newHeight = settings.sH+((settings.lH-settings.sH)*val)/100;
                      ig_pos = ig.position();

                      if(settings.debug && typeof(console) != 'undefined') {
                        console.log('new dimensions:'+newWidth+'x'+newHeight);
                      }
                      
                      deltaWidth = ig.width()-settings.sW;
                      leftPos = Math.abs(ig_pos.left);
                      leftFactor = leftPos/deltaWidth;
                      newDeltaWidth = newWidth-settings.sW;
                      newLeft = (leftFactor*newDeltaWidth)*-1;
                      
                      deltaHeight = ig.height()-settings.sH;
                      topPos = Math.abs(ig_pos.top);
                      topFactor = topPos/deltaHeight;
                      newDeltaHeight = newHeight-settings.sH;
                      newTop = (topFactor*newDeltaHeight)*-1;
              				ig.css({ width: newWidth, height: newHeight, left:newLeft, top:newTop});
                    }
               		});
		jQuery('<br style="clear:both" />').insertAfter($plus);
		
		function swapImage(param, uri){
			param.load(function () {
				$div.children("span.loader").fadeOut(250);
			}).error(function (){
  			alert("Image does not exist or its SRC is not correct.");
			}).attr('src', uri);
		}
		
		$div.mousemove(function(e){			// ISL - altered entire routine for dragging
			if (mousedown) {
				var diffX = e.pageX - startX;
				var diffY = e.pageY - startY;
				startX = e.pageX;
				startY = e.pageY;
				
				var igPos = ig.position();
				var divPos = $div.position();
				
				var newTop = igPos.top + diffY;
				var newLeft = igPos.left + diffX;
				
				if (newTop <= 0 && newLeft <= 0) {
					var newBot = newTop + ig.height();
					if (newBot >= $div.height()) {
						var newRight = newLeft + ig.width();
						if (newRight >= $div.width()) 
							ig.css({left: newLeft, top: newTop});
					}
				}
				
				/*
				var divWidth = $div.width();
				var divHeight = $div.height();
				var igW = ig.width();
				var igH = ig.height();
				var dOs = $div.offset();
				var leftPan = (e.pageX - dOs.left) * (divWidth - igW) / (divWidth+settings.frameWidth*2);
				var topPan = (e.pageY - dOs.top) * (divHeight - igH) / (divHeight+settings.frameWidth*2);
	
		        if(settings.debug && typeof(console) != 'undefined') {
				  console.log('left:'+leftPan+'|Top:'+topPan);
				}

 				ig.css({left: leftPan, top: topPan});
 				*/
			}		
		});    
		
	  if(typeof($) != 'undefined'){
		/*
		if(typeof($.event.special.mousewheel) != 'undefined') {
			ig.mousewheel(function(event, delta) {
				if (delta > 0) {
					valore = parseInt($slider.slider('value')) + settings.step;
					$slider.slider('value', valore);
				} else if (delta < 0) {
					valore = parseInt($slider.slider('value')) - settings.step;
					$slider.slider('value', valore);
				}
				return false; // prevent default
				});//mousewheel

		} //special mousewheel
		*/
	 } //$
		
		function resize_fx(intImageWidth,intImageHeight) {
		
      if(settings.debug && typeof(console) != 'undefined') {
        console.log('resize_fx('+intImageWidth+','+intImageHeight+')');
      }

			if(intImageWidth > (jQuery(window).width()*80/100)) {
  			imgWidth = jQuery(window).width()*80/100;
  			intImageHeight = (imgWidth/intImageWidth)*intImageHeight;
  			jQuery('#zoomedimage').css({'width': imgWidth+'px', 'height':intImageHeight});
	      if(settings.debug && typeof(console) != 'undefined') {
	        console.log('Img dimensions 80% horizontal:'+imgWidth+'x'+intImageHeight);
	      }
			} else {
  			imgWidth = intImageWidth;
			}
			
			if(intImageHeight > jQuery(window).height()*80/100) {
			  imgHeight = jQuery(window).height()*80/100;
			  imgWidth = (imgHeight/intImageHeight)*imgWidth;
  			jQuery('#zoomedimage').css({'width': imgWidth+'px', 'height':imgHeight});
	      if(settings.debug && typeof(console) != 'undefined') {
	        console.log('Img dimensions 80% vertical:'+imgWidth+'x'+imgHeight);
	      }
			} else {
			  imgHeight = intImageHeight;
			}
			
      if(settings.debug && typeof(console) != 'undefined') {
        console.log('Img dimensions:'+imgWidth+'x'+imgHeight);
      }
			
			// Get current width and height
			var intCurrentWidth = jQuery('#imagebox').width();
			var intCurrentHeight = jQuery('#imagebox').height();
			// Get the width and height of the selected image plus the padding
			var intWidth = (imgWidth + (settings.containerBorderSize * 2)); // Plus the imageŽs width and the left and right padding value
			var intHeight = (imgHeight + (settings.containerBorderSize * 2)); // Plus the imageŽs height and the left and right padding value

    
			
			// Diferences
			var intDiffW = intCurrentWidth - intWidth;
			var intDiffH = intCurrentHeight - intHeight;
			// Perfomance the effect
			jQuery('#imagebox').animate({ width: intWidth, height: intHeight },settings.containerResizeSpeed,function() { _show_image(); });
			if ( ( intDiffW == 0 ) && ( intDiffH == 0 ) ) {
				if ( jQuery.browser.msie ) {
					___pause(250);
				} else {
					___pause(100);	
				}
			} 
			jQuery('#lboximgdatacontainer').css({ width: imgWidth });
		};
		
		function drawIface() {
		
			jQuery('body').append('<div id="gzoomoverlay"></div><div id="gzoomlbox"><div id="imagebox"><div id="gzoom-cont-img"><img id="zoomedimage"><div id="gzoomloading"><a href="#" id="gzoomloadinglink"><img src="images/loading.gif"></a></div></div></div><div id="gzoomlbox-con-imgdata"><div id="lboximgdatacontainer"><div id="gzoomlbox-image-details"><span id="gzoom-image-caption"></span></div></div></div></div>');	
		
			jQuery('#gzoomoverlay').css({
				backgroundColor:	settings.overlayBgColor,
				opacity:			settings.overlayOpacity,
				width:				jQuery(window).width(),
				height:				jQuery(document).height()
			}).fadeIn();
			
			// Calculate top and left offset for the gzoomlbox div object and show it
			jQuery('#gzoomlbox').css({
				top:	jQuery(window).scrollTop() + (jQuery(window).height() / 10),
				left:	jQuery(window).scrollLeft()
			}).show();
			
			jQuery('#gzoomoverlay,#gzoomlbox').click(function() {
				close();									
			});
			// If window was resized, calculate the new overlay dimensions
			jQuery(window).resize(function() {
				jQuery('#gzoomoverlay').css({
					width:		jQuery(window).width(),
					height:		jQuery(window).height()
				});
				// Calculate top and left offset for the jquery-lightbox div object and show it
				jQuery('#gzoomlbox').css({
					top:	jQuery(window).scrollTop() + (jQuery(window).height() / 10),
					left:	jQuery(window).scrollLeft()
				});
			});
			
			_set_image_to_view();
		}

		function _set_image_to_view() { // show the loading
			// Show the loading
			jQuery('#gzoomlbox-con-imgdata').hide();
			jQuery('#zoomedimage').hide();
			jQuery('#gzoomloading').show();
			// Image preload process
			var objImagePreloader = new Image();
      if(!swapped) {
				var hiSrc = ig.attr("src").replace(settings.re, settings.replace);
		  } else {
				var hiSrc = ig.attr("src").replace(settings.re, settings.replace);
		  }
			objImagePreloader.onload = function() {
				jQuery('#zoomedimage').attr('src',hiSrc);
				resize_fx(objImagePreloader.width,objImagePreloader.height);
			};
		  objImagePreloader.src = hiSrc;
		};

		function _show_image() {
 			jQuery('#gzoomloading').hide();
			jQuery('#zoomedimage').fadeIn(function() {
				_show_image_data();
			});
		};

		/**
		 * Show the image information
		 *
		 */
		function _show_image_data() {
			jQuery('#lightbox-loading').hide();
      jQuery('#gzoom-image-caption').html(ig.attr('title'));
			jQuery('#gzoomlbox-con-imgdata').slideDown('fast');
		}
		
		function close() {
			jQuery('#gzoomlbox').remove();
			jQuery('#gzoomoverlay').fadeOut(function() { jQuery('#gzoomoverlay').remove(); });
			jQuery('embed, object, select').css({ 'visibility' : 'visible' });
		}

    function ___pause(ms) {
  		var date = new Date(); 
	  	curDate = null;
		  do { var curDate = new Date(); }
  		while ( curDate - date < ms);
	  };
		
	});	
	
};