/**
*	@name imgPreview
*	@type jQuery plugin
*	@author James Padolsey (j@qd9.co.uk | http://james.padolsey.com)
*	@version 0.22
*	Some changes made by Kaveh Ahmadi (kavehahmadi.com) for Netsups CO. (netsups.com)
*	Copyright (c) 2009 James Padolsey
*	licensed under MIT and GPL
*	Updated: 09/02/09
**/
;(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({
			imgCSS: {},						// CSS to be applied to image
			showCaption: true,					// Show Caption?
			distanceFromCursor: {x:10, y:10},			// Distance between cursor and preview
			preloadImages: true,					// Boolean, whether or not to preload images
			onShow: function(){},				// Callback: run when link is hovered: container is shown
			onHide: function(){},					// Callback: container is hidden
			onLoad: function(){},					// Callback: Run when image within container has loaded
			containerID: 'imgPreviewContainer',			// ID to give to container (for CSS styling)
			containerLoadingClass: 'imgPreviewLoading',	// Class to be given to container while image is loading
			thumbPrefix: '',						// Prefix (if using thumbnails), e.g. 'thumb_'
			srcAttr: 'href',						// Where to retrieve the image from
			captionAttr: null
		}, userDefinedSettings);

		// Get all valid elements (linking to images / ATTR with image link):
		$collection = this.filter(':linkingToImage(' + s.srcAttr + ')');

		// 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
			.hover(function(e){
				var link = this;

				$container = $('<div/>').attr('id', s.containerID)
					.append('<img/>').hide()
					.append('<span></span').hide()
					.css('position','absolute')
					.appendTo('body'),

				$img = $('img', $container).css(s.imgCSS),
				$caption = $('span', $container),

				$container
					.addClass(s.containerLoadingClass)
					.show();
				$img
					.load(function(){
						$container.removeClass(s.containerLoadingClass);
						$img.show();
						if (s.showCaption) {
							if(s.captionAttr == null) {
								$caption.text($(link).text());
							} else {
								$caption.text($(link).attr(s.captionAttr));
							}
							$caption.show();
						}

						if(e.pageX > ($(window).width()/2)) {
							$container.css({
								top: e.pageY + s.distanceFromCursor.y + 'px',
								left: e.pageX - $container.outerWidth() - s.distanceFromCursor.x + 'px'
							});
						} else {
							$container.css({
								top: e.pageY + s.distanceFromCursor.x + 'px',
								left: e.pageX + s.distanceFromCursor.x + 'px'
							});
						}
						s.onLoad.call($img[0], link);
					})
					.attr('src' , addPrefix($(link).attr(s.srcAttr)));
				s.onShow.call($container[0], link);
			}, function() {
				$container.remove();
				s.onHide.call($container[0], this);
			})
			.mousemove(function(e) {
				$container = $('#' + s.containerID);
				if(e.pageX > ($(window).width()/2)) {
					$container.css({
						top: e.pageY + s.distanceFromCursor.y + 'px',
						left: e.pageX - $container.outerWidth() - s.distanceFromCursor.x + 'px'
					});
				} else {
					$container.css({
						top: e.pageY + s.distanceFromCursor.y + 'px',
						left: e.pageX + s.distanceFromCursor.x + 'px'
					});
				}
			})
			.click(function() {
				$('#' + s.containerID).remove();
			});
		// Return full selection, not $collection!
		return this;
	};
})(jQuery);
