/*
 * imgPreview jQuery plugin
 * Copyright (c) 2009 James Padolsey
 * j@qd9.co.uk | http://james.padolsey.com
 * Dual licensed under MIT and GPL.
 * Updated: 09/02/09
 * @author James Padolsey
 * @version 0.22
 */
(function($){
	
	$.expr[':'].linkingToImage = function(elem, index, match){
		// This will return true if the specified attribute contains a valid link to an image:
		return !! ($(elem).attr(match[3]) && $(elem).attr(match[3]).match(/\.(gif|jpe?g|png|bmp)$/i));
	};
	
	$.fn.imgPreview = function(userDefinedSettings){
		
		var s = $.extend({
			
			/* DEFAULTS */
			unload : false,
			// CSS to be applied to image:
			imgCSS: {},
			// Distance between cursor and preview:
			distanceFromCursor: {top:10, left:10},
			// Boolean, whether or not to preload images:
			preloadImages: true,
			// Callback: run when link is hovered: container is shown:
			onShow: function(){},
			// Callback: container is hidden:
			onHide: function(){},
			// Callback: Run when image within container has loaded:
			onLoad: function(){},
			// ID to give to container (for CSS styling):
			containerID: 'imgPreviewContainer',
			// Class to be given to container while image is loading:
			containerLoadingClass: 'loading',
			// Prefix (if using thumbnails), e.g. 'thumb_'
			thumbPrefix: '',
			// Where to retrieve the image from:
			srcAttr: 'href'
			
		}, userDefinedSettings),
		
		$container = $('<div/>').attr('id', s.containerID)
						.append('<img/>').hide()
						.css('position','absolute')
						.appendTo('body'),
			
		$img = $('img', $container).css(s.imgCSS),
		
		// Get all valid elements (linking to images / ATTR with image link):
		$collection = this.filter(':linkingToImage(' + s.srcAttr + ')');

		if (s.unload || !$collection.length) 
		{
			$collection.unbind('mousemove').unbind('hover');
			return this;
		}

		// Re-usable means to add prefix (from setting):
		function addPrefix(src) {
			return src.replace(/(\/?)([^\/]+)$/,'$1' + s.thumbPrefix + '$2');
		}
		
		if (s.preloadImages) {
			(function(i){
				var tempIMG = new Image(),
					callee = arguments.callee;
				tempIMG.src = addPrefix($($collection[i]).attr(s.srcAttr));
				tempIMG.onload = function(){
					$collection[i + 1] && callee(i + 1);
				};
			})(0);
		}

		$collection
			.mousemove(function(e){
				var wh = $(window).height(),wndscTop = $('html').scrollTop() ;
				var poxY=0;
				
				if (wh +wndscTop - s.imgCSS.height-s.distanceFromCursor.top<e.pageY) posY = wh+wndscTop-s.imgCSS.height;
				else posY = e.pageY + s.distanceFromCursor.top;
				
				$container.css({
					top: posY + 'px' ,
					left: e.pageX + s.distanceFromCursor.left + 'px'
				});
				
			})
			.hover(function(){
				
				var link = this;
				$container
					.addClass(s.containerLoadingClass)
					.show();
				$img
					.load(function(){
						$container.removeClass(s.containerLoadingClass);
						$img.show();
						s.onLoad.call($img[0], link);
					})
					.attr( 'src' , addPrefix($(link).attr(s.srcAttr)) );
				s.onShow.call($container[0], link);
				
			}, function(){
				
				$container.hide();
				$img.unbind('load').attr('src','').hide();
				s.onHide.call($container[0], this);
				
			});
		
		// Return full selection, not $collection!
		return this;
		
	};
	
})(jQuery);
