--- hover_preview.js	2010-05-16 20:41:40.482260075 -0700
+++ hover_preview.js.new	2010-05-16 20:41:22.621593468 -0700
@@ -11,31 +11,72 @@
 Drupal.behaviors.HoverPreview = function (context) {
   /* CONFIG */
     
-    xOffset = 10;
-    yOffset = 30;
-    
-    // these 2 variable determine popup's distance from the cursor
-    // you might want to adjust to get the right result
+  xOffset = 25;
+  yOffset = -15;
+  hoverMultiply = 2.24; // how much larger the hovered image is in comparison to the original
+  bottomGuard = 50; // how far to come up from the bottom of the viewport
+  topGuard = 60; // how much space is needed at the top of the viewport
+  rightGuard = xOffset + 20; // experiment to find the proper value. include hover box padding and border size
+  leftGuard = 20;
+
+  // these 2 variable determine popup's distance from the cursor
+  // you might want to adjust to get the right result
     
   /* END CONFIG */
   $("img.hover-preview").hover(function(e){
     this.t = this.title;
     this.title = "";  
-    var c = (this.t != "") ? "<br/>" + this.t : "";
-    var preview_link = $('#' + this.id + '-url')[0];
-    $("body").append("<p id='hover-preview'><img src='"+ preview_link.href +"' alt='Loading Image Preview' />"+ c +"</p>");                
-    $("#hover-preview")
-      .css("top",(e.pageY - xOffset) + "px")
-      .css("left",(e.pageX + yOffset) + "px")
-      .fadeIn("fast");            
-    },
+
+    var windowBottom = $(window).scrollTop() + $(window).height();
+    var imgPos = $(this).offset();
+    var hoverHeight = $(this).height() * hoverMultiply;
+    var hoverWidth = $(this).width() * hoverMultiply;
+
+    /* scale the image if it's too big for the window */
+    hoverScaleY = ($(window).height() - topGuard - bottomGuard) / hoverHeight;
+    hoverScaleX = ($(window).width() -leftGuard - rightGuard) / hoverWidth;
+
+    imageScale = hoverScaleY < hoverScaleX ? hoverScaleY : hoverScaleX;
+
+    if(imageScale < 1) {
+      hoverHeight = hoverHeight * imageScale;
+      hoverWidth = hoverWidth * imageScale;
+    }
+
+    /* check to make sure the bottom of the hovered image will show up above the fold */
+
+    if(imgPos.top + hoverHeight + bottomGuard >= windowBottom){
+      hoverY = windowBottom - hoverHeight - bottomGuard;
+    } else {
+      hoverY = imgPos.top;
+    }
+
+    if(hoverY <= $(window).scrollTop()) {
+      hoverY = $(window).scrollTop() + topGuard;
+    }
+
+    /* and check right then left to get the image within the window */
+    hoverX = imgPos.left + $(this).width();
+
+    /* position to the left or right? */
+   if(hoverX + hoverWidth + rightGuard >= $(window).width()) {
+     hoverX = imgPos.left - hoverWidth - (xOffset*2) -15;
+   }
+
+  if(hoverX < 1) {
+    hoverX = leftGuard;
+  }
+
+  var c = (this.t != "") ? "<br/>" + this.t : "";
+  var preview_link = $('#' + this.id + '-url')[0];
+  $("body").append("<p id='hover-preview'><img src='"+ preview_link.href +"' alt='Loading Image Preview' height='" + hoverHeight + "' width='" + hoverWidth + "' />"+ c +"</p>");                
+  $("#hover-preview")
+    .css("top",(hoverY + yOffset) + "px")
+    .css("left",(hoverX + xOffset) + "px")
+    .fadeIn("fast");            
+  },
   function(){
     this.title = this.t;  
     $("#hover-preview").remove();
-    }); 
-  $("img.hover-preview").mousemove(function(e){
-    $("#hover-preview")
-      .css("top",(e.pageY - xOffset) + "px")
-      .css("left",(e.pageX + yOffset) + "px");
-  });     
+  }); 
 };
