diff --git a/README.txt b/README.txt
index 12dd1f8..66264c1 100644
--- a/README.txt
+++ b/README.txt
@@ -1,14 +1,10 @@
-$Id
+Hover Preview Image Style
+=========================
 
-Hover Preview for ImageCache
-============================
+Requires Drupal 7.x.
 
-Requires Drupal 6.x, Imagefield, ImageCache, and Content modules.
-
-This module provides a new series of ImageCache formatters. The overall goal
-is to enable the ability to provide a hover state of an image when a mouse
-rolls over it. This is similar to functionality you would find on many
-shopping websites.
+This module provides a mouse hover state for images. This is similar to
+functionality you would find on many shopping websites.
 
 The implementation of this module goes a bit further than just a javascript
 hover. The idea is you create multiple imagecache presets, and this will allow
@@ -16,37 +12,21 @@ you to hover from any preset to any other preset.
 
 Here's a step-by-step of how to use it.
 
-1) Create at least two imagecache presets, one for your thumbnail/static/small
+1) Create at least two image styles, one for your thumbnail/static/small
 image, and one for your larger hover image. You can create as many presets as
 you like, but for this example we'll use two.
 
 Preset #1 = Thumbnail = Scale and Crop, size of 80x80
 Preset #2 = BigImage = Scale and Crop, size of 200x200
 
-2) After saving your presets, you now have new choices available for the field
-output. Let's say I am using views, and I created a view that outputs an
-imagefield. I can now open the view, click on that field, and head down to the
-'format' section. You have new options available to you, such as:
-
-Hover: Thumbnail TO: BigImage
-Hover: BigImage TO: Hover
-
-The item on the left is the static image size to output, and the item on the
-right is the hover state. 
 
-3) You can also manually output this at the theme layer with a statement
-similar to the following. I am assuming you opened a file such as
-node-mynodetype.tpl.php.
-
-<?php
-  print theme('hover_preview', $node, 'field_mycckfieldname', 'Thumbnail',
-	'BigImage');
-?>
-
-In this case, field_mycckfieldname is the name of your CCK field, Thumbnail is
-the name of the source imagecache preset, and BigImage is the hover state.
+2) After saving your presets, you now have new choices available for the field
+output. In the Field Display settings, choose Hover Preview as the display.
+You can then choose the image style as well as the Hover Preview style when
+showing the image.
 
+Hover Preview
+-------------
+Image style: Thumbnail
+Hover Preview Style: BigImage
 
-IMPORTANT NOTE: If you have a lot of imagecache presets, you are going to have a huge
-number of formatters. This is due to the fact that the module maps ALL presets
-to ALL other presets. 
diff --git a/hover_preview.css b/hover_preview.css
deleted file mode 100644
index 25031db..0000000
--- a/hover_preview.css
+++ /dev/null
@@ -1,15 +0,0 @@
-
-#hover-preview {
-	background: #fff;
-	border: 1px solid #fff;
-	color: #000;
-	display: none;
-	padding: 5px;
-	position: absolute;
-	z-index: 1000;
-}
-
-#ruler {
-  visibility: hidden;
-	white-space: nowrap;
-}
diff --git a/hover_preview.info b/hover_preview.info
index 735d95f..b02147b 100644
--- a/hover_preview.info
+++ b/hover_preview.info
@@ -1,8 +1,4 @@
-
-name = Imagecache hover preview
-description = A jQuery-based hover preview feature for imagefield/imagecache fields.
-core = 6.x
-package = ImageCache
-dependencies[] = imagecache
-dependencies[] = imagefield
-dependencies[] = content
+name = Hover Preview
+description = A jQuery-based hover preview feature for Image fields.
+core = 7.x
+dependencies[] = image
diff --git a/hover_preview.js b/hover_preview.js
index 260b9c9..b2f3025 100644
--- a/hover_preview.js
+++ b/hover_preview.js
@@ -1,104 +1,37 @@
-
-/*
- * Hover preview javascript
- *
- * Inspired by http://cssglobe.com/post/1695/easiest-tooltip-and-image-preview-using-jquery
- *   by Alen Grakalic (http://cssglobe.com)
- *
+/**
+ * @file
+ * JavaScript for the Hover Preview module.
  */
+(function ($) {
 
-Drupal.behaviors.HoverPreview = function (context) {
-  /* CONFIG */
-    
-    yOffset = 10;
-    xOffset = 30;
-    docHeight = $(document).height();
-		//get here because document height could change during DOM manipulation 
-    // these 2 variable determine popup's distance from the cursor
-    // you might want to adjust to get the right result
-    
-  /* END CONFIG */
-
-  //determins the length of the title in pixels.
-  String.prototype.visualLength = function()
-  {
-      var ruler = document.getElementById("ruler");
-      ruler.innerHTML = this;
-	    return ruler.offsetWidth;
-  }  
-
-  $("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]; //why [0] ?
-    
-    img_width = $(preview_link).width();
-    img_height = $(preview_link).height();
-    
-    //Output of the preview element
-    $("body").append("<span id='ruler'></span><p id='hover-preview'><img src='" + preview_link.src + "' alt='Loading Image Preview' />" + c + "</p>");
-    $("#hover-preview")
-      .css("top",(e.pageY - yOffset) + "px")
-      .css("left",(e.pageX + xOffset) + "px")
-      .fadeIn("fast");
-    },
-    
-  function(){
-   // this.title = this.t;  
-    $("#ruler").remove();
-    $("#hover-preview").remove();
-    });   
-
-  
-  //keep track of mouse movement in an image and move preview element
-  $("img.hover-preview").mousemove(function(e){
-  
-  var elementHeight = $("p#hover-preview").outerHeight(true);
-  var elementWidth = $("p#hover-preview").outerWidth(true);
-  var winHeight = $(window).height();
-  var winWidth = $(window).width();
-	var scrolledPixel = $(window).scrollTop();
-  var scrolledPixelLeft = $(window).scrollLeft();
-
-  //Check if item title is too long.
-  var tlen = this.title;
-	var len = tlen.visualLength();
-
-  if(len > elementWidth){
-    elementWidth = len;
-  }
-  //Checks if the bottom was hit.
-  if( ((winHeight - e.pageY + 20 +  scrolledPixel) <= elementHeight) ) {
-		   var yPosition = winHeight - elementHeight + scrolledPixel;
-  }
-	//Checks if the right side was hit.
-  if( ((winWidth - e.pageX - xOffset + scrolledPixelLeft) <= elementWidth) ) {
-	     var xPosition = winWidth - elementWidth + scrolledPixelLeft;
-  }
-
-  if (yPosition != null || xPosition != null){
-    if (yPosition != null && xPosition == null){
-      $("#hover-preview")
-        .css("top",(yPosition + yOffset) + "px")
-	      .css("left",(e.pageX + xOffset) + "px");
-		}
-    if (yPosition == null && xPosition != null){
-      $("#hover-preview")
-		    .css("top",(e.pageY - yOffset) + "px")
-		    .css("left",(e.pageX - elementWidth - xOffset) + "px");
-    }
-    if (xPosition != null && yPosition != null){
-      $("#hover-preview")
-       .css("top",(yPosition + yOffset) + "px")
-       .css("left",(e.pageX - elementWidth - xOffset) + "px");
-    }
-  } else {
-    $("#hover-preview")
-      .css("top",(e.pageY - yOffset) + "px")
-      .css("left",(e.pageX + xOffset) + "px");
+/**
+ * Drupal Hover Preview behavior.
+ */
+Drupal.behaviors.hoverPreview = {
+  attach: function (context, settings) {
+    // Scan through each of the IDs provided by Hover Preview.
+    $.each(settings.hoverPreview || {}, function(id, images) {
+      // Only act on the family of hover images once.
+      $("#" + id).once('hover-preview', function() {
+        // Preload all the images in this family of hover states.
+        $(images).each(function(index, value) {
+          $('<img/>').attr('src', value);
+        });
+
+        // Setup the hover states for each of the images.
+        $('img', this).each(function(index, value) {
+          // Save the Hover Preview image from the settings.
+          $(this).data('hoverPreview', images[index]);
+          $(this).hover(function() {
+            // Swap the images whenever the user hovers their mouse.
+            var backup = $(this).data('hoverPreview');
+            $(this).data('hoverPreview', $(this).attr('src'));
+            $(this).attr('src', backup);
+          });
+        });
+      });
+    });
   }
-  });  
 };
+
+})(jQuery);
diff --git a/hover_preview.module b/hover_preview.module
index 3b3c1a9..4fedcbf 100644
--- a/hover_preview.module
+++ b/hover_preview.module
@@ -1,137 +1,108 @@
 <?php
 
 /**
- * Implementation of hook_theme()
- */
-function hover_preview_theme() {  
-  $presets_a = imagecache_presets();
-  $presets_b = $presets_a;
-
-  $items = array();
-  $items['hover_preview'] = array(
-    'arguments' => array('node' => NULL, 'field_name' => '', 'preset_a' => '', 'preset_b' => '')
-  );
- 
-  foreach ($presets_a as $preset_a) {
-    foreach ($presets_b as $preset_b) {
-      $id = $preset_a['presetname'] . '_hover_preview_' . $preset_b['presetname'];
-      $items['hover_preview_formatter_' . $id] = array(
-        'arguments' => array('element' => NULL),
-        'function' => 'theme_hover_preview_formatter',
-      );
-    }
-  }
-  return $items;
-}
-
-/**
- * Implementation of hook_field_formatter_info().
- * Adds formatters to CCK image fields
+ * Implements hook_field_formatter_info().
  */
 function hover_preview_field_formatter_info() {
-  $presets_a = imagecache_presets();
-  $presets_b = $presets_a;
-  
-  $formatters = array();
-  foreach ($presets_a as $preset_a) {
-    foreach ($presets_b as $preset_b) {
-      $id = $preset_a['presetname'] . '_hover_preview_' . $preset_b['presetname'];
-      $formatters[$id] = array(
-        'label' => t('Hover: @preset_a TO: @preset_b', array('@preset_a' => $preset_a['presetname'], '@preset_b' => $preset_b['presetname'])),
-        'field types' => array('image', 'filefield'),
-      );
-    }
-  }
+  $formatters['hover_preview'] = array(
+    'label' => t('Hover Preview'),
+    'field types' => array('image'),
+    'settings' => array(
+      'image_style' => '',
+      'image_link' => '',
+      'hover_preview_style' => '',
+    ),
+  );
   return $formatters;
 }
 
 /**
- * Display a field like an imagecache formatter but with a wrapper to facilitate the hover preview.
- *
- * Some parts of this function are inspired from theme_imagecache_formatter_default()
- *   since hover preview is just extra stuff around an imagecache-generated img tag.
+ * Implements hook_field_formatter_settings_form().
  */
-function theme_hover_preview_formatter($element) {
-  // Generate unique id's for an image and it's corresponding preview url
-  $unique = $element['#item']['fid'] . '-' . $element['#item']['timestamp'];
-  
-  // Inside a view $element may contain NULL data. In that case, just return.
-  if (empty($element['#item']['fid'])) {
-    return '';
-  }
+function hover_preview_field_formatter_settings_form($field, $instance, $view_mode, $form, &$form_state) {
+  // Build off of the Image field formatter settings.
+  $display = $instance['display'][$view_mode];
+  $settings = $display['settings'];
+  $element = image_field_formatter_settings_form($field, $instance, $view_mode, $form, $form_state);
 
-  drupal_add_js(drupal_get_path('module', 'hover_preview') . '/hover_preview.js');
-  drupal_add_css(drupal_get_path('module', 'hover_preview') . '/hover_preview.css');
-
-  // Extract the two constituent presets
-  list($preset_a, $preset_b) = explode('_hover_preview_', $element['#formatter']);
+  // Add the hover preview setting.
+  $image_styles = image_style_options(FALSE);
+  $element['hover_preview_style'] = array(
+    '#title' => t('Hover preview'),
+    '#type' => 'select',
+    '#default_value' => $settings['image_style'],
+    '#empty_option' => t('None (original image)'),
+    '#options' => $image_styles,
+  );
 
-  // Generate the preview data
-  $preview_id = "hover-preview-" . $unique;
-  $preview_url = imagecache_create_url($preset_b, $element['#item']['filepath']);
-  
-   
-  $item = $element['#item'];
-  $item['data']['alt'] = isset($item['data']['alt']) ? $item['data']['alt'] : '';
-  $item['data']['title'] = isset($item['data']['title']) ? $item['data']['title'] : '';  
-  
-  $preview_text = theme('imagecache', $preset_b,  ($element['#item']['filepath']), $item['data']['alt'], $item['data']['title'], array(
-    'class' => 'hover-preview-preview-url',
-    'style' => 'display: none',
-    'id' => $preview_id . '-url'
-    ));
-  
+  return $element;
+}
 
-  // Generate stuff needed for imagecache
-  $style = 'default';
-  $item = $element['#item'];
+/**
+ * Implements hook_field_formatter_settings_summary().
+ */
+function hover_preview_field_formatter_settings_summary($field, $instance, $view_mode) {
+  // Build off of the Image summary.
+  $summary = image_field_formatter_settings_summary($field, $instance, $view_mode);
 
-  // Set the image alt and title if suitable values are available
-  if (isset($item['data']['alt'])) {
-    $alt = $item['data']['alt'];
-  }
-  elseif (isset($element['#node']->node_title)) {
-    $alt = $element['#node']->node_title;
-  }
-  elseif (isset($element['#node']->title)) {
-    $alt = $element['#node']->title;
-  }
-  
-  if (isset($item['data']['title'])) {
-    $title = $item['data']['title'];
+  // Add in the hover style.
+  $display = $instance['display'][$view_mode];
+  $settings = $display['settings'];
+  $image_styles = image_style_options(FALSE);
+  if (isset($image_styles[$settings['hover_preview_style']])) {
+    $summary .= '<br />' . t('Hover Preview style: @style', array('@style' => $image_styles[$settings['hover_preview_style']]));
   }
   else {
-    $title = $alt;
+    $summary .= '<br />' . t('Hover Preview style: Original image');
   }
-  
-  // Generate the imagecache html
-  $class = "imagecache imagecache-$preset_a imagecache-$style imagecache-{$element['#formatter']}";
-  $class .= " hover-preview";
-  $output = theme('imagecache', $preset_a, $item['filepath'], $alt, $title, array('class' => $class, 'id' => $preview_id));
 
-  return $output . $preview_text;
+  return $summary;
 }
 
 /**
- * Convenience function to display an applicable field from a node using hover_preview
- *
- * Usage: theme('hover_preview', $node, 'field_photo', 'small_preset', 'large_preset');
+ * Implements hook_field_formatter_view().
  */
-function theme_hover_preview($node, $field_name, $preset_a, $preset_b) {
-  $field = content_fields($field_name, $node->type);
-  if ($field) {
-    // If necessary, pass the node through node_view first to sanitise it
-    if (empty($node->content)) {
-      $node->build_mode = NODE_BUILD_NORMAL;
-      node_view($node);
-    }
-    // Poke CCK's display settings to use the formatter we want
-    $format = $preset_a . '_hover_preview_' . $preset_b;
-    $field['display_settings']['full']['format'] = $format;
+function hover_preview_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) {
+  $image_style = $display['settings']['image_style'];
+  $hover_style = $display['settings']['hover_preview_style'];
+
+  $id = drupal_html_id('hover-preview');
+  $settings = array();
+
+  // Build the view from the displayed image.
+  $element = image_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display);
 
-    // Invoke CCK to assemble the data structure for us and then render it
-    $data = content_field('view', $node, $field, $node->$field_name, FALSE, FALSE);
-    $output = drupal_render($data);
-    return $output;
-  }  
+  foreach ($items as $delta => $item) {
+    $hover_uri = image_style_path($hover_style, $item['uri']);
+    $settings[$id][$delta] = file_create_url($hover_uri);
+  }
+
+  // TODO: Send the data in as attributes instead:
+  //   http://drupal.org/node/1025796
+  // Could even pass the hover image in as a data attribute:
+  //   http://ejohn.org/blog/html-5-data-attributes/
+  /*foreach ($element as $delta => $item) {
+    $element[$delta]['#item']['attributes']['class'] = 'hover-preview';
+    $element[$delta]['#item']['attributes']['data-hover-preview'] = $url;
+  }*/
+
+  // If there are images, provide the JavaScript required to have the hover.
+  if (!empty($element)) {
+    $element['#type'] = 'container';
+    $element['#attributes']['class'][] = 'hover-preview';
+    $element['#attributes']['id'] = $id;
+    $element['#attached']['js'][] = array(
+      'data' => drupal_get_path('module', 'hover_preview') . '/hover_preview.js',
+      'type' => 'file',
+    );
+    $element['#attached']['js'][] = array(
+      'data' => array(
+        'hoverPreview' => $settings,
+      ),
+      'type' => 'setting',
+    );
+  }
+
+  return $element;
 }
+
