/*
 * jQuery WCS Image Zoom Plugin
 * Examples and documentation at: http://demo.webcodingstudio.com/wcs-zoom/
 * Copyright (c) 2010 Evgeny Matsakov
 * Version: 1.0 (1-JUL-2010)
 * 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.2.6 or later
 */
(function($){
	$.fn.wcs_zoom = function(element_params){
		
		var defaults = {
			small_width: 10, // small image width
			small_height: 10, // small image height
			large_width: 20, // large image width
			large_height: 20, // large image height
			dir_original : 'original', 
			dir_preview : 'preview', 
			dir_thumbnail : 'thumbnail', 
			
			loader_content: "loading...",  // plain text or an image tag eg.: "<img src='yoursite.com/spinner.gif' />"
			lightbox: false,
			
			slider_step : 1,
			slider_speed: 10,
			
			debug : false
		}
		
		var settings = $.extend({}, defaults, element_params);
		
		return this.each(function(){
			
			var swapped = false;
			
			//wrap image
			var $img = $(this).wrap('<div class="zoompan"></div>');
			//get image container
			var $div = $(this).parent();
			
			//init container styles
			$div.css({width: settings.small_width, height: settings.small_height, overflow:'hidden'});
			//set wrapper
			$div.wrap('<div class="zoomwrap"></div>').css({ width:settings.small_width });
			
			$img.css({position: "relative"});			
			//set image size
			/*$(window).bind("load", function() {
				$img.width(settings.small_width); 
			});*/
			
			$('<span class="loader">'+settings.loader_content+'</span>').insertBefore($img);
			
			var $slider_wrapper = $('<div class="zoomnav">').insertAfter($div);
			
			var $minus = $('<a style="display:none" href="#" class="minus">minus</a>').appendTo($slider_wrapper);
			var $slider = $('<div style="display:none" class="slider"></div>').appendTo($slider_wrapper).css({ width:(settings.small_width-83)+'px'});
			var $plus = $('<a style="display:none" href="#" class="plus">plus</a>').appendTo($slider_wrapper);
			$slider.wrap('<div style="display:none" class="slider-outer"></div>');
			$slider_outer = $slider.parent();
			$slider_outer.css({ width:(settings.small_width-66)+'px' });
			
			//init vars		
			var floor_zoom = 1;
			var ceiling_zoom;
			if (settings.large_width > settings.large_height) {
	            ceiling_zoom = settings.large_width / settings.small_width;
	        } else {
	            ceiling_zoom = settings.large_height / settings.small_width;
	        }
			var image_zoom = 1;
			var image_x = 0;
        	var image_y = 0;
			
			//init slider
			$slider.slider({
				value:0,
				min: 0,
				max: 100,
				step: settings.slider_step, 
				slide: function(event, ui) { 				
					scale(ui.value);						
				},
				change : function(event, ui){
					scale(ui.value);
				}
			});
			
			//init draggable
			/*$img.draggable({
				drag: function(event, ui) {
					//top boundary
					if (ui.position.top > 0) {
						ui.position.top = 0;	
					}
					//left boundary
					if (ui.position.left > 0) {
						ui.position.left = 0;	
					}
					//right boundary
					if ( (settings.small_width - $img.width() ) > ui.position.left ) {
						ui.position.left = settings.small_width - $img.width();	
					}
					
					//bottom boundary
					if ( (settings.small_height - $img.height() ) > ui.position.top ) {
						ui.position.top = settings.small_height - $img.height();	
					}
					
					image_x = ui.position.left;
					image_y = ui.position.top;
				
				}
			}); */
			
			//init cursor
			$div.mousedown(function(e) {			
				$(this).css('cursor','move');
				return false;
			});
			$div.mouseup(function(e) {
				$(this).css('cursor','default');
			});
			
			//scale
			function scale(val) {
				
				if(!swapped) {
					var $original = $img.attr("src").replace(settings.dir_preview, settings.dir_original);
					swap_image($img, $original);
					$div.children("span.loader").fadeIn(250);
					swapped = true;
				}	
				
				var center_x  = (settings.small_width*(1-image_zoom)/2-image_x)/image_zoom;
		        var center_y  = (settings.small_height*(1-image_zoom)/2-image_y)/image_zoom;
		        var over_size = (settings.large_width > settings.small_width && settings.large_height > settings.small_height);
		        
				image_zoom = floor_zoom+(val/100*(ceiling_zoom-floor_zoom));
				
		        if (over_size) {
		            if (settings.large_width > settings.small_width) {
		                var image_width =  (image_zoom*settings.small_width)+'px';
						$img.css({width:image_width});
		            }
		        } else {
		            slider = slider("disable");
		        }
		
		        image_x = settings.small_width*(1-image_zoom)/2-center_x*image_zoom;
		        image_y = settings.small_height*(1-image_zoom)/2-center_y*image_zoom;
		
				contain(image_x, image_y);
		
		        return true;
				
			}
			
			/*
			* This method need to review. 
			* Bug appears when zoom in near the right or bottom boundary of image
			*/
			function contain(x,y) {
				
				var x_min = 0, x_max = settings.small_width-settings.large_width;
				var y_min = 0, y_max = settings.small_height-settings.large_height;
				
				x = x>x_min ? x_min : x;
				x = x<x_max ? x_max : x;
				y = y>y_min ? y_min : y;
				y = y<x_max ? x_max : y;
				
				//right boundary
				if ( ($img.width() + parseInt($img.css('left')) ) < settings.small_width ) {
					x = settings.small_width - $img.width();
					image_x = x;	
				}
				
				//bottom boundary
				if ( ($img.height() + parseInt($img.css('top')) ) < settings.small_height ) {
					y = settings.small_height - $img.height();
					image_y = y;	
				}
				
				$img.css({top:y});
				$img.css({left:x});
				
				return [x,y];
			}
			
			
			$plus.click(function() {
				valore = parseInt($slider.slider('value')) + settings.slider_step;
				$slider.slider('value', valore);
				return false;
			});
			
			$minus.click(function() {
				valore = parseInt($slider.slider('value')) - settings.slider_step;
				$slider.slider('value', valore);
				return false;
			});
			
			var plus_interval;
			
			$plus.mousedown(function() {
				plus_interval = setInterval(function() { 
					valore = parseInt($slider.slider('value')) + settings.slider_step;
					$slider.slider('value', valore);
				} , settings.slider_speed); 
				return false;
			});
			
			$plus.bind('mouseup mouseleave', function() {
			  	clearInterval( plus_interval );
				return false;
			});
			
			var minus_interval;
			
			$minus.mousedown(function() {
				minus_interval = setInterval(function() { 
					valore = parseInt($slider.slider('value')) - settings.slider_step;
					$slider.slider('value', valore);
				} , settings.slider_speed); 
				return false;
			});
			
			$minus.bind('mouseup mouseleave', function() {
				clearInterval( minus_interval );
				return false;
			});			
			
			//swap image src
			function swap_image(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);
			}
		
		});
		
	}
})(jQuery);
