

;(function($){
	$.fn.productImageZoomer = function(op){

		var sf = $.fn.productImageZoomer;
		var ths = $(this);
		
					var zoomLeft=0;
					var zoomTop=0;


		// First, let's get refernces to the elements we will
		// be using.
		var image = $( "img.info" , ths);
		var imageBig = $( "img.popup" , ths);
		
		//preload image
		clearImage = new Image(); 
		clearImage.src = image.attr('src'); 
		//preload image
		clearImage = new Image(); 
		clearImage.src = imageBig.attr('src'); 

		
		// Create the ZOOM element - this will be added with
		// Javascript since it's more of an "effect".
		var zoom = $( "<a id='zoom'><span><br /></span></a>" );
 		
			// Before we start messing with the scripts, let's
			// update the display to allow for the absolute
			// positioning of the image and zoomer.
			// Set an explicit height / width on the view based
			// on the initial size of the image.
		var imgData = ths.getImageData(image);   
		var imgBigData = ths.getImageData(imageBig);   
		ths.width( imgData.width );
		//
 

		var zoomLevels = 6;
		var zoomLevel = 0;
 		var ratio = ths.imageRatio(imgData.width,imgBigData.width);
		var currentSize = ths.imageZoomRatio(imgData,imgBigData,zoomLevels,0);
		var zoomSize = ths.imageZoomRatio(imgData,imgBigData,zoomLevels,1);
 
		zoom.css({'z-index':99});
		imageBig.css({'z-index':1});
		
		 imageBig.width=Math.floor( imgData.width + zoomSize.width);
		 imageBig.height=Math.floor( image.height() + zoomSize.height);
		 // Animate the zoom.
		 
		 /*
		imageBig.animate(
					{
						width: imgData.width,
						height: imgData.height,
						left: 0,
						top: 0
					},
					50
				);
				
				*/
			// Before we add the zoom square, we need it to match
			// the aspect ratio of the image.
			zoom.width( Math.floor( imgData.width - zoomSize.width) );
			zoom.height( Math.floor( imgData.height - zoomSize.height) );
 
			// Now, add the zoom square to the view.
			ths.append( zoom );
			
			
			// ---------------------------------------------- //
			// ---------------------------------------------- //
			var sliderChange = function(e, ui){
				zoomLevel = ui.value;
				zoomImage(zoomLevel);
				return true;
			};
			var sl = $('#ilslider').slider({'slide':sliderChange, 'min' : 0,'max' :zoomLevels, 'value': zoomLevel});	
 
			// Now that we have our UI set up physically, we need
			// to bind the event handlers.
 
			// We want to show and hide the zoom only when the
			// user hovers over the view.
			ths.hover(
				function( event ){
					// Show the soom.
					zoom.show();
				},
				function( event ){
					// Hide the zoom.
					zoom.hide();
				}
			);			

			// As the user mouses over the view, we can get the
			// mouse coordinates in terms of the page; we need
			// to be able to translate those into VIEW-based
			// X and Y cooridates. As such, let's get the offset
			// of the view as our base 0x0 coordinate.
			//
			// NOTE: We are doing this here so that we do it once,
			// rather than every time the mouse moves.
			viewOffset = ths.offset();
 
			// Get the jQuery-ed version of the window as we will
			// need to access it's scroll offsets every time the
			// mouse moves over the div.
			//
			// NOTE: This will change the change the refernce to
			// "window" for all of the code in this closure.
			var window = $( window );
 
 
			// As the user moves across the view, we want to move
			// the zoom square with them.
			ths.mousemove(
				function( event ){
					// Get the window scroll top; the mouse
					// position is relative to the window, NOT
					// the document.
					var windowScrollTop = window.scrollTop();
					var windowScrollLeft = window.scrollLeft();
 
					// Translate the mouse X / Y into view-local
					// coordinates that can be used to position
					// the zoom box.
					setZoomPosition(
						Math.floor(
							event.clientX - viewOffset.left + windowScrollLeft
						),
						Math.floor(
							event.clientY - viewOffset.top + windowScrollTop
						)
					);
				}
			);
 			
 
			// Now, let's attach the click event handler to the
			// zoom box.
			zoom.click(
				function( event ){
					// First, prevent the default since this is
					// not a navigational link.
					event.preventDefault();
	
 					zoomLevel++;
 						
					sl.slider({value:zoomLevel});
					// Let's pass the position of the zoom box
					// off to the function that is responsible
					// for zooming the image.
					zoomImage(zoomLevel);
					

				}
			);		
			
		
			// As a final step, to make sure that the image can
			// be zoomed out, bind the mousedown to the document.
			$( document ).mousedown(
				function( event ){
					// Check to see if the view is in the event
					// bubble chain for the mouse down. If it is,
					// then this click was in the view or its
					// child elements.
					/*
					var closestView = $( event.target ).closest( "#view" );
					// Check to see if this mouse down was in the
					// image view.
					if (!closestView.size()){
 
						// The view was not found in the chain.
						// This was clicked outside of the view.
						// Reset the image zoom.
						//resetZoom();
 
					}
					*/
				}
			);				
			var oldPos = {left:0, top:0, width: 0, height: 0};
			// I position the zoom box within the view based on
			// the given view-local mouse coordinates.
			var setZoomPosition = function( mouseLeft, mouseTop ){
				// Ideally, we want to keep the zoom box centered
				// on the mouse. As such, we want the given mouse
				// left and mouse top coordiantes to be in the
				// middle of the zoom box.
				var zoomLeft = (mouseLeft - (zoom.width() / 2));
				var zoomTop = (mouseTop - (zoom.height() / 2))
 
				// As we move the zoom box around, however, we
				// never want it to go out of bounds of the view.
 
				// Protect the top-left bounds.
				zoomLeft = Math.max( zoomLeft, 0 );
				zoomTop = Math.max( zoomTop, 0 );

				scrollLeft = Math.max( zoomLeft, 0 );
				scrollTop = Math.max( zoomTop, 0 );
								
				// Protect the bottom-right bounds. Because the
				// bottom and right need to take the dimensions
				// of the zoom box into account, be sure to use
				// the outer width to include the border.
				zoomLeft = Math.min(
					zoomLeft,
					(ths.width() - zoom.outerWidth())
					);
				zoomTop = Math.min(
					zoomTop,
					(ths.height() - zoom.outerHeight())
					);
 
				scrollLeft = Math.min(
					zoomLeft,
					(ths.width() - (zoom.outerWidth()))
					);					
				scrollTop = Math.min(
					zoomTop,
					(ths.height() - (zoom.outerHeight()))
					);					
				// Position the zoom box in the bounds of the
				// image view box.
				zoom.css({
					left: zoomLeft,
					top: zoomTop
				});

				oldPos = {left:-scrollLeft, top:-scrollTop, width: zoom.width(), height: zoom.height()};
				
				 // Animate Scroll the zoom.
				 if (zoomLevel > 0) {
					 // animate zoomscroll
					imageBig.animate(
						{
							left: -scrollLeft*zoomLevel,
							top: -scrollTop*zoomLevel
						},
						10
					);	
				 }						
			};	
			

 
			// I take the zoom box coordinates and translate them
			// into an actual image zoom based on the existing
			// zoom and offset of the image.
			//
			// NOTE: We don't care about the dimensions of the
			// zoom box itself as those should have already been
			// properly translated into the zoom *factor*.
			var zoomImage = function(factor){
				if (factor == 0 || factor > zoomLevels) {
					resetZoom();
				} else {
					image.hide();
					var _i = $( "img.popup" , ths);
					
					ths.height( image.height() );
 					ths.showImage(_i);
				}



				// Check to see if we have reached the max zoom
				// or if the image is currently animating.
				// If so, just return out.
				if (
					(factor > zoomLevels) ||
					(imageBig.is( ":animated" ))
					){
 					
					// Zooming in beyond this is pointless (and
					// can cause the browser to mis-render the
					// image).
					return;
				}
				//

				var _width = image.width()+(zoomSize.width*factor);
				var _height = image.height()+(zoomSize.height*factor);	 					


							
				// Animate the zoom.
				imageBig.animate(
					{
						width: _width,
						height: _height,
						left:oldPos.left*factor,
						top:oldPos.top*factor
					},
					100
				);
				zoom.css(oldPos);	
				
			};	

			
							
			// I reset the image zoom.
			var resetZoom = function(){
				// Get a reference to the image data object so we
				// don't need to keep retreiving it.

				 sl.slider({value:0});
				// Reset the image data.
				
				zoomLeft=0;
				zoomTop=0;
								
				zoomLevel = 0;
				imageBig.top = 0;
				imageBig.left = 0;
				
				imageBig.width = imgData.width;
				imageBig.height = imgData.height;
				
				ths.width(imgData.width);
				ths.height(imgData.height);
				// Animate the zoom.
				imageBig.animate(
					{
						width: imgData.width,
						height: imgData.height,
						left: 0,
						top: 0
					},
					300
				);
			};
	};
	
	$.fn.extend({
		showImage:function(img){
			// Now that the view has an explicit width and height,
			// we can change the displays for positioning.
			img.css( "position", "absolute" );	
			// Set an exlicit height on the image (to make sure
			// that some of the later calcualtions don't get
			// messed up - I saw some irradic caculated-height
			// behavior).
			img.height( img.height() );	
			img.show();				
		},
		getImageData:function(img){
			return {
				zoom: 0,
				top: 0,
				left: 0,
				width: img.width(),
				height: img.height()
				};						
		},
		imageRatio:function(imageData,imageBigData) {
			var ratio = imageBigData / imageData;
			return ratio;
		},
		imageZoomRatio:function(imageData,imageBigData,zoomLevels, zoomLevel) {

			var _width = (((imageBigData.width - imageData.width)/zoomLevels) * (zoomLevel) );
			var _height = (((imageBigData.height - imageData.height)/zoomLevels) * (zoomLevel) );

			
			return {
					width:_width,
					height:_height,
					zoomLevel: zoomLevel
			};	
		}
				
	});
})(jQuery);

