/*!
 * 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
	plus:  false,
	minus: false,
  	step : 3,
  	frameColor: "#cecece",
  	frameWidth: 1,
  	re : 'large', 
  	replace : 'thickbox',  
  	debug : false,
  	loaderContent: "loading...",  // plain text or an image tag eg.: "<img src='yoursite.com/spinner.gif' />"
  	zoomIcon : "" // icon url, if not empty shown on the right-top corner of the image
	}, settings);

	return this.each(function(){
	  var value_size = 0;
	  var value_size2 = 0;
	  var swapped = false;
	  
	  
	  
		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, height: settings.sH });
		var ig = $div.children().css({position: "relative"});
		
		jQuery(window).bind("load", function() {
			ig.css({left:"0", top:"0"});
		});
		
		var wStep = [];
		var hStep = [];
		var n = (settings.step *(settings.step + 1)) / 2;

		for(i = 1; i < (settings.step + 1); i++) {
			wStep[wStep.length] = (settings.lW - settings.sW) / n * i;
			hStep[hStep.length] = (settings.lH - settings.sH) / n * i;
		}
		
		var local_step = 0;
			
		var $plus  = settings.plus  ? settings.plus : jQuery('<div class="ui-icon ui-icon-circle-plus gzoombutton">+</div>').insertAfter($div);
		var $minus = settings.minus ? settings.minus: jQuery('<div class="ui-icon ui-icon-circle-minus gzoombutton">-</div>').insertAfter($div);
		
		function resize(st, button) {
			//if reset
			if(ig.width() == settings.sW) {
				swapped = false;
				value_size  = 0;
				value_size2 = 0;
				local_step  = 0;
			}
			
			button = button || false;
			
			if(!swapped) {
					var hiSrc = ig.attr("src").replace(settings.re, settings.replace);
					swapImage(ig, hiSrc);
					$div.children("span.loader").fadeIn(250);
					swapped = true;
			}
			
			if(st) {
				if(value_size != (settings.lW - settings.sW) ) {
					value_size  += wStep[local_step];
					value_size2 += hStep[local_step];
					local_step++;
				}
			}
			else {
				
				if(value_size != 0) {
					local_step--;
					value_size  -= wStep[local_step];
					value_size2 -= hStep[local_step];
				}
			}
		
			newWidth  = settings.sW  + value_size;
			newHeight = settings.sH  + value_size2;
			
			ig_pos = ig.position();

			if(settings.debug && typeof(console) != 'undefined') {
				console.log('new dimensions:'+newWidth+'x'+newHeight);
			}

			deltaWidth    = ig.width() - settings.sW;
			newDeltaWidth = newWidth - settings.sW;
			
			leftPos = Math.abs(ig_pos.left);
			leftFactor = leftPos/deltaWidth;
			
			if(button || value_size == wStep[0]) {
				newLeft = newDeltaWidth/2*-1;
			}
			else {
				newLeft = (leftFactor*newDeltaWidth)*-1;
				if(newLeft > 0)
					newLeft = 0;
			}
			
			deltaHeight = ig.height()-settings.sH;
			
			topPos = Math.abs(ig_pos.top);

			topFactor = topPos/deltaHeight;
			newDeltaHeight = newHeight-settings.sH;
			
			if(button || value_size == wStep[0]) {
				newTop = newDeltaHeight/2*-1;
			}
			else {
				newTop = (topFactor*newDeltaHeight)*-1;
			}
			
			ig.css({ width: newWidth, height: newHeight, left:newLeft, top:newTop});
		
		
		}
		
		$plus.click(function() {
			resize(true);
		});
		
		$minus.click(function() {
			resize(false);
		});
		
		$('<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){
			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($.event.special.mousewheel) != 'undefined') {
			ig.mousewheel(function(event, delta) {
			if (delta > 0) {
				resize(true);
	  		} else if (delta < 0) {
				resize(false);
		  	}
	      return false; // prevent default
	    });
	  }
		
		
	});	
	
};
