(function() {  
	
    jQuery.fn.jZoom = function(settings) {  

        settings = jQuery.extend({
			shadow: true,				/* Display shadow */
			margin: 80,					/* Min-margin between image and screen border, in pixel. If shadow is true, you should have a margin of 80px at least */
			duration: 260,				/* Animation duration, in milliseconds */
			images_dir: 'images/jzoom/',		/* Images directory - absolute or relative path */
			opacity: 0				/* Begin the animation with that opacity */
        }, settings);

		var css_image_id = 'jZoom_image';

		var window_width, window_height, screen_offset_top, screen_offset_left;
		var thumb_width, thumb_height, thumb_top, thumb_left;
		var image_width, image_height, image_top, image_left;
		
		var object_a;	/* a object that was just clicked */
		
		var spinner_frame = 12;
		
		
		// #########################
		// Images preload
		// #########################

		var imgCloseBox = new Image();
		$(imgCloseBox).attr('src', settings['images_dir'] + 'close.png');

		var imgSpinner = new Image();
		$(imgSpinner).attr('src', settings['images_dir'] + 'spinner.png');

		if (settings['shadow']) {
			var imgShadow1 = new Image();
			imgShadow1.src = settings['images_dir'] + 'shadow-1.png';
			var imgShadow2 = new Image();
			imgShadow2.src = settings['images_dir'] + 'shadow-2.png';
			var imgShadow3 = new Image();
			imgShadow3.src = settings['images_dir'] + 'shadow-3.png';
			var imgShadow4 = new Image();
			imgShadow4.src = settings['images_dir'] + 'shadow-4.png';
			var imgShadow5 = new Image();
			imgShadow5.src = settings['images_dir'] + 'shadow-5.png';
			var imgShadow6 = new Image();
			imgShadow6.src = settings['images_dir'] + 'shadow-6.png';
			var imgShadow7 = new Image();
			imgShadow7.src = settings['images_dir'] + 'shadow-7.png';
			var imgShadow8 = new Image();
			imgShadow8.src = settings['images_dir'] + 'shadow-8.png';
		}
		
		this.click(function() {

			object_a = this;
			
			if (document.getElementById(css_image_id)) {
				unzoom(true);
			}
			
			else {
				loadImage();
			}
						
			return false;
			
		});
		
		function loadImage() {
			
			var href = $(object_a).attr('href');

			var img = document.createElement('img');
			
			$(img).attr('src', href);
			$(img).attr('id', css_image_id);
			$(img).css('opacity', settings['opacity']);
			$(img).css('position', 'absolute');
			$(img).css('display', 'none');

			$(img).appendTo("body")
		
			
			var imgIsLoaded = new Image();
			$(imgIsLoaded).attr('src', href);
			
			if (imgIsLoaded.complete) {
				saveSizesAndPositions();
				zoomEffect();
			}
			
			else {
				saveSizesAndPositions();
				loadSpinner();
				img.onload = function() { /* Once the image is loaded, launch functions */
					removeSpinner();
					saveSizesAndPositions();
					zoomEffect();
				};
			}
			
		}
		
		function saveSizesAndPositions() {
		
			/* Save the screen's width & height */
			if (parseInt(navigator.appVersion)>3) {
				if (navigator.appName.indexOf("Microsoft")!=-1) {
					window_width = document.documentElement.clientWidth;
					window_height = document.documentElement. clientHeight;
				}
				else {
					window_width = window.innerWidth;
			  		window_height = window.innerHeight;
				}
			}
			
			/* Save the screen's width & height 
			window_width = $(window).width();
			window_height = $(window).height();*/
			
			screen_offset_top = $(window).scrollTop();
			screen_offset_left = $(window).scrollLeft();
			
			var thumb = object_a.firstChild;
			
			/* Save the thumb's width, height, top & left position */
			var thumb_position = $(thumb).offset({ scroll: false });
			thumb_top = parseInt(thumb_position['top']);
			thumb_left = parseInt(thumb_position['left']);
			thumb_width = parseInt($(thumb).width());
			thumb_height = parseInt($(thumb).height());
			
			/* We save the image's width and height */
			image_width = parseInt($('#'+css_image_id).width());
			image_height = parseInt($('#'+css_image_id).height());
			
			/* If the image's width is too big, we resize the image to the max width */
			if (image_width + settings['margin'] * 2 > window_width) {
				var max_width = parseInt(window_width - settings['margin'] * 2);
				image_height = parseInt(image_height / image_width * max_width);
				image_width = parseInt(max_width);
			}
			
			/* If the image's height is too big, we resize the image to the max height */
			if (image_height + settings['margin'] * 2 > window_height) {
				var max_height = parseInt(window_height - settings['margin'] * 2);
				image_width = parseInt(image_width / image_height * max_height);
				image_height = parseInt(max_height);
			}
			
			/* We define the image's top and left positions */
			image_top = parseInt(screen_offset_top + (window_height - image_height) / 2);
			image_left = parseInt(screen_offset_left + (window_width - image_width) / 2);

		}
				
		function zoomEffect() {
		
			$('#'+css_image_id).css('top', thumb_top + 'px');
			$('#'+css_image_id).css('left', thumb_left + 'px');
			
			$('#'+css_image_id).css('width', thumb_width + 'px');
			$('#'+css_image_id).css('height', thumb_height + 'px');
			$('#'+css_image_id).css('dipslay', 'block');
			
			$('#'+css_image_id).animate({ 
				width: image_width+'px',
				height: image_height+'px',
				top: image_top+'px',
				left: image_left+'px',
				opacity: '1'
			}, settings['duration'], function() {
				loadFinalElements();		// Callback function loading shadow and closebox
			} );
			
		}
		
		function loadFinalElements() {
			
			if (settings['shadow']) {	/* If shadow option is true */
				
				var oShadow1 = document.createElement('div');	/* corner bottom left */
				oShadow1.style.background = 'url(' + settings['images_dir'] + 'shadow-1.png)';
				oShadow1.id = 'jZoom_shadow1';
				oShadow1.style.position = 'absolute';
				oShadow1.style.display = 'none';
				oShadow1.style.width = '135px';
				oShadow1.style.height = '135px';
				oShadow1.style.top = (image_top - 59) + 'px';
				oShadow1.style.left = (image_left - 65	) + 'px';
				if ($.browser.msie && parseInt(jQuery.browser.version) < 7) {
					oShadow1.style.background = 'url(' + settings['images_dir'] + 'blank.gif)';
					oShadow1.style.filter = 'progid:DXImageTransform.Microsoft.AlphaImageLoader(src="' + settings['images_dir'] + 'shadow-1.png", sizingMethod="scale")';
				}
				document.body.appendChild(oShadow1);
			
				var oShadow2 = document.createElement('div');	/* top */
				oShadow2.style.background = 'url(' + settings['images_dir'] + 'shadow-2.png)';
				oShadow2.id = 'jZoom_shadow2';
				oShadow2.style.position = 'absolute';
				oShadow2.style.display = 'none';
				oShadow2.style.width = (image_width - 140) + 'px';
				oShadow2.style.height = '59px';
				oShadow2.style.top = (image_top - 59) + 'px';
				oShadow2.style.left = (image_left + 70) + 'px';
				if ($.browser.msie && parseInt(jQuery.browser.version) < 7) {
					oShadow2.style.background = 'url(' + settings['images_dir'] + 'blank.gif)';
					oShadow2.style.filter = 'progid:DXImageTransform.Microsoft.AlphaImageLoader(src="' + settings['images_dir'] + 'shadow-2.png", sizingMethod="scale")';
				}
				document.body.appendChild(oShadow2);
			
				var oShadow3 = document.createElement('div');	/* corner top right */
				oShadow3.style.background = 'url(' + settings['images_dir'] + 'shadow-3.png)';
				oShadow3.id = 'jZoom_shadow3';
				oShadow3.style.position = 'absolute';
				oShadow3.style.display = 'none';
				oShadow3.style.width = '135px';
				oShadow3.style.height = '135px';
				oShadow3.style.top = (image_top - 59) + 'px';
				oShadow3.style.left = (image_left + image_width - 70) + 'px';
				if ($.browser.msie && parseInt(jQuery.browser.version) < 7) {
					oShadow3.style.background = 'url(' + settings['images_dir'] + 'blank.gif)';
					oShadow3.style.filter = 'progid:DXImageTransform.Microsoft.AlphaImageLoader(src="' + settings['images_dir'] + 'shadow-3.png", sizingMethod="scale")';
				}
				document.body.appendChild(oShadow3);
			
				var oShadow4 = document.createElement('div');	/* right */
				oShadow4.style.background = 'url(' + settings['images_dir'] + 'shadow-4.png)';
				oShadow4.id = 'jZoom_shadow4';
				oShadow4.style.position = 'absolute';
				oShadow4.style.display = 'none';
				oShadow4.style.width = '65px';
				oShadow4.style.height = (image_height - 147) + 'px';
				oShadow4.style.top = (image_top + 76) + 'px';
				oShadow4.style.left = (image_left + image_width) + 'px';
				if ($.browser.msie && parseInt(jQuery.browser.version) < 7) {
					oShadow4.style.background = 'url(' + settings['images_dir'] + 'blank.gif)';
					oShadow4.style.filter = 'progid:DXImageTransform.Microsoft.AlphaImageLoader(src="' + settings['images_dir'] + 'shadow-4.png", sizingMethod="scale")';
				}
				document.body.appendChild(oShadow4);
			
				var oShadow5 = document.createElement('div');	/* corner bottom right */
				oShadow5.style.background = 'url(' + settings['images_dir'] + 'shadow-5.png)';
				oShadow5.id = 'jZoom_shadow5';
				oShadow5.style.position = 'absolute';
				oShadow5.style.display = 'none';
				oShadow5.style.width = '135px';
				oShadow5.style.height = '135px';
				oShadow5.style.top = (image_top + image_height - 71) + 'px';
				oShadow5.style.left = (image_left + image_width - 70) + 'px';
				if ($.browser.msie && parseInt(jQuery.browser.version) < 7) {
					oShadow5.style.background = 'url(' + settings['images_dir'] + 'blank.gif)';
					oShadow5.style.filter = 'progid:DXImageTransform.Microsoft.AlphaImageLoader(src="' + settings['images_dir'] + 'shadow-5.png", sizingMethod="scale")';
				}
				document.body.appendChild(oShadow5);
			
				var oShadow6 = document.createElement('div');	/* bottom */
				oShadow6.style.background = 'url(' + settings['images_dir'] + 'shadow-6.png)';
				oShadow6.id = 'jZoom_shadow6';
				oShadow6.style.position = 'absolute';
				oShadow6.style.display = 'none';
				oShadow6.style.width = (image_width - 140) + 'px';
				oShadow6.style.height = '64px';
				oShadow6.style.top = (image_top + image_height) + 'px';
				oShadow6.style.left = (image_left + 70) + 'px';
				if ($.browser.msie && parseInt(jQuery.browser.version) < 7) {
					oShadow6.style.background = 'url(' + settings['images_dir'] + 'blank.gif)';
					oShadow6.style.filter = 'progid:DXImageTransform.Microsoft.AlphaImageLoader(src="' + settings['images_dir'] + 'shadow-6.png", sizingMethod="scale")';
				}
				document.body.appendChild(oShadow6);
			
				var oShadow7 = document.createElement('div');	/* corner bottom left */
				oShadow7.style.background = 'url(' + settings['images_dir'] + 'shadow-7.png)';
				oShadow7.id = 'jZoom_shadow7';
				oShadow7.style.position = 'absolute';
				oShadow7.style.display = 'none';
				oShadow7.style.width = '135px';
				oShadow7.style.height = '135px';
				oShadow7.style.top = (image_top + image_height - 71) + 'px';
				oShadow7.style.left = (image_left - 65	) + 'px';
				if ($.browser.msie && parseInt(jQuery.browser.version) < 7) {
					oShadow7.style.background = 'url(' + settings['images_dir'] + 'blank.gif)';
					oShadow7.style.filter = 'progid:DXImageTransform.Microsoft.AlphaImageLoader(src="' + settings['images_dir'] + 'shadow-7.png", sizingMethod="scale")';
				}
				document.body.appendChild(oShadow7);
			
				var oShadow8 = document.createElement('div');	/* left */
				oShadow8.style.background = 'url(' + settings['images_dir'] + 'shadow-8.png)';
				oShadow8.id = 'jZoom_shadow8';
				oShadow8.style.position = 'absolute';
				oShadow8.style.display = 'none';
				oShadow8.style.width = '65px';
				oShadow8.style.height = (image_height - 147) + 'px';
				oShadow8.style.top = (image_top + 76) + 'px';
				oShadow8.style.left = (image_left - 65) + 'px';
				if ($.browser.msie && parseInt(jQuery.browser.version) < 7) {
					oShadow8.style.background = 'url(' + settings['images_dir'] + 'blank.gif)';
					oShadow8.style.filter = 'progid:DXImageTransform.Microsoft.AlphaImageLoader(src="' + settings['images_dir'] + 'shadow-8.png", sizingMethod="scale")';
				}
				document.body.appendChild(oShadow8);
				
				if ($.browser.msie) {
					$('#jZoom_shadow1, #jZoom_shadow2, #jZoom_shadow3, #jZoom_shadow4, #jZoom_shadow5, #jZoom_shadow6, #jZoom_shadow7, #jZoom_shadow8').show();
				}
				else {
					$('#jZoom_shadow1, #jZoom_shadow2, #jZoom_shadow3, #jZoom_shadow4, #jZoom_shadow5, #jZoom_shadow6, #jZoom_shadow7, #jZoom_shadow8').fadeIn('fast');
				}
				
			}
			
			var oCloseBox = document.createElement('div');
			oCloseBox.style.background = 'url(' +settings['images_dir'] + 'close.png)';
			oCloseBox.id = 'jZoom_closebox';
			oCloseBox.style.position = 'absolute';
			oCloseBox.style.display = 'none';
			oCloseBox.style.width = '28px';
			oCloseBox.style.height = '28px';
			oCloseBox.style.top = (image_top - 13) + 'px';
			oCloseBox.style.left = (image_left - 13) + 'px';
			if ($.browser.msie && parseInt(jQuery.browser.version) < 7) {
				oCloseBox.style.background = 'url(' + settings['images_dir'] + 'blank.gif)';
				oCloseBox.style.filter = 'progid:DXImageTransform.Microsoft.AlphaImageLoader(src="' + settings['images_dir'] + 'close.png", sizingMethod="scale")';
			}
			document.body.appendChild(oCloseBox);
			
			
			$('#'+css_image_id+', #'+'jZoom_closebox').css('cursor','pointer');
			
			$('#'+css_image_id+', #'+'jZoom_closebox').click(function() {
				unzoom();
			});
			
			if ($.browser.msie) {
				$('#jZoom_closebox').show();
			}
			else {
				$('#jZoom_closebox').fadeIn('fast');
			}
			
		}
		
		function unzoom(zoomBack) {
			
			$('#jZoom_closebox').remove();		// Remove closebox
			
			if (settings['shadow']) {		// Remove shadows box
				$('#jZoom_shadow1, #jZoom_shadow2, #jZoom_shadow3, #jZoom_shadow4, #jZoom_shadow5, #jZoom_shadow6, #jZoom_shadow7, #jZoom_shadow8').remove();
			}
			
			$('#'+css_image_id).animate({ 
				width: thumb_width + 'px',
				height: thumb_height + 'px',
				top: thumb_top + 'px',
				left: thumb_left + 'px',
				opacity: settings['opacity']
			}, settings['duration'], function() {
				//Callback
				document.body.removeChild(document.getElementById(css_image_id));

				if (zoomBack) {
					loadImage();
				}
				
			});
			
		}
		
		function loadSpinner() {
			
			var spinner = document.createElement('div');
			spinner.style.background = 'url(' + settings['images_dir'] + 'spinner.png)';
			spinner.id = 'jZoom_spinner';
			spinner.style.position = 'absolute';
			spinner.style.top = (thumb_top + (thumb_height / 2) - 15) + 'px';
			spinner.style.left = (thumb_left + (thumb_width / 2) - 15) + 'px';
			spinner.style.width = '30px';
			spinner.style.height = '30px';
			
			document.body.appendChild(spinner);	
			
			animeSpinner();
			
		}

		function animeSpinner() {
			
			if (document.getElementById('jZoom_spinner')) {
				
				if (spinner_frame > 1) {
					$('#jZoom_spinner').css('backgroundPosition','0px '+spinner_frame*30+'px');
					spinner_frame--;
				}
				
				else {
					$('#jZoom_spinner').css('backgroundPosition','0px 0px');
					spinner_frame = 12;
				}
				
				setTimeout(function() { animeSpinner(); }, 60);
				
			}
		}
		
		function removeSpinner() {
			if (document.getElementById('jZoom_spinner')) {
				document.body.removeChild(document.getElementById('jZoom_spinner'));
			}
		}
  
    };  
  
})(jQuery);
