diff --git a/imagefield_crop.js b/imagefield_crop.js
index fae3f54..ad9c4a7 100644
--- a/imagefield_crop.js
+++ b/imagefield_crop.js
@@ -6,7 +6,6 @@ Drupal.behaviors.imagefield_crop = {
   attach: function (context, settings) {
     // wait till 'fadeIn' effect ends (defined in filefield_widget.inc)
     setTimeout(attachJcrop, 1000, context);
-    //attachJcrop(context);
 
     function attachJcrop(context) {
       if ($('.cropbox', context).length == 0) {
@@ -17,59 +16,70 @@ Drupal.behaviors.imagefield_crop = {
       $('.cropbox', context).once(function() {
         var self = $(this);
 
-        //alert("found a cropbox" + self.attr('id'));
-
         // get the id attribute for multiple image support
         var self_id = self.attr('id');
         var id = self_id.substring(0, self_id.indexOf('-cropbox'));
         // get the name attribute for imagefield name
         var widget = self.parent().parent();
 
-          if ($(".edit-image-crop-changed", widget).val() == 1) {
-              $('.preview-existing', widget).css({display: 'none'});
-              $('.jcrop-preview', widget).css({display: 'block'});
-          }
+        if ($(".edit-image-crop-changed", widget).val() == 1) {
+          $('.preview-existing', widget).css({display: 'none'});
+          $('.jcrop-preview', widget).css({display: 'block'});
+        }
 
-        $(this).Jcrop({
+        //$(this).Jcrop();
+        var jCropOptions = {
           onChange: function(c) {
             $('.preview-existing', widget).css({display: 'none'});
             var preview = $('.imagefield-crop-preview', widget);
             // skip newly added blank fields
-            if (undefined == settings.imagefield_crop[id].preview) {
-              return;
-            }
-            var rx = settings.imagefield_crop[id].preview.width / c.w;
-            var ry = settings.imagefield_crop[id].preview.height / c.h;
+            var rx = 100 / c.w;
+            var ry = 100 / c.h;
             $('.jcrop-preview', preview).css({
-              width: Math.round(rx * settings.imagefield_crop[id].preview.orig_width) + 'px',
-              height: Math.round(ry * settings.imagefield_crop[id].preview.orig_height) + 'px',
+              //width: Math.round(rx * settings.imagefield_crop[id].preview.orig_width) + 'px',
+              //height: Math.round(ry * settings.imagefield_crop[id].preview.orig_height) + 'px',
               marginLeft: '-' + Math.round(rx * c.x) + 'px',
               marginTop: '-' + Math.round(ry * c.y) + 'px',
               display: 'block'
             });
           },
           onSelect: function(c) {
-            $('.preview-existing', widget).css({display: 'none'});
-            $(".edit-image-crop-x", widget).val(c.x);
-            $(".edit-image-crop-y", widget).val(c.y);
-            if (c.w) $(".edit-image-crop-width", widget).val(c.w);
-            if (c.h) $(".edit-image-crop-height", widget).val(c.h);
+            //$('.preview-existing', widget).css({display: 'none'});
+            if (c.w && c.h) {
+              $(".edit-image-crop-x", widget).val(c.x);
+              $(".edit-image-crop-y", widget).val(c.y);
+              $(".edit-image-crop-width", widget).val(c.w);
+              $(".edit-image-crop-height", widget).val(c.h);
+            }
+            else {
+              $(".edit-image-crop-x", widget).val('');
+              $(".edit-image-crop-y", widget).val('');
+              $(".edit-image-crop-width", widget).val('');
+              $(".edit-image-crop-height", widget).val('');
+            }
             $(".edit-image-crop-changed", widget).val(1);
           },
-          aspectRatio: settings.imagefield_crop[id].box.ratio,
-          boxWidth: settings.imagefield_crop[id].box.box_width,
-          boxHeight: settings.imagefield_crop[id].box.box_height,
-          minSize: [Drupal.settings.imagefield_crop[id].minimum.width, Drupal.settings.imagefield_crop[id].minimum.height], 
+          aspectRatio: $('.edit-image-crop-ratio', widget).val(),
+          boxWidth: 400,
+          boxHeight: 400,
+          //boxWidth: settings.imagefield_crop[id][image_style].box.box_width,
+          //boxHeight: settings.imagefield_crop[id][image_style].box.box_height,
+          //minSize: [Drupal.settings.imagefield_crop[id][image_style].minimum.width, Drupal.settings.imagefield_crop[id][image_style].minimum.height],
+        };
+        
+        if ($(".edit-image-crop-x", widget).val()) {
           /*
            * Setting the select here calls onChange event, and we lose the original image visibility
-          */
-          setSelect: [
+           */
+          jCropOptions.setSelect = [
             parseInt($(".edit-image-crop-x", widget).val()),
             parseInt($(".edit-image-crop-y", widget).val()),
             parseInt($(".edit-image-crop-width", widget).val()) + parseInt($(".edit-image-crop-x", widget).val()),
             parseInt($(".edit-image-crop-height", widget).val()) + parseInt($(".edit-image-crop-y", widget).val())
-          ]
-        });
+          ];
+        }
+        
+        $(this).Jcrop(jCropOptions);
       });
     };
   }
diff --git a/imagefield_crop.module b/imagefield_crop.module
index c5f77fa..ab8f07c 100644
--- a/imagefield_crop.module
+++ b/imagefield_crop.module
@@ -1,266 +1,324 @@
 <?php
 
 /**
- * Implements hook_field_widget_info().
+ * Implements hook_image_effect_info().
  */
-function imagefield_crop_field_widget_info() {
-  //dpm(__FUNCTION__);
-  return array(
-    'imagefield_crop_widget' => array(
-      'label' => t('Image with cropping'),
-      'field types' => array('image'),
-      'settings' => array(
-        'progress_indicator' => 'throbber',
-        'preview_image_style' => 'thumbnail',
-        'collapsible' => 2,
-        'resolution' => '200x150',
-        'enforce_ratio' => true,
-        'enforce_minimum' => true,
-        'croparea' => '500x500',
-      ),
-      'behaviors' => array(
-        'multiple values' => FIELD_BEHAVIOR_CUSTOM,
-        'default value' => FIELD_BEHAVIOR_NONE,
-      ),
-    ),
+function imagefield_crop_image_effect_info() {
+  $effects = array();
+  
+  $effects['imagefield_crop_javascript'] = array(
+    'label' => t('User-selected crop'),
+    'help' => t('Users define crops on a per-image basis.'),
+    'effect callback' => 'imagefield_crop_effect',
+    'form callback' => 'imagefield_crop_effect_form',
+    'summary theme' => 'imagefield_crop_effect_summary',
   );
+
+  return $effects;
 }
 
 /**
- * Implements hook_field_widget_settings_form().
+ * Image effect callback: Crop the image based on the javascript selected crop.
+ *
+ * @param $image An image object returned by image_load().
+ * @param $data An array of settings from the user for cropping the image.
+ * @return TRUE on success. FALSE on failure to crop the image.
+ *
  */
-function imagefield_crop_field_widget_settings_form($field, $instance) {
-  //dpm(__FUNCTION__);
-  $widget = $instance['widget'];
-  $settings = $widget['settings'];
-
-  // Use the image widget settings form.
-  $form = image_field_widget_settings_form($field, $instance);
-
-  $form['collapsible'] = array(
-    '#type' => 'radios',
-    '#title' => t('Collapsible behavior'),
-    '#options' => array(
-      1 => t('None.'),
-      2 => t('Collapsible, expanded by default.'),
-      3 => t('Collapsible, collapsed by default.'),
-    ),
-    '#default_value' => $settings['collapsible'],
-  );
+function imagefield_crop_effect(&$image, $data) {
+  $success = TRUE;
+  
+  // @TODO: When previewing, there isn't an image style with the data. This is ugly. Thoughts?
+  $image_style = (!empty($data['image_style'])) ? $data['image_style'] : arg(5);
+  
+  $file_info = db_query('SELECT * FROM {file_managed} WHERE uri = :uri', array(':uri' => $image->source))->fetchObject();
+  $isid = db_query('SELECT isid FROM {image_styles} WHERE name = :name', array(':name' => $image_style))->fetchField();
+  
+  $image_data = NULL;
+  
+  if (!empty($isid) && !empty($file_info)) {
+    $image_data = db_query('SELECT * FROM {imagefield_crop_settings} WHERE fid = :fid && isid = :isid', array(':fid' => $file_info->fid, ':isid' => $isid))->fetchObject();
+  }
+  
+  if (!empty($image_data)) {
+    // Crop defined in db.
+    $success = image_crop($image, $image_data->xoffset, $image_data->yoffset, $image_data->width, $image_data->height);
+  }
+  
+  // now, scale to defined limit. If there wasn't a crop, this just scales the image.
+  if ($success) {
+    if (empty($data['width']) || empty($data['height'])) {
+      $success = image_scale($image, $data['width'], $data['height']);
+    }
+    else {
+      $success = image_scale_and_crop($image, $data['width'], $data['height']);
+    }
+  }
 
-  // Resolution settings.
-  $resolution = explode('x', $settings['resolution']) + array('', '');
-  $form['resolution'] = array(
-    '#title' => t('The resolution to crop the image onto'),
-    '#element_validate' => array('_image_field_resolution_validate', '_imagefield_crop_widget_resolution_validate'),
-    '#theme_wrappers' => array('form_element'),
-    '#description' => t('The output resolution of the cropped image, expressed as WIDTHxHEIGHT (e.g. 640x480). Set to 0 not to rescale after cropping. Note: output resolution must be defined in order to present a dynamic preview.'),
-  );
-  $form['resolution']['x'] = array(
-    '#type' => 'textfield',
-    '#default_value' => $resolution[0],
-    '#size' => 5,
-    '#maxlength' => 5,
-    '#field_suffix' =>' x ',
-    '#theme_wrappers' => array(),
-  );
-  $form['resolution']['y'] = array(
-    '#type' => 'textfield',
-    '#default_value' => $resolution[1],
-    '#size' => 5,
-    '#maxlength' => 5,
-    '#field_suffix' => ' ' . t('pixels'),
-    '#theme_wrappers' => array(),
-  );
-  $form['enforce_ratio'] = array(
-    '#type' => 'checkbox',
-    '#title' => t('Enforce crop box ratio'),
-    '#default_value' => $settings['enforce_ratio'],
-    '#description' => t('Check this to force the ratio of the output on the crop box. NOTE: If you leave this unchecked but enforce an output resolution, the final image might be distorted'),
-    '#element_validate' => array('_imagefield_crop_widget_enforce_ratio_validate'),
-  );
-  $form['enforce_minimum'] = array(
-    '#type' => 'checkbox',
-    '#title' => t('Enforce minimum crop size based on the output size'),
-    '#default_value' => $settings['enforce_minimum'],
-    '#description' => t('Check this to force a minimum cropping selection equal to the output size. NOTE: If you leave this unchecked you might get zoomed pixels if the cropping area is smaller than the output resolution.'),
-    '#element_validate' => array('_imagefield_crop_widget_enforce_minimum_validate'),
-  );
+  return $success;
+}
 
-  // Crop area settings
-  $croparea = explode('x', $settings['croparea']) + array('', '');
-  $form['croparea'] = array(
-    '#title' => t('The resolution of the cropping area'),
-    '#element_validate' => array('_imagefield_crop_widget_croparea_validate'),
-    '#theme_wrappers' => array('form_element'),
-    '#description' => t('The resolution of the area used for the cropping of the image. Image will displayed at this resolution for cropping. Use WIDTHxHEIGHT format, empty or zero values are permitted, e.g. 500x will limit crop box to 500 pixels width.'),
-  );
-  $form['croparea']['x'] = array(
-    '#type' => 'textfield',
-    '#default_value' => $croparea[0],
-    '#size' => 5,
-    '#maxlength' => 5,
-    '#field_suffix' => ' x ',
-    '#theme_wrappers' => array(),
+/**
+ * Settings form for configuring a javascript imagecrop effect.
+ */
+function imagefield_crop_effect_form($data) {
+  $form = image_scale_form($data);
+  
+  $form['description'] = array(
+    '#type' => 'item',
+    '#markup' => '@TODO: Explain what\'s going on. The width/height defines the final size of the image.',
+    '#title' => t('Instructions'),
+    '#weight' => -10,
   );
-  $form['croparea']['y'] = array(
-    '#type' => 'textfield',
-    '#default_value' => $croparea[1],
-    '#size' => 5,
-    '#maxlength' => 5,
-    '#field_suffix' => ' ' . t('pixels'),
-    '#theme_wrappers' => array(),
+  
+  $form['image_style'] = array(
+    '#type' => 'value',
+    '#value' => arg(5), // Image style from uri.
   );
 
   return $form;
 }
 
-function _imagefield_crop_widget_resolution_validate($element, &$form_state) {
-  //dpm(__FUNCTION__);
-	$settings = $form_state['values']['instance']['widget']['settings'];
-  // _image_field_resolution_validate() does most of the validation
-  if ($settings['enforce_ratio'] && (empty($element['x']['#value']))) {
-    form_error($element, t('Target resolution must be defined as WIDTHxHEIGHT if resolution is to be enforced'));
-  }
-}
-
-function _imagefield_crop_widget_enforce_ratio_validate($element, &$form_state) {
-  //dpm(__FUNCTION__);
-	$settings = $form_state['values']['instance']['widget']['settings'];
-  if ($settings['resolution']['x'] && !$element['#value']) {
-    drupal_set_message(t('Output resolution is defined, but not enforced. Final images might be distroted'));
-  }
+/**
+ * Implements hook_image_style_flush().
+ */
+ 
+function imagefield_crop_image_style_flush($style) {
+  db_delete('imagefield_crop_settings')
+    ->condition('isid', $style['isid'])
+    ->execute();
 }
 
-function _imagefield_crop_widget_enforce_minimum_validate($element, &$form_state) {
-  $settings = $form_state['values']['instance']['widget']['settings'];
-  $rw = ($settings['resolution']['x']) ? $settings['resolution']['x'] : 0;
-  $rh = ($settings['resolution']['y']) ? $settings['resolution']['y'] : 0;
+/**
+ * Summary callback for image effect.
+ */
 
-  if ($settings['enforce_minimum'] && 
-      (!is_numeric($rw) || intval($rw) != $rw || $rw <= 0 ||
-       !is_numeric($rh) || intval($rh) != $rh || $rh <= 0)) {
-    form_error($element, t('Target resolution must be defined as WIDTH_HEIGHT if minimum is to be enforced.'));
-  }
+function imagefield_crop_effect_summary($data) {
+  return "HI";
 }
 
-
-function _imagefield_crop_widget_croparea_validate($element, &$form_state) {
-  //dpm(__FUNCTION__);
-  foreach (array('x', 'y') as $dimension) {
-		$value = $element[$dimension]['#value'];
-    if (!empty($value) && !is_numeric($value)) {
-      form_error($element[$dimension], t('The @dimension value must be numeric.', array('@dimesion' => $dimension)));
-      return;
+/**
+ * Implements hook_form_field_ui_field_edit_form_alter().
+ * Add the imagecrop setting to an imagefield.
+ */
+function imagefield_crop_form_field_ui_field_edit_form_alter(&$form, $form_state) {
+  if ($form['#field']['type'] == 'image') {
+    $styles = imagefield_crop_get_imagecrop_styles();
+    if (count($styles) > 0) {
+      $form['instance']['settings']['imagecrop'] = array(
+        '#type' => 'checkboxes',
+        '#options' => $styles,
+        '#title' => t('Available imagecrop styles'),
+        '#description' => t('Select which imagecrop styles should be available for this field'),
+        '#weight' => 12,
+        '#default_value' => isset($form_state['build_info']['args'][0]['settings']['imagecrop']) ? $form_state['build_info']['args'][0]['settings']['imagecrop'] : array(),
+      );
     }
   }
-  form_set_value($element, intval($element['x']['#value']) . 'x' . intval($element['y']['#value']), $form_state);
 }
 
 /**
- * Implements hook_field_widget_form().
+ * Return a list of presets.
+ *
+ * @param $enabled_styles array of styles that are enabled for a field
+ * @return $presets array with presetid to load and list of all other possible presets.
  */
-function imagefield_crop_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {
-  //dpm(__FUNCTION__);
-  $elements = image_field_widget_form($form, $form_state, $field, $instance, $langcode, $items, $delta, $element);
-  foreach (element_children($elements) as $delta) {
-    // Add all extra functionality provided by the imagefield_crop widget.
-    $elements[$delta]['#process'][] = 'imagefield_crop_widget_process';
+function imagefield_crop_get_imagecrop_styles($enabled_styles = array()) {
 
-    //dpm($elements[$delta]);
-    // Register our value callback
-    $elements[$delta]['#file_value_callbacks'][] = 'imagefield_crop_widget_value';
+  $apply_filter = (count($enabled_styles) > 0);
 
+  $all_styles = image_styles();
+  $styles = array();
+  foreach ($all_styles as $key => $style) {
+    foreach ($style['effects'] as $effect) {
+      if ($effect['name'] == 'imagefield_crop_javascript') {
+
+        // Skip if current style is not enabled.
+        if ($apply_filter && !in_array($style['isid'], $enabled_styles)) {
+          continue;
+        }
+        $styles[$style['isid']] = $style['name'];
+
+      }
+    }
   }
-  return $elements;
+
+  return $styles;
+
 }
 
 /**
- * An element #process callback for the imagefield_crop field type.
+ * Implements hook_element_info_alter().
  */
-function imagefield_crop_widget_process($element, &$form_state, $form) {
-  //dpm(__FUNCTION__);
-  //  dpm(array(__FUNCTION__, $element));
-  $item = $element['#value'];
-  $item['fid'] = $element['fid']['#value'];
+function imagefield_crop_element_info_alter(&$type) {
+  $type['managed_file']['#process'][] = 'process_imagefield_crop_form_element';
+  $type['managed_file']['#element_validate'][] = 'imagefield_crop_widget_submit'; // See note with function
+}
 
+/**
+ * Process function for imagecrop-enabled fields.
+ */
+function process_imagefield_crop_form_element($element, &$form_state) { 
   $instance = $form_state['field'][$element['#field_name']][$element['#language']]['instance'];
-
-  $settings = $instance['settings'];
-  $widget_settings = $instance['widget']['settings'];
-  $element['#theme'] = 'imagefield_crop_widget';
-  $element['#description'] = t('Click on the image and drag to mark how the image will be cropped');
-
-  $path = drupal_get_path('module', 'imagefield_crop');
-  $element['#attached']['js'][] = "$path/Jcrop/js/jquery.Jcrop.js";
-  // We must define Drupal.behaviors for ahah to work, even if there is no file
-  $element['#attached']['js'][] = "$path/imagefield_crop.js";
-  $element['#attached']['css'][] = "$path/Jcrop/css/jquery.Jcrop.css";
-
-  if ($element['#file']) {
-    $file_to_crop = _imagefield_crop_file_to_crop($element['#file']->fid);
-
-    $element['preview'] = array(
-      '#type' => 'markup',
-      '#file' => $file_to_crop, // This is used by the #process function
-      '#process' => array('imagefield_crop_widget_preview_process'),
-      '#theme' => 'imagefield_crop_preview',
-      '#markup' => theme('image', array(
-                           'path' => $element['#file']->uri,
-                           'getsize' => FALSE,
-                           'attributes' => array('class' => 'preview-existing'))),
-    );
-    $element['cropbox'] = array(
-      '#markup' => theme('image', array(
-          'path' => $file_to_crop->uri,
-          'attributes' => array(
-            'class' => 'cropbox',
-            'id' => $element['#id'] . '-cropbox'))),
-    );
-    $element['cropinfo'] = _imagefield_add_cropinfo_fields($element['#file']->fid);
-    list($res_w, $res_h) = explode('x', $widget_settings['resolution']);
-    list($crop_w, $crop_h) = explode('x', $widget_settings['croparea']);
-    $settings = array(
-      $element['#id'] => array(
-        'box' => array(
-          'ratio' => $res_h ? $widget_settings['enforce_ratio'] * $res_w/$res_h : 0,
-          'box_width' => $crop_w,
-          'box_height' => $crop_h,
-        ),
-        'minimum' => array(
-          'width'   => $widget_settings['enforce_minimum'] ? $res_w : NULL,
-          'height'  => $widget_settings['enforce_minimum'] ? $res_h : NULL,
-        ),
-        //'preview' => $preview_js,
-      ),
-    );
-    $element['#attached']['js'][] = array(
-      'data' => array('imagefield_crop' => $settings),
-      'type' => 'setting',
-      'scope' => 'header',
+  
+  // @TODO: Not sure if this is the best check for availaibility.
+  if (count($instance['settings']['imagecrop'] > 0)) {
+    $item = $element['#value'];
+    $item['fid'] = $element['fid']['#value'];
+    
+    //$element['#theme'] = 'imagefield_crop_widget';
+    $element['#description'] = t('Click on the image and drag to mark how the image will be cropped');
+    
+    $image_styles = array();
+    foreach ($instance['settings']['imagecrop'] as $isid) {
+      if ($isid != 0) {
+        $style = image_style_load(NULL, $isid);
+        $image_styles[$isid] = $style['name'];
+      }
+    }
+    
+    $path = drupal_get_path('module', 'imagefield_crop');
+    $element['#attached']['js'][] = "$path/Jcrop/js/jquery.Jcrop.js";
+    // We must define Drupal.behaviors for ahah to work, even if there is no file
+    $element['#attached']['js'][] = "$path/imagefield_crop.js";
+    $element['#attached']['css'][] = "$path/Jcrop/css/jquery.Jcrop.css";
+    
+    if (!empty($element['#file'])) {
+      $file_to_crop = _imagefield_crop_file_to_crop($element['#file']->fid);
+      
+      // @TODO: for each image style, create a field set with the info below.
+      
+      $element['crops'] = array(
+        '#type' => 'container',
+        '#attributes' => array(),
       );
+      
+      $settings = array(
+        $element['#id'] => array(),
+      );
+      
+      foreach ($image_styles as $key => $name) {
+        $element['crops'][$key] = array(
+          '#type' => 'fieldset',
+          '#title' => $name,
+        );
+        
+        $element['crops'][$key]['cropbox'] = array(
+          '#markup' => theme('image', array(
+            'path' => $file_to_crop->uri,
+            'attributes' => array(
+              'class' => 'cropbox',
+              'id' => $element['#id'] . '-cropbox'))),
+        );
+        
+        /*$element['crops'][$key]['preview'] = array(
+          '#markup' => '<div class=".imagefield-crop-preview">' . theme('image', array(
+            'path' => $file_to_crop->uri,
+            'attributes' => array(
+              'class' => 'jcrop-preview',
+            ),
+          )) . '</div>'
+        );*/
+        
+        $element['crops'][$key]['cropinfo'] = _imagefield_crop_add_cropinfo_fields($element['#file']->fid, $key);
+      }
+    }
   }
   
-  // prepend submit handler to remove button
-  array_unshift($element['remove_button']['#submit'], 'imagefield_crop_widget_delete');
-  
   return $element;
 }
 
-function _imagefield_add_cropinfo_fields($fid = NULL) {
+/**
+ * Validate callback for this element.
+ *
+ * Technical note: This is done through a validation hook instead of a submit hook. Submit hooks aren't called on an element level
+ *   for managed_file elements (nor most elements), so this is the closest we get. As such, we need to take into account the possibility
+ *   that a validation call doesn't necessarily mean that the field is actually being saved.
+ */
+ 
+function imagefield_crop_widget_submit($form, $form_state) {
+  // @TODO: Push variables into db.  
+  $field_name = $form['#field_name'];
+  $values = $form_state['values'][$field_name]['und'];
+  
+  foreach ($values as $file) {
+    $file = $file;
+    foreach ($file['crops'] as $isid => $crop) {
+      if ($crop['cropinfo']['changed'] == 1) {
+        // Clear out potential old values first.
+        db_delete('imagefield_crop_settings')
+          ->condition('fid', $file['fid'])
+          ->condition('isid', $isid)
+          ->execute();
+  
+        if (!empty($crop['cropinfo']['width'])) {
+          db_insert('imagefield_crop_settings')
+            ->fields(array(
+              'fid' => $file['fid'],
+              'isid' => $isid,
+              'xoffset' => (!empty($crop['cropinfo']['x'])) ? $crop['cropinfo']['x'] : 0,
+              'yoffset' => (!empty($crop['cropinfo']['y'])) ? $crop['cropinfo']['y'] : 0,
+              'width' => (!empty($crop['cropinfo']['width'])) ? $crop['cropinfo']['width'] : 50,
+              'height' => (!empty($crop['cropinfo']['height'])) ? $crop['cropinfo']['height'] : 50,
+            ))
+            ->execute();
+        }
+          
+        // be sure to delete the created image style for regeneration.
+        $style_info = image_style_load(NULL, $isid);
+        $file_object = file_load($file['fid']);
+        $thumbnail_uri = image_style_path($style_info['name'], $file_object->uri);
+        if (file_exists($thumbnail_uri)) {
+          unlink($thumbnail_uri);
+        }
+      }
+    }
+  }
+    
+  // tmp, need to throw error.
+  //db_query('SELECT test FROM {node}');
+}
+
+/**
+ * Loads defaults for crop.
+ *
+ * @fid - File ID.
+ * @isid - Image Style ID.
+ */
+
+function _imagefield_crop_add_cropinfo_fields($fid = NULL, $isid = NULL) {
+  $style = image_style_load(NULL, $isid);
+  $effect = array();
+  foreach ($style['effects'] as $effect) {
+    if ($effect['label'] == 'User-selected crop') {
+      $effect = image_effect_load($effect['ieid'], $style['name']);
+      break;
+    }
+  }
   $defaults = array(
-    'x'       => 0,
-    'y'       => 0,
-    'width'   => 50,
-    'height'  => 50,
+    'x'       => -1,
+    'y'       => -1,
+    'width'   => -1,
+    'height'  => -1,
     'changed' => 0,
+    'ratio' => '',
   );
-  if($fid) {
-  	$crop_info = variable_get('imagefield_crop_info', array());
-  	if(isset($crop_info[$fid]) && !empty($crop_info[$fid])) {
-  		$defaults = array_merge($defaults,$crop_info[$fid]);
+  if(!empty($fid)) {
+  	$crop_info = db_query('SELECT * FROM {imagefield_crop_settings} WHERE fid = :fid && isid = :isid', array(':fid' => $fid, ':isid' => $isid))->fetchAssoc();
+  	if(isset($crop_info)) {
+      $from_db = array(
+        'x' => $crop_info['xoffset'],
+        'y' => $crop_info['yoffset'],
+        'width' => $crop_info['width'],
+        'height' => $crop_info['height'],
+      );
+  		$defaults = array_merge($defaults,$from_db);
   	}
   }
+  
+  if (!empty($effect['data']['width']) && !empty($effect['data']['height'])) {
+    $defaults['ratio'] = round($effect['data']['width'] / $effect['data']['height'], 3);
+  }
 
   foreach ($defaults as $name => $default) {
     $element[$name] = array(
@@ -270,166 +328,23 @@ function _imagefield_add_cropinfo_fields($fid = NULL) {
       '#default_value' => $default,
     );
   }
-  return $element;
-}
-
-
-function imagefield_crop_widget_preview_process($element, &$form_state, $form) {
-  //dpm(__FUNCTION__);
-  $file = $element['#file'];
-  if ($file->fid == 0) {
-    return $element;
-  }
-  // The widget belongs to the parent, so we got to find it first
-  $parents = array_slice($element['#array_parents'], 0, -1);
-  $parent = drupal_array_get_nested_value($form, $parents);
-  $instance = field_widget_instance($parent, $form_state);
-  if ($instance['widget']['settings']['resolution']) {
-    list($width, $height) = explode('x', $instance['widget']['settings']['resolution']);
-  }
-
-  $image_info = image_get_info(drupal_realpath($file->uri));
-  $settings = array(
-    $parent['#id'] => array(
-      'preview' => array(
-        'orig_width' => $image_info['width'],
-        'orig_height' => $image_info['height'],
-        'width' => (integer)$width,
-        'height' => (integer)$height,
-      ),
-    ),
-  );
-
-  $element['#attached']['js'][] = array(
-    'data' => array('imagefield_crop' => $settings),
-    'type' => 'setting',
-    'scope' => 'header',
-  );
-  $element['#imagefield_crop'] = array (
-    '#file' => $element['#file'],
-    '#width' => $width,
-    '#height' => $height,
-    '#path' => file_create_url($file->uri),
-    );
+  
   return $element;
 }
 
 /**
- * value callback
- *
- * Registered by imagefield_crop_field_widget_form()
+ * Internal functions
  */
-function imagefield_crop_widget_value(&$element, &$input, $form_state) {
-  // set $input['fid'] and that will be the value of the element
-  if (!empty($input['fid']) && $input['cropinfo']['changed']) {
-
-    // get crop and scale info
-    $crop = $input['cropinfo'];
-    $instance = field_widget_instance($element, $form_state);
-    if ($instance['widget']['settings']['resolution']) {
-      list($scale['width'], $scale['height']) = explode('x', $instance['widget']['settings']['resolution']);
-    }
-
-    $src = file_load($input['fid']);
-    $file_to_crop = _imagefield_crop_file_to_crop($src->fid);
-    // Copy the original aside, for future cropping
-    if ($file_to_crop->fid == $src->fid &&
-        $orig_uri = file_unmanaged_copy($src->uri, $src->uri)) {
-      $orig = clone $src;
-      $orig->fid = 0;
-      $orig->uri = $orig_uri;
-      $orig->filename = basename($orig_uri);
-      $orig = file_save($orig);
-      file_usage_add($orig, 'imagefield_crop', 'file', $src->fid);
-    }
-    // do the crop. @todo check for errors
-    // This worked in D6, doesn't work in D7
-    // // Save crop data to the database
-    // $src->imagefield_crop = array('crop' => $crop);
-    // file_save($src);
-    
-    if(_imagefield_crop_resize(drupal_realpath($file_to_crop->uri), $crop, $scale, drupal_realpath($src->uri))) {
-		  // insert crop info for this image in imagefield_crop_info variable
-		  $crop_info = variable_get('imagefield_crop_info', array());
-		  unset($crop['changed']);
-		  $crop_info[$src->fid] = $crop;
-		  variable_set('imagefield_crop_info', $crop_info);
-		}
-    
-  }
-}
-
-function imagefield_crop_widget_delete($form, &$form_state) {
-	$parents = array_slice($form_state['triggering_element']['#array_parents'], 0, -1);
-  $element = drupal_array_get_nested_value($form_state['values'], $parents);
-	$orig = _imagefield_crop_file_to_crop($element['fid']);
-	if($orig->fid != $element['fid']) {
-		file_usage_delete($orig, 'imagefield_crop');
-		file_delete($orig);
-	  $crop_info = variable_get('imagefield_crop_info', array());
-	  unset($crop_info[$element['fid']]);
-	  variable_set('imagefield_crop_info', $crop_info);
-	}
-}
-
-/*********************/
-/* Theming functions */
-/*********************/
-
-/**
- * Implements hook_theme().
- */
-function imagefield_crop_theme() {
-  return array(
-    'imagefield_crop_widget' => array(
-      'render element' => 'element'),
-    'imagefield_crop_preview' => array(
-      'render element' => 'element',
-    ),
-  );
-}
-
-function theme_imagefield_crop_widget($variables) {
-  //dpm(__FUNCTION__);
-  $element = $variables['element'];
-  $output = '';
-  $output .= '<div class="imagefield-crop-widget form-managed-file clearfix">';
-
-  //$output .= '<pre>' . print_r($element['#attached'],1) . '</pre>';
-  if (isset($element['preview'])) {
-    $output .= '<div class="imagefield-crop-preview">';
-    $output .= drupal_render($element['preview']);
-    $output .= '</div>';
-  }
-  if (isset($element['cropbox'])) {
-    $output .= '<div class="imagefield-crop-cropbox">';
-    $output .= drupal_render($element['cropbox']);
-    $output .= '</div>';
-  }
-  $output .= '</div>';
-  $output .= drupal_render_children($element);
-  return $output;
-}
-
-function theme_imagefield_crop_preview($variables) {
-  //dpm(__FUNCTION__);
-  $info = $variables['element']['#imagefield_crop'];
-  $output = '<div class="jcrop-preview-wrapper" style="width:'. $info['#width'] .'px;height:'. $info['#height'] .'px;overflow:hidden;">';
-  $output .= $variables['element']['#markup'];
-  $output .= theme('image', array('path' => $info['#path'], 'alt' => 'jcrop-preview', 'attributes' => array('class' => 'jcrop-preview', 'style' => 'display:none')));
-  $output .= '</div>';
-  return $output;
-}
-
-/*********************/
-/* Internal functions */
-/*********************/
 
 /**
  * Crop the image and resize it
+ *
+ * @src = path to image.
+ * @crop = Array of crop options, keys 'x', 'y', 'width', 'height'
+ * @scale = Array of scale options, keys 'width', 'height'
+ * @dst = Destination path.
  */
 function _imagefield_crop_resize($src, $crop = NULL, $scale = NULL, $dst = NULL) {
-  //dpm(__FUNCTION__);
   $image = image_load($src);
   if ($image) {
     $result = TRUE;
