function calculatePosition(options) {
	var position = {
			x : 0,
			y : 0
		},
		right  = options.window.width - (options.client.x + options.offset.x),
		bottom = options.window.height - (options.client.y + options.offset.y),
		top    = options.client.y + options.offset.y;			

		
	//Position Left
	if ( right > options.image.width ) {
		//right
		position.x = options.page.x + options.offset.x;
	} else { 
		//left
		position.x = options.page.x - (options.image.width + options.offset.x);
	}
					
	//Position Top
	if ( top < options.image.height && bottom < options.image.height ) {
		//Middle
		position.y = options.page.y - (options.image.height / 2 + options.offset.y);
	} else if ( bottom > options.image.height) {
		//bottom
		position.y = options.page.y - options.offset.y;
	} else {
		//top
		position.y = options.page.y - (options.image.height + options.offset.y);
	}
	
	return position; 
}

jQuery(document).ready(function ( $ ) {
	
	jQuery.fn.hoverImage = function( options ) {
	
		var settings = $.extend( {
		  'imageId'  		 : 'imageElement',
		  'imageAttribute' 	 : 'data-image',
		  'captionAttribute' : 'title',
		  'xOffset'			 : 30,
		  'yOffset'			 : 30
		}, options);
		
		//Get the window height(windowHeight) and width (windowWidth)
		var w=window,d=document,e=d.documentElement,g=d.getElementsByTagName('body')[0],windowWidth=w.innerWidth||e.clientWidth||g.clientWidth,windowHeight=w.innerHeight||e.clientHeight||g.clientHeight;
	
		var positionOptions = {
			window : {
				width : windowWidth,
				height : windowHeight
			},
			client : {
				x : 0,
				y : 0
			},
			page : {
				x : 0,
				y : 0
			},
			offset : { 
				x : settings.xOffset,
				y : settings.yOffset
			},
			image : {
				width : 0,
				height : 0
			}
		};
	
		return this.each( function() {
			var $this = $(this);
			
			$this.mouseenter( function( event ) {
				var img = new Image();
				var loaded = false;	
				
				$("body").append(img);
							
				$(img).attr( {
					id	: settings.imageId,
					src	: $this.attr(settings.imageAttribute)					
				});

				
				if ($(img)[0].complete) {
					$.extend( positionOptions, {
						image : {
							width : $(img).width(),
							height : $(img).height()
						},
						client : {
							x : event.clientX,
							y : event.clientY
						},
						page : {
							x : event.pageX,
							y : event.pageY
						}
					});
									
					var position = calculatePosition(positionOptions);

					$("#" + settings.imageId).css({
						'top' : position.y + "px",
						'left' : position.x + "px"
					}).fadeIn("slow");
				
				} else {
				
					$(img).load(function( event ) {
					  $.extend( positionOptions, {
						image : {
							width : this.width,
							height : this.height
						},
						client : {
							x : event.clientX,
							y : event.clientY
						},
						page : {
							x : event.pageX,
							y : event.pageY
						}
					});
									
					var position = calculatePosition(positionOptions);

					$("#" + settings.imageId).css({
						'top' : position.y + "px",
						'left' : position.x + "px"
					}).fadeIn("slow");
				
					});
				}
				
				
			}).mouseleave( function() {	
			
				$("#" + settings.imageId).remove();
				
			}).mousemove(function( event ){				
				$.extend( positionOptions, {
					client : {
						x : event.clientX,
						y : event.clientY
					},
					page : {
						x : event.pageX,
						y : event.pageY
					}
				} );					
									
				var position = calculatePosition(positionOptions);

				$("#" + settings.imageId).css({
					'top' : position.y + "px",
					'left' : position.x + "px"
				});			
			});
		});
	};
});
