/*
 * jQuery Nivo Zoom v1.0
 * http://nivozoom.dev7studios.com
 *
 * Copyright 2010, Gilbert Pellegrom
 * Free to use and abuse under the MIT license.
 * http://www.opensource.org/licenses/mit-license.php
 * 
 * April 2010
 */

(function(jQuery) {

	jQuery.fn.nivoZoom = function(options) {

		//Defaults are below
		var settings = jQuery.extend({}, jQuery.fn.nivoZoom.defaults, options);
		
		if(settings.overlay){
			//Disable overly in IE7 due to z-index bug
			if(!(jQuery.browser.msie && jQuery.browser.version.substr(0,1)<8)){
				jQuery('body').prepend('<div id="nivoOverlay" />');
				jQuery('#nivoOverlay').css({
					position:'fixed',
					top:0,
					left:0,
					width:'100%',
					height:'100%',
					background:settings.overlayColor,
					opacity:settings.overlayOpacity,
					'z-index':90,
					display:'none'
				});
			}	
		}

		return this.each(function(){
			var context = jQuery(this);
			
			var nivoZooms = jQuery('a.nivoZoom', context);
			nivoZooms.each(function(){
				var link = jQuery(this);
				if(link.is('a')){
					var img = jQuery(this).find('img:first');
					
					//Setup link
					link.css({
						position:'relative',
						display:'inline-block'
					});
					link.attr('title','Click to zoom');
					
					//Add ZoomHover
					link.append('<div class="nivoZoomHover" />');
					var nivoZoomHover = jQuery('.nivoZoomHover', link);
					nivoZoomHover.css('opacity','0');					
					link.hover(function(){
						if(!link.hasClass('zoomed')){
							nivoZoomHover.stop().animate({ opacity:settings.zoomHoverOpacity }, 300);
						}
					}, function(){
						if(!nivoZoomHover.hasClass('loading')){
							nivoZoomHover.stop().animate({ opacity:0 }, 300);
						}
					});
					
					link.bind('click', function(){
						//Check to see if large image is loaded
						if(jQuery('img.nivoLarge', link).length == 0){
							nivoZoomHover.addClass('loading');
							loadImg(img, link, function(){
								nivoZoomHover.removeClass('loading');
								doZoom(img, link, nivoZoomHover); 
							});
						} else {
							doZoom(img, link, nivoZoomHover);
						}
						return false;
					});
				}
			});
			
		});
		
		function doZoom(img, link, nivoZoomHover){
			var imgLarge = jQuery('img.nivoLarge', link);
			if(link.hasClass('zoomed')){
				//Hide Overlay
				if(settings.overlay) jQuery('#nivoOverlay').fadeOut(settings.speed/2);
				//Hide Caption
				if(jQuery('.nivoCaption', link).length > 0){
					jQuery('.nivoCaption', link).fadeOut(settings.speed/2);
				}
				//Hide Image
				imgLarge.fadeOut(settings.speed/2, function(){
					img.animate({ opacity:1 }, settings.speed/2);
				});
				link.removeClass('zoomed');
			} else {
				//Show Overlay
				if(settings.overlay) jQuery('#nivoOverlay').fadeIn(settings.speed/2);
				//Hide ZoomHover
				nivoZoomHover.css('opacity','0');
				//Show Image
				img.animate({ opacity:0 }, settings.speed/2, function(){
					imgLarge.fadeIn(settings.speed/2, function(){
						showCaption(img, imgLarge, link);
					});
				});
				link.addClass('zoomed');
			}
		}
		
		function showCaption(img, imgLarge, link){
			if(jQuery('.nivoCaption', link).length > 0){
				var nivoCaption = jQuery('.nivoCaption:first', link);
				if(!nivoCaption.hasClass('nivo-processed')){
					//Calculate the image dimensions
					var imgWidth = img.width();
					if(imgWidth == 0) imgWidth = img.attr('width');
					var imgHeight = img.height();
					if(imgHeight == 0) imgHeight = img.attr('height');
					var bigImgWidth = imgLarge.width();
					if(bigImgWidth == 0) bigImgWidth = imgLarge.attr('width');
					var bigImgHeight = imgLarge.height();
					if(bigImgHeight == 0) bigImgHeight = imgLarge.attr('height');
					nivoCaption.css({
						width:bigImgWidth,
						opacity:settings.captionOpacity
					});
					
					if(link.hasClass('topRight')){
						nivoCaption.css({
							top:(bigImgHeight - nivoCaption.outerHeight()) + 'px',
							right:'0px'
						});
					} 
					else if(link.hasClass('bottomRight')){
						nivoCaption.css({
							bottom:'0px',
							right:'0px'
						});
					}
					else if(link.hasClass('bottomLeft')){
						nivoCaption.css({
							bottom:'0px',
							left:'0px'
						});
					} 
					else if(link.hasClass('center')){
						nivoCaption.css({
							top:Math.ceil(imgHeight/2 - bigImgHeight/2) + (bigImgHeight - nivoCaption.outerHeight()) + 'px',
							left:(imgWidth/2 - bigImgWidth/2) +'px'
						});
					} else {
						nivoCaption.css({
							top:(bigImgHeight - nivoCaption.outerHeight()) + 'px',
							left:'0px'
						});
					}
					nivoCaption.addClass('nivo-processed');
				}
				nivoCaption.fadeIn(settings.speed/2);
			}
		}
		
		function loadImg(img, link, callback){
			//Load large image
			var newImg = new Image();
			jQuery(newImg).load(function (){   
				jQuery(this).addClass('nivoLarge');
				jQuery(this).css({
					position:'absolute',
					display:'none',
					'z-index':99
				});
				
				//Fix IE7 z-index bug
				if(navigator.userAgent.match(/MSIE \d\.\d+/)){
					link.css('z-index','100');
				}
				
				if(link.hasClass('topRight')){
					jQuery(this).css({
						top:'0px',
						right:'0px'
					});
				} 
				else if(link.hasClass('bottomRight')){
					jQuery(this).css({
						bottom:'0px',
						right:'0px'
					});
				}
				else if(link.hasClass('bottomLeft')){
					jQuery(this).css({
						bottom:'0px',
						left:'0px'
					});
				} 
				else if(link.hasClass('center')){
					//Calculate the image dimensions
					var imgWidth = img.width();
					if(imgWidth == 0) imgWidth = img.attr('width');
					var imgHeight = img.height();
					if(imgHeight == 0) imgHeight = img.attr('height');
					var bigImgWidth = jQuery(this).width();
					if(bigImgWidth == 0) bigImgWidth = jQuery(this).attr('width');
					var bigImgHeight = jQuery(this).height();
					if(bigImgHeight == 0) bigImgHeight = jQuery(this).attr('height');
					jQuery(this).css({
						top:(imgHeight/2 - bigImgHeight/2) +'px',
						left:(imgWidth/2 - bigImgWidth/2) +'px'
					});
				} else {
					jQuery(this).css({
						top:'0px',
						left:'0px'
					});
				}
				
				jQuery(this).attr('title','Click to close');
				link.append(jQuery(this));
				callback.call(this);
			}).attr('src', link.attr('href'));
		}
	};
	
	//Default settings
	jQuery.fn.nivoZoom.defaults = {
		speed:500,
		zoomHoverOpacity:0.8,
		overlay:false,
		overlayColor:'#333',
		overlayOpacity:0.5,
		captionOpacity:0.8
	};
		
})(jQuery);
