/*
 * Paris Air Product Zoom jQuery Plugin 1.0
 * Based on code from Renzi Marco's JQZoom Evolution 1.0.1
 *
 * Copyright (c) 2010 Greg Kuwaye (gregkuwaye.com)
 *
 * Released under GPL. Modify this code as you like!
 *
 */

(function($)
{	
    $.fn.productzoom = function(options)
    {
        var settings = {
			'loader': '#pz-loading',
			'loadingMessage': 'Loading image...',
			'enableZoomMessage': 'Click to enable zoom',
			'disableZoomMessage': 'Click to disable zoom',
			'loadingZoomMessage': 'Loading zoom...',
			'errorLoadingMessage': '',
			'lensHorizMargin': 140,
			'lensVertMargin': 120
		}
		
		// Extend options
		options = options || {};
		$.extend( settings, options );
		
		return this.each( function()
		{
			
			var isZoomOn = false; 				// Are we in zoom mode?
			var isDblClickRunning = false;		// Has a double click been issued?
			var isHovering = false;
			var isLoading = false;				// Are we loading a zoom image?
			
			var c = $(this); 					// Let c = the containing div elt
			var a =	c.find('A');				// Let a = the A wrapper
			var i = c.find('IMG');				// Let i = the IMG
			// TODO: make this dynamic
			var tClass = '.thumb';
			
			var smallImgSrc = i.attr( 'src' );	// Hold the original image src for swapping
			
			var mousepos = {};					// Mouse position
			var img = {};						// Scaled image position
			
			var cPos = c.offset();			// Absolute position: {left: #, top: #}
			
			// Binding for image hover, double clicking
			a
			.hover(
				function(e){
					isHovering = true;
					mousepos.x = e.pageX;
					mousepos.y	= e.pageY;
					if (!isZoomOn)
						showLoading( settings.enableZoomMessage );
					activate();
				},
				function()
				{
					isHovering = false;
					/* This catches the case where user mouses out before zoom load is finished
					   We want to keep loading the image even if the user mouses out */
					if (!isLoading)
					{
						deactivate();
						hideLoading();
						//if (isZoomOn) a.click(); // trigger zoom out
					}
				}
			)
			.bind( 'click',
				function(e)
				{
					// Only run if a current dbl click operation is running
					if( !isDblClickRunning )
					{
						isDblClickRunning = true;
						if( isZoomOn )
						{
							isZoomOn = false;
							deactivate();
							i.attr( 'src', smallImgSrc );
							isDblClickRunning = false;
						}
						else
						{
							// Potential problem spot. Need to set this to true first
							// so that activate() does its thing
							isZoomOn = true;
							isLoading = true;
							
							showLoading( settings.loadingZoomMessage );
							
							// Preload the image
							var img = new Image();
							// once it's loaded, execute code
							$(img)
							.load( function(){
								hideLoading();
								if (isHovering) // Is the cursor still within the image?
								{
									i.attr( 'src', a.attr( 'href' ));  // Set IMG src to A href
									activate(e);
								}
								// User has already "moused out", so update zoom mode to "false"
								else
								{
									isZoomOn = false;
								}
								isLoading = false;
							})
							.error( function(){
								hideLoading();
								alert( settings.errorLoadingMessage );
							})
							.attr( 'src', a.attr( 'href' )); // Preload image object with A href
							
							isDblClickRunning = false;
						}
					}
					return false;
				}
			);
			
			// Binding for thumbnail change
			$( tClass ).each( function()
				{
					$(this)
					.bind( 'click', function(e)
						{
							// Store some useful variables
							var newSmallImgSrc = $(this).attr( 'href' );
							var newBigImgSrc = newSmallImgSrc.replace('-extra-large','');

							// Switch image only if different thumbnail clicked
							if ( smallImgSrc != newSmallImgSrc )
							{
								showLoading();
								
								var img = new Image();
								$(img)
								.load( function(){
									hideLoading();
									a.attr( 'href', newBigImgSrc );		// Change the image link
									i.attr( 'src', newSmallImgSrc );  	// Change the image src
									smallImgSrc = newSmallImgSrc; 		// Update smallImgSrc
									isZoomOn = false;					// Turn zoom off BEFORE deactivating
									deactivate();						// Deactivate
									//img = {x: 0, y: 0};				// Reset position of image to 0,0
								})
								.error( function(){
									hideLoading();
									alert( settings.errorLoadingMessage );
								})
								.attr( 'src', newSmallImgSrc ); // Preload image object with A href
								
							}
							return false;
						}
					);
				}
			);
			
			/*
			 * function: activate
			 */
			 
			function activate(e)
			{
				if ( isZoomOn )
				{
					mouseMove(e); // Call once to "set" position after dblclick
					a.css({
						'cursor': 'crosshair'
					});
					a.bind( 'mousemove', mouseMove );
					//showLoading( settings.disableZoomMessage );
				}
			}
			
			function deactivate()
			{
				if ( !isZoomOn )
				{
					if (isHovering)
						showLoading( settings.enableZoomMessage );
					a.css( 'cursor', 'pointer' );
					a.unbind( 'mousemove', mouseMove );
					i.css({
						'left': 0,
						'top': 0
					});
				}
			}
			
			function mouseMove(e)
			{
				mousepos.x = e.pageX - cPos.left;
				mousepos.y = e.pageY - cPos.top;
				
				// "Globalize" these options later
				var windowWidth = 680;
				var windowHeight = 452;
				var fullImgWidth = ( i.width() != '' ) ? i.width() : 1360;
				var fullImgHeight = ( i.height() != '' ) ? i.height() : 904;
				
				// X position
				if (mousepos.x <= settings.lensHorizMargin)
					img.x = 0;
				else if (mousepos.x > settings.lensHorizMargin && mousepos.x <= windowWidth - settings.lensHorizMargin)
					img.x = -1 * (fullImgWidth - windowWidth) * (mousepos.x - settings.lensHorizMargin) / (windowWidth - (2 * settings.lensHorizMargin));
				else
					img.x = -1 * (fullImgWidth - windowWidth);
					
				// Y position
				if (mousepos.y <= settings.lensVertMargin)
					img.y = 0;
				else if (mousepos.y > settings.lensVertMargin && mousepos.y <= windowHeight - settings.lensVertMargin)
					img.y = -1 * (fullImgHeight - windowHeight) * (mousepos.y - settings.lensVertMargin) / (windowHeight - (2 * settings.lensVertMargin));
				else
					img.y = -1 * (fullImgHeight - windowHeight);
				
				i.css({
					'left': img.x,
					'top': img.y
				});
			}
			
			function showLoading( message )
			{
				// Do we have a message to show?
				var message = (message == undefined) ? settings.loadingMessage : message;

				$(settings.loader)
				.show()
				.html( message );
			}
			
			function hideLoading()
			{
				$(settings.loader).hide();
			}
			
		});
		
	}
	
})(jQuery);
