;(function($){
	
	$.fn.fancyZoom = function(options){

		// Pass options into the plugin, using the defaults if no options have been passed in the function call
		var options = $.extend( {}, $.fn.fancyZoom.defaultOptions, options );
		
		// If zooming is in progress, dont't react to a click or the esc key
		var zooming = false;
		
		return this.each( function() {	
			
			// Close zoom box alos when escape key is pressed
			$(document).keyup( function( e ){
				if( e.keyCode == 27 && $('#zoom:visible').length > 0 ) {
					closeBox( e );
				}
			});
			
			// ...or when user clicks on the close icon
			$('#zoom_close').click( closeBox );
			
			// attach the plugin function to each found element
			$(this).each( function() {
				$(this).bind( 'click', loadImage );
			});
			
			
			function loadImage( e ) {
				if( zooming === true ) return false;
				e.preventDefault();
				zooming = true;
				
				var loading_img = '<div class="loading_img">'
						+ '<img src="images/loading.gif" border="0" alt="loading" />'
						+ '</div>';
				$('body').append( loading_img );
				$('.loading_img').css( {
						position : 'absolute', 
						width : '16px',
						height : '16px',
						display: 'block', 
						zIndex : 9999999999
					} );
				$(document).mousemove( function( e ) {
					$('.loading_img').css({
						top: ( e.pageY - 20 ) + 'px', 
						left : ( e.pageX - 20 ) + 'px'
					});
				});
					
				// Create an img element to get its real size
				// Get the path of the large image from the link's href
				var large_img = new Image();
				var img_src = $(this).attr('href');

				$(large_img)
					.load( function() {
						var pic_real_width = this.width;
						var pic_real_height = this.height;
						
						$('#zoom_content').html( '<img src="' + img_src + '" border="0" alt="" />' );
						
						if( pic_real_width > 0 && pic_real_height > 0 ) {
							var img_dimensions = {
									width : $(this).width(),
									height : $(this).height()
							};
							$('.loading_img').remove();
							startZoom( e, img_dimensions );
						}
						else {
							$(this).removeAttr('src');
							setTimeout( function() {
								$(large_img).attr('src', img_src );
							}, 100 );
						};
					})
					.attr('src', img_src );
			};
			
			
			function startZoom( e, img_dimensions ) {
				// Calculate the screen size to animate the zoom box into the center
				// $(window).width() dows not work here, because the result deviates.
				var win_width = window.innerWidth || (window.document.documentElement.clientWidth || window.document.body.clientWidth);
				var win_height = window.innerHeight || (window.document.documentElement.clientHeight || window.document.body.clientHeight);
				var win_x = window.pageXOffset || (window.document.documentElement.scrollLeft || window.document.body.scrollLeft);
				var win_y = window.pageYOffset || (window.document.documentElement.scrollTop || window.document.body.scrollTop);
				var window_size = {'width' : win_width, 'height' : win_height, 'x' : win_x, 'y' : win_y };
				
				// Width of the zoom box
				var box_width = ( img_dimensions.width > 0 ) ? img_dimensions.width : options.width;
				var box_height = ( img_dimensions.height > 0 ) ? img_dimensions.height : options.height;
				
				// ensure that newTop is at least 0 so it doesn't hide close button
				var newTop = Math.max( ( window_size.height / 2 ) - ( box_height / 2 ) + win_y, 0 );
				var newLeft = ( window_size.width / 2 ) - ( box_width / 2 );
				
				// This is our starting point (the mouse click coordinates)!
				var curTop = e.pageY;
				var curLeft = e.pageX;
				// Save this point to the zoom conatiner, so we can zoom back to that point 
				// in the closeBox function
				$('#zoom').attr( 'curTop', curTop );
				$('#zoom').attr( 'curLeft', curLeft );
				
				// Hide the "close icon
				$('#zoom_close').hide();

				if( options.closeOnClick ) {
					$('#zoom').bind( 'click', closeBox );
				}
				
				// Position the zoom container on the page and hide it
				$('#zoom').hide().css({
					zIndex : 9999999, 
					position : 'absolute',
					top : curTop + 'px',
					left : curLeft + 'px',
					width : '1px',
					height : '1px',
					opacity : 0
				}).animate({
					top : newTop + 'px',
					left : newLeft + 'px',
					opacity : 1,
					width : box_width + 'px',
					height : box_height + 'px'
					}, 500, null, function() {
						$('#zoom_close').fadeIn('fast');
						zooming = false;
				});
				//return false;			
			}; // end startZoom
			
			
			function closeBox( e ) {
				if( zooming === true ) return false;
				e.preventDefault();
				zooming = true;
				
				$('#zoom_close').hide();
				
				$('#zoom')
					.unbind('click')
					.animate({
						top : $('#zoom').attr('curTop') + 'px',
						left : $('#zoom').attr('curLeft') + 'px',
						opacity : 0,
						width : '1px',
						height : '1px'
					}, 500, null, function() {
						$('#zoom').hide();
						zooming = false;
					}
				);
				//return false;
			}; // end closeBox
			
		}); // end return each

	}; // end plugin main function
	
	// Define default settings if no options are passed via the function call
	$.fn.fancyZoom.defaultOptions = {
			width : 800,
			height : 600,
			closeOnClick : true,
			useEscKey : true
	};
	
})(jQuery);