From 61b254347116cfd8832ccc5c41c68a3de86b0058 Mon Sep 17 00:00:00 2001
From: Jonathan Jordan <jonathan@metaltoad.com>
Date: Fri, 11 Nov 2011 10:44:34 -0800
Subject: [PATCH 01/30] Applied coder module updates to match coding
 standards.

---
 swfupload.admin.inc  |   23 +++++++++++++----------
 swfupload.module     |   25 ++++++++++++++-----------
 swfupload_widget.inc |   20 ++++++++++----------
 3 files changed, 37 insertions(+), 31 deletions(-)

diff --git a/swfupload.admin.inc b/swfupload.admin.inc
index 22c07d3..0f9853b 100755
--- a/swfupload.admin.inc
+++ b/swfupload.admin.inc
@@ -32,7 +32,7 @@ function swfupload_js() {
         'upload_progress_handler' => 'ref.uploadProgress',
         'upload_error_handler' => 'ref.uploadError',
         'upload_complete_handler' => 'ref.uploadComplete',
-        'init_complete_handler' => 'ref.initComplete',// This custom javascript callback function is used to place the markup inside the dom
+        'init_complete_handler' => 'ref.initComplete', // This custom javascript callback function is used to place the markup inside the dom
       );
       $instance->elements = array(
         'drag' => array(
@@ -68,7 +68,7 @@ function swfupload_js() {
 
       // Allow other modules to change the file_path an validators
       foreach (module_implements('swfupload') as $module) {
-        $function = $module .'_swfupload';
+        $function = $module . '_swfupload';
         $function($file, $op, $instance, $widget);
       }
 
@@ -77,12 +77,15 @@ function swfupload_js() {
   }
   // Allow other modules to change the returned data
   foreach (module_implements('swfupload') as $module) {
-    $function = $module .'_swfupload';
+    $function = $module . '_swfupload';
     $function($file, $op, $instance, $widget);
 
     // We want to make sure the last column of each tablerow contains the 'cancel' or 'delete' button.
     if ($op == 'init') {
-      $instance->elements['cancel'] = array('class' => 'last', 'type' => 'cancel');
+      $instance->elements['cancel'] = array(
+        'class' => 'last',
+        'type' => 'cancel',
+      );
     }
   }
 
@@ -90,7 +93,7 @@ function swfupload_js() {
   if (is_array($instance->elements)) {
     array_walk($instance->elements, '_class_to_classname');
   }
-  
+
   $p->op = $op;
   $p->file = $file;
   $p->file_path = $file_path;
@@ -105,23 +108,23 @@ function swfupload_js() {
  * Theme function for the swfupload form element
  */
 function theme_swfupload_widget($element) {
-  drupal_add_css(drupal_get_path('module', 'swfupload') .'/swfupload.css');
+  drupal_add_css(drupal_get_path('module', 'swfupload') . '/swfupload.css');
 
   // Force the classes swfupload_button and disabled to be added to the button
   _form_set_class($element, array('swfupload_button', 'disabled'));
   $element['#attributes']['class'] = str_replace(' error', ' swfupload-error', $element['#attributes']['class']);
 
   $title = ($element['#title']) ? $element['#title'] : t('Upload new !file', array('!file' => ($element['#max_files'] > 1 ? t('file(s)') : t('file'))));
-  $output[] = '<div id="'. $element['#id'] .'" '. drupal_attributes($element['#attributes']) .'>';
+  $output[] = '<div id="' . $element['#id'] . '" ' . drupal_attributes($element['#attributes']) . '>';
   $output[] = '  <div class="swfupload-wrapper">';
-  $output[] = '    <div id="'. $element['#name'] .'-swfwrapper">&nbsp;</div>';
+  $output[] = '    <div id="' . $element['#name'] . '-swfwrapper">&nbsp;</div>';
   $output[] = '  </div>';
   $output[] = '  <div class="left">&nbsp;</div>';
-  $output[] = '  <div class="center">'. $title .'</div>';
+  $output[] = '  <div class="center">' . $title . '</div>';
   $output[] = '  <div class="right">&nbsp;</div><br />';
   $output[] = '</div>';
   if ($element['#description']) {
-    $output[] = '  <div class="description">'. $element['#description'] .'</div>';
+    $output[] = '  <div class="description">' . $element['#description'] . '</div>';
   }
   return join("\n", $output);
 }
diff --git a/swfupload.module b/swfupload.module
index 4a45080..cf236cf 100644
--- a/swfupload.module
+++ b/swfupload.module
@@ -51,16 +51,16 @@ function swfupload_upload_access() {
     // Get all session for the provided user
     $result = db_query("SELECT sid FROM {sessions} WHERE uid = %d", $uid);
     // There is no user with that uid, deny permission.
-    if($result == false) {
+    if ($result == false) {
       return false;
-    } 
+    }
 
     $valid_sids = array();
     // create our hashes we need for verification
     while ($row = db_fetch_object($result)) {
       $valid_sids[$row->sid] = md5($row->sid);
     }
-    
+
     // If the hashed session is is present in the stored hashed session ids from the database,
     // and if there weren't more that 5 invalid attempts for matching,
     // make the user account global so other modules can use its credentials.
@@ -146,7 +146,7 @@ function swfupload_add_js($element) {
     $field['widget']['list_field'] = $field['list_field'];
     $field['widget']['list_default'] = $field['list_default'];
     $field['widget']['description_field'] = $field['description_field'];
-  
+
     $limit = ($field['multiple'] == 1 ? 0 : ($field['multiple'] == 0 ? 1 : $field['multiple']));
 
     // We need to store the variable $flash_url statically while the 2nd time the script is loaded,
@@ -159,19 +159,19 @@ function swfupload_add_js($element) {
     $settings['swfupload_settings'][$element['#id']] = array(
       'module_path' => $path,
       'flash_url' => $flash_url,
-      'upload_url' => url('swfupload'),  // Relative to the SWF file
+      'upload_url' => url('swfupload'), // Relative to the SWF file
       'upload_button_id' => $element['#id'],
       'file_post_name' => $element['#name'],
       'file_queue_limit' => $limit,
       'post_params' => array(
         'sid' => _post_key(),
-        'file_path' => file_directory_path() .'/'. $field['widget']['file_path'],
+        'file_path' => file_directory_path() . '/' . $field['widget']['file_path'],
         'op' => 'move_uploaded_file',
         'instance' => swfupload_to_js(array('name' => $element['#field_name'])),
         'widget' => swfupload_to_js($field['widget']),
       ),
-      'file_size_limit' => ($field['widget']['max_filesize_per_file'] ? (parse_size($field['widget']['max_filesize_per_file']) / 1048576) .'MB' : 0),
-      'file_types' => (empty($field['widget']['file_extensions']) ? '' : '*.'. str_replace(" ", ";*.", $field['widget']['file_extensions'])),
+      'file_size_limit' => ($field['widget']['max_filesize_per_file'] ? (parse_size($field['widget']['max_filesize_per_file']) / 1048576) . 'MB' : 0),
+      'file_types' => (empty($field['widget']['file_extensions']) ? '' : '*.' . str_replace(" ", ";*.", $field['widget']['file_extensions'])),
       'file_types_description' => ($element['#description'] ? $element['#description'] : ''),
       'file_upload_limit' => $limit,
       'custom_settings' => array(
@@ -192,7 +192,7 @@ function swfupload_add_js($element) {
  */
 function _post_key() {
   global $user;
-  return bin2hex("$user->uid*". md5(($user->uid && $user->sid) ? $user->sid : $_SERVER['REMOTE_ADDR']));
+  return bin2hex("$user->uid*" . md5(($user->uid && $user->sid) ? $user->sid : $_SERVER['REMOTE_ADDR']));
 }
 
 /**
@@ -233,11 +233,14 @@ function swfupload_swfupload(&$file, $op, &$instance, $widget) {
         );
         $columns++;
       }
-      foreach (array('alt' => t('Alt'), 'title' => t('Title')) as $elem => $title) {
+      foreach (array(
+        'alt' => t('Alt'),
+        'title' => t('Title'),
+      ) as $elem => $title) {
         if ($widget->{"custom_$elem"}) {
           $instance->elements[$elem] = array(
             'title' => $title,
-            'type' => ($widget->{$elem .'_type'} ? $widget->{$elem .'_type'} : 'textfield'),
+            'type' => ($widget->{$elem . '_type'} ? $widget->{$elem . '_type'} : 'textfield'),
             'default_value' => $widget->{$elem},
             'class' => 'text',
             'contains_progressbar' => TRUE,
diff --git a/swfupload_widget.inc b/swfupload_widget.inc
index d227603..f16e401 100755
--- a/swfupload_widget.inc
+++ b/swfupload_widget.inc
@@ -49,13 +49,13 @@ function swfupload_widget_validate(&$element, &$form_state) {
       $form_state['values'][$element['#field_name']][$key] = array_merge(
         field_file_load($file['fid']), // Load all fields, such as 'filepath'.
         array(
-          'list' => $file['list'],
-          'data' => array(
-            'description' => $file['description'],
-            'alt' => $file['alt'],
-            'title' => $file['title'],
-          ),
-        )
+        'list' => $file['list'],
+        'data' => array(
+          'description' => $file['description'],
+          'alt' => $file['alt'],
+          'title' => $file['title'],
+        ),
+      )
       );
       unset($form_state['values'][$element['#field_name']][$file['fid']]);
     }
@@ -78,7 +78,7 @@ function swfupload_widget_value($element, $edit = FALSE) {
       foreach ($element['#default_value'] as $tmp_file) {
         if ($tmp_file) {
           // Due to a bug in CCK or filefield, the fileobject store in the CCK cache (cache_content) is not stored fully
-          // that means some fields are simply missing (filepath etc.). We need to properly restore it here 
+          // that means some fields are simply missing (filepath etc.). We need to properly restore it here
           $file = field_file_load($tmp_file['fid']);
           $file += array(
             'description' => $tmp_file['data']['description'] ? $tmp_file['data']['description'] : '',
@@ -115,7 +115,7 @@ function swfupload_widget_process($element, $edit, $form_state, $form) {
     $element += imagefield_widget_process($element, $edit, $form_state, $form);
     unset($element['#theme']);
   }
-  
+
   // Make sure that the thumbnails exist. $element['#value'] is
   // structured differently in our widget, so this is not handled by
   // imagefield_widget_process().
@@ -163,5 +163,5 @@ function swfupload_widget_settings_validate($widget) {
  */
 function swfupload_widget_settings_save($widget) {
   $filefield_settings = module_invoke('filefield', 'widget_settings', 'save', $widget);
-  return array_merge($filefield_settings, array('max_resolution', 'min_resolution', 'alt',  'custom_alt', 'title', 'custom_title', 'title_type', 'default_image', 'use_default_image'));
+  return array_merge($filefield_settings, array('max_resolution', 'min_resolution', 'alt', 'custom_alt', 'title', 'custom_title', 'title_type', 'default_image', 'use_default_image'));
 }
-- 
1.7.7


From c1e00b959b5e962ca0e77cd3140caed7e316816d Mon Sep 17 00:00:00 2001
From: Jonathan Jordan <jonathan@metaltoad.com>
Date: Fri, 11 Nov 2011 10:58:07 -0800
Subject: [PATCH 02/30] Applied coder module updates to core api changes.

---
 swfupload.admin.inc  |    3 ++-
 swfupload.info       |    2 +-
 swfupload.module     |   42 +++++++++++++++++++++++++-----------------
 swfupload_widget.inc |   12 ++++++------
 4 files changed, 34 insertions(+), 25 deletions(-)

diff --git a/swfupload.admin.inc b/swfupload.admin.inc
index 0f9853b..6953384 100755
--- a/swfupload.admin.inc
+++ b/swfupload.admin.inc
@@ -107,7 +107,8 @@ function swfupload_js() {
 /**
  * Theme function for the swfupload form element
  */
-function theme_swfupload_widget($element) {
+function theme_swfupload_widget($variables) {
+  $element = $variables['element'];
   drupal_add_css(drupal_get_path('module', 'swfupload') . '/swfupload.css');
 
   // Force the classes swfupload_button and disabled to be added to the button
diff --git a/swfupload.info b/swfupload.info
index 1545075..2afc9de 100644
--- a/swfupload.info
+++ b/swfupload.info
@@ -4,6 +4,6 @@ package = CCK
 version = VERSION
 dependencies[] = filefield
 dependencies[] = jqp
-core = 6.x
+core = 7.x
 
 
diff --git a/swfupload.module b/swfupload.module
index cf236cf..0f16801 100644
--- a/swfupload.module
+++ b/swfupload.module
@@ -1,5 +1,5 @@
 <?php
-include_once dirname(__FILE__) . '/swfupload_widget.inc';
+module_load_include('inc', 'swfupload', 'swfupload_widget');
 
 /**
  * @file
@@ -8,14 +8,19 @@ include_once dirname(__FILE__) . '/swfupload_widget.inc';
  */
 
 /**
- * Implementation of hook_perm().
+ * Implements hook_permission().
  */
-function swfupload_perm() {
-  return array('upload files with swfupload');
+function swfupload_permission() {
+  return array(
+    'upload files with swfupload' => array(
+      'title' => t('upload files with swfupload'),
+      'description' => t('TODO Add a description for \'upload files with swfupload\''),
+    ),
+  );
 }
 
 /**
- * Implementation of hook_menu().
+ * Implements hook_menu().
  */
 function swfupload_menu() {
   $items['swfupload'] = array(
@@ -49,7 +54,7 @@ function swfupload_upload_access() {
     }
 
     // Get all session for the provided user
-    $result = db_query("SELECT sid FROM {sessions} WHERE uid = %d", $uid);
+    $result = db_query("SELECT sid FROM {sessions} WHERE uid = :uid", array(':uid' => $uid));
     // There is no user with that uid, deny permission.
     if ($result == false) {
       return false;
@@ -70,6 +75,9 @@ function swfupload_upload_access() {
 
       // Now load the global user object to "login". We use the $uid provided, as we verfified
       // that the token is correct (and matches this user)
+      // TODO Convert "user_load" to "user_load_multiple" if "$uid" is other than a uid.
+      // To return a single user object, wrap "user_load_multiple" with "array_shift" or equivalent.
+      // Example: array_shift(user_load_multiple(array(), $uid))
       $user = user_load($uid);
 
       // This is needed. Most people forget about this - thats why forms wont work anymore ... the validation fails (token).
@@ -91,7 +99,7 @@ function swfupload_upload_access() {
 }
 
 /**
- * Implementation of hook_widget().
+ * Implements hook_widget().
  */
 function swfupload_widget(&$form, &$form_state, $field, $items, $delta = 0) {
   $element = array(
@@ -102,21 +110,21 @@ function swfupload_widget(&$form, &$form_state, $field, $items, $delta = 0) {
 }
 
 /**
- * Implementation of hook_theme().
+ * Implements hook_theme().
  */
 function swfupload_theme() {
   return array(
     'swfupload_widget' => array(
-      'arguments' => array('element' => NULL),
+      'render element' => 'element',
       'file' => 'swfupload.admin.inc',
     ),
   );
 }
 
 /**
- * Implementation of hook_elements().
+ * Implements hook_element_info().
  */
-function swfupload_elements() {
+function swfupload_element_info() {
   $filefield_elements = module_invoke('filefield', 'elements');
   $elements['swfupload_widget'] = $filefield_elements['filefield_widget'];
   $elements['swfupload_widget']['#process'] = array('swfupload_widget_process');
@@ -179,9 +187,9 @@ function swfupload_add_js($element) {
         'max_queue_size' => ($field['widget']['max_filesize_per_node'] ? $field['widget']['max_filesize_per_node'] : 0),
       ),
     );
-    drupal_add_js('misc/tabledrag.js', 'core');
+    drupal_add_js('misc/tabledrag.js', array('type' => 'file', 'weight' => JS_LIBRARY));
     drupal_add_js("$path/js/swfupload_widget.js");
-    drupal_add_js($settings, 'setting');
+    drupal_add_js($settings, array('type' => 'setting', 'scope' => JS_DEFAULT));
   }
 
   return $element;
@@ -210,7 +218,7 @@ function hex2bin($h) {
 }
 
 /**
- * Implementation of our own API hook_swfupload().
+ * Implements hook_swfupload().
  */
 function swfupload_swfupload(&$file, $op, &$instance, $widget) {
   switch ($op) {
@@ -287,7 +295,7 @@ function swfupload_swfupload(&$file, $op, &$instance, $widget) {
 
       if (user_access('upload files with swfupload') && ($file = file_save_upload($instance->name, $file->validators, $file->file_path))) {
         if (image_get_info($file->filepath)) {
-          $file->thumb = file_create_url(drupal_urlencode(swfupload_thumb_path($file, TRUE)));
+          $file->thumb = file_create_url(drupal_encode_path(swfupload_thumb_path($file, TRUE)));
         }
         break;
       }
@@ -310,7 +318,7 @@ function swfupload_filefield_paths_process_file($new, $file, $settings, $node, $
 }
 
 /**
- * Implementation of hook_jqp().
+ * Implements hook_jqp().
  */
 function swfupload_jqp() {
   $libraries['swfupload'] = array(
@@ -348,6 +356,6 @@ function swfupload_to_js($var) {
     return str_replace(array('<', '>', '&'), array('\u003c', '\u003e', '\u0026'), json_encode($var));
   }
   else {
-    return str_replace(array('\x3c', '\x3e', '\x26'), array('\u003c', '\u003e', '\u0026'), drupal_to_js($var));
+    return str_replace(array('\x3c', '\x3e', '\x26'), array('\u003c', '\u003e', '\u0026'), drupal_json_encode($var));
   }
 }
diff --git a/swfupload_widget.inc b/swfupload_widget.inc
index f16e401..d3519ea 100755
--- a/swfupload_widget.inc
+++ b/swfupload_widget.inc
@@ -6,7 +6,7 @@
  */
 
 /**
- * Implementation of hook_widget_info().
+ * Implements hook_widget_info().
  */
 function swfupload_widget_info() {
   return array(
@@ -22,7 +22,7 @@ function swfupload_widget_info() {
 }
 
 /**
- * Implementation of CCK's hook_widget_settings().
+ * Implements hook_widget_settings().
  *
  * Delegated to filefield.
  */
@@ -89,7 +89,7 @@ function swfupload_widget_value($element, $edit = FALSE) {
 
           // If we're dealing with an image, create a thumbpath
           if (image_get_info($file['filepath'])) {
-            $file['thumb'] = file_create_url(drupal_urlencode(swfupload_thumb_path($file)));
+            $file['thumb'] = file_create_url(drupal_encode_path(swfupload_thumb_path($file)));
           }
           $default_value[$file['fid']] = $file;
         }
@@ -133,7 +133,7 @@ function swfupload_widget_process($element, $edit, $form_state, $form) {
 }
 
 /**
- * Implementation of CCK's hook_widget_settings($op = 'form').
+ * Implements hook_widget_settings($op = 'form')().
  */
 function swfupload_widget_settings_form($widget) {
   if (module_exists('imagefield')) {
@@ -147,7 +147,7 @@ function swfupload_widget_settings_form($widget) {
 }
 
 /**
- * Implementation of CCK's hook_widget_settings($op = 'validate').
+ * Implements hook_widget_settings($op = 'validate')().
  */
 function swfupload_widget_settings_validate($widget) {
   // Check that set resolutions are valid.
@@ -159,7 +159,7 @@ function swfupload_widget_settings_validate($widget) {
 }
 
 /**
- * Implementation of CCK's hook_widget_settings($op = 'save').
+ * Implements hook_widget_settings($op = 'save')().
  */
 function swfupload_widget_settings_save($widget) {
   $filefield_settings = module_invoke('filefield', 'widget_settings', 'save', $widget);
-- 
1.7.7


From e9e5f8e92499aed648fe36fdf5cfce3c2a707f46 Mon Sep 17 00:00:00 2001
From: Jonathan Jordan <jonathan@metaltoad.com>
Date: Fri, 11 Nov 2011 11:01:06 -0800
Subject: [PATCH 03/30] Updated description of permission and updated
 dependencies for D7.

---
 swfupload.info   |    7 ++-----
 swfupload.module |    4 ++--
 2 files changed, 4 insertions(+), 7 deletions(-)

diff --git a/swfupload.info b/swfupload.info
index 2afc9de..6c88f22 100644
--- a/swfupload.info
+++ b/swfupload.info
@@ -1,9 +1,6 @@
 name = SWFupload Widget
-description = A widget for CCK's Filefield which enables multiple file uploads using the SWFUpload library.
+description = A widget for File fields which enables multiple file uploads using the SWFUpload library.
 package = CCK
 version = VERSION
-dependencies[] = filefield
-dependencies[] = jqp
+dependencies[] = file
 core = 7.x
-
-
diff --git a/swfupload.module b/swfupload.module
index 0f16801..3d13779 100644
--- a/swfupload.module
+++ b/swfupload.module
@@ -13,8 +13,8 @@ module_load_include('inc', 'swfupload', 'swfupload_widget');
 function swfupload_permission() {
   return array(
     'upload files with swfupload' => array(
-      'title' => t('upload files with swfupload'),
-      'description' => t('TODO Add a description for \'upload files with swfupload\''),
+      'title' => t('Upload files with SWFUpload'),
+      'description' => t('Allows the user to upload multiple files using SWFUpload.'),
     ),
   );
 }
-- 
1.7.7


From 854ce37270e455a92b03b8169fb1e2b839088306 Mon Sep 17 00:00:00 2001
From: Jonathan Jordan <jonathan@metaltoad.com>
Date: Fri, 11 Nov 2011 11:25:04 -0800
Subject: [PATCH 04/30] Added the swfupload library and changed jqp functions
 to the D7 equivalents.

---
 library/swfupload.js  |  980 +++++++++++++++++++++++++++++++++++++++++++++++++
 library/swfupload.swf |  Bin 0 -> 12787 bytes
 swfupload.module      |   28 +-
 3 files changed, 999 insertions(+), 9 deletions(-)
 create mode 100755 library/swfupload.js
 create mode 100755 library/swfupload.swf

diff --git a/library/swfupload.js b/library/swfupload.js
new file mode 100755
index 0000000..969e200
--- /dev/null
+++ b/library/swfupload.js
@@ -0,0 +1,980 @@
+/**
+ * SWFUpload: http://www.swfupload.org, http://swfupload.googlecode.com
+ *
+ * mmSWFUpload 1.0: Flash upload dialog - http://profandesign.se/swfupload/,  http://www.vinterwebb.se/
+ *
+ * SWFUpload is (c) 2006-2007 Lars Huring, Olov Nilzén and Mammon Media and is released under the MIT License:
+ * http://www.opensource.org/licenses/mit-license.php
+ *
+ * SWFUpload 2 is (c) 2007-2008 Jake Roberts and is released under the MIT License:
+ * http://www.opensource.org/licenses/mit-license.php
+ *
+ */
+
+
+/* ******************* */
+/* Constructor & Init  */
+/* ******************* */
+var SWFUpload;
+
+if (SWFUpload == undefined) {
+	SWFUpload = function (settings) {
+		this.initSWFUpload(settings);
+	};
+}
+
+SWFUpload.prototype.initSWFUpload = function (settings) {
+	try {
+		this.customSettings = {};	// A container where developers can place their own settings associated with this instance.
+		this.settings = settings;
+		this.eventQueue = [];
+		this.movieName = "SWFUpload_" + SWFUpload.movieCount++;
+		this.movieElement = null;
+
+
+		// Setup global control tracking
+		SWFUpload.instances[this.movieName] = this;
+
+		// Load the settings.  Load the Flash movie.
+		this.initSettings();
+		this.loadFlash();
+		this.displayDebugInfo();
+	} catch (ex) {
+		delete SWFUpload.instances[this.movieName];
+		throw ex;
+	}
+};
+
+/* *************** */
+/* Static Members  */
+/* *************** */
+SWFUpload.instances = {};
+SWFUpload.movieCount = 0;
+SWFUpload.version = "2.2.0 2009-03-25";
+SWFUpload.QUEUE_ERROR = {
+	QUEUE_LIMIT_EXCEEDED	  		: -100,
+	FILE_EXCEEDS_SIZE_LIMIT  		: -110,
+	ZERO_BYTE_FILE			  		: -120,
+	INVALID_FILETYPE		  		: -130
+};
+SWFUpload.UPLOAD_ERROR = {
+	HTTP_ERROR				  		: -200,
+	MISSING_UPLOAD_URL	      		: -210,
+	IO_ERROR				  		: -220,
+	SECURITY_ERROR			  		: -230,
+	UPLOAD_LIMIT_EXCEEDED	  		: -240,
+	UPLOAD_FAILED			  		: -250,
+	SPECIFIED_FILE_ID_NOT_FOUND		: -260,
+	FILE_VALIDATION_FAILED	  		: -270,
+	FILE_CANCELLED			  		: -280,
+	UPLOAD_STOPPED					: -290
+};
+SWFUpload.FILE_STATUS = {
+	QUEUED		 : -1,
+	IN_PROGRESS	 : -2,
+	ERROR		 : -3,
+	COMPLETE	 : -4,
+	CANCELLED	 : -5
+};
+SWFUpload.BUTTON_ACTION = {
+	SELECT_FILE  : -100,
+	SELECT_FILES : -110,
+	START_UPLOAD : -120
+};
+SWFUpload.CURSOR = {
+	ARROW : -1,
+	HAND : -2
+};
+SWFUpload.WINDOW_MODE = {
+	WINDOW : "window",
+	TRANSPARENT : "transparent",
+	OPAQUE : "opaque"
+};
+
+// Private: takes a URL, determines if it is relative and converts to an absolute URL
+// using the current site. Only processes the URL if it can, otherwise returns the URL untouched
+SWFUpload.completeURL = function(url) {
+	if (typeof(url) !== "string" || url.match(/^https?:\/\//i) || url.match(/^\//)) {
+		return url;
+	}
+	
+	var currentURL = window.location.protocol + "//" + window.location.hostname + (window.location.port ? ":" + window.location.port : "");
+	
+	var indexSlash = window.location.pathname.lastIndexOf("/");
+	if (indexSlash <= 0) {
+		path = "/";
+	} else {
+		path = window.location.pathname.substr(0, indexSlash) + "/";
+	}
+	
+	return /*currentURL +*/ path + url;
+	
+};
+
+
+/* ******************** */
+/* Instance Members  */
+/* ******************** */
+
+// Private: initSettings ensures that all the
+// settings are set, getting a default value if one was not assigned.
+SWFUpload.prototype.initSettings = function () {
+	this.ensureDefault = function (settingName, defaultValue) {
+		this.settings[settingName] = (this.settings[settingName] == undefined) ? defaultValue : this.settings[settingName];
+	};
+	
+	// Upload backend settings
+	this.ensureDefault("upload_url", "");
+	this.ensureDefault("preserve_relative_urls", false);
+	this.ensureDefault("file_post_name", "Filedata");
+	this.ensureDefault("post_params", {});
+	this.ensureDefault("use_query_string", false);
+	this.ensureDefault("requeue_on_error", false);
+	this.ensureDefault("http_success", []);
+	this.ensureDefault("assume_success_timeout", 0);
+	
+	// File Settings
+	this.ensureDefault("file_types", "*.*");
+	this.ensureDefault("file_types_description", "All Files");
+	this.ensureDefault("file_size_limit", 0);	// Default zero means "unlimited"
+	this.ensureDefault("file_upload_limit", 0);
+	this.ensureDefault("file_queue_limit", 0);
+
+	// Flash Settings
+	this.ensureDefault("flash_url", "swfupload.swf");
+	this.ensureDefault("prevent_swf_caching", true);
+	
+	// Button Settings
+	this.ensureDefault("button_image_url", "");
+	this.ensureDefault("button_width", 1);
+	this.ensureDefault("button_height", 1);
+	this.ensureDefault("button_text", "");
+	this.ensureDefault("button_text_style", "color: #000000; font-size: 16pt;");
+	this.ensureDefault("button_text_top_padding", 0);
+	this.ensureDefault("button_text_left_padding", 0);
+	this.ensureDefault("button_action", SWFUpload.BUTTON_ACTION.SELECT_FILES);
+	this.ensureDefault("button_disabled", false);
+	this.ensureDefault("button_placeholder_id", "");
+	this.ensureDefault("button_placeholder", null);
+	this.ensureDefault("button_cursor", SWFUpload.CURSOR.ARROW);
+	this.ensureDefault("button_window_mode", SWFUpload.WINDOW_MODE.WINDOW);
+	
+	// Debug Settings
+	this.ensureDefault("debug", false);
+	this.settings.debug_enabled = this.settings.debug;	// Here to maintain v2 API
+	
+	// Event Handlers
+	this.settings.return_upload_start_handler = this.returnUploadStart;
+	this.ensureDefault("swfupload_loaded_handler", null);
+	this.ensureDefault("file_dialog_start_handler", null);
+	this.ensureDefault("file_queued_handler", null);
+	this.ensureDefault("file_queue_error_handler", null);
+	this.ensureDefault("file_dialog_complete_handler", null);
+	
+	this.ensureDefault("upload_start_handler", null);
+	this.ensureDefault("upload_progress_handler", null);
+	this.ensureDefault("upload_error_handler", null);
+	this.ensureDefault("upload_success_handler", null);
+	this.ensureDefault("upload_complete_handler", null);
+	
+	this.ensureDefault("debug_handler", this.debugMessage);
+
+	this.ensureDefault("custom_settings", {});
+
+	// Other settings
+	this.customSettings = this.settings.custom_settings;
+	
+	// Update the flash url if needed
+	if (!!this.settings.prevent_swf_caching) {
+		this.settings.flash_url = this.settings.flash_url + (this.settings.flash_url.indexOf("?") < 0 ? "?" : "&") + "preventswfcaching=" + new Date().getTime();
+	}
+	
+	if (!this.settings.preserve_relative_urls) {
+		//this.settings.flash_url = SWFUpload.completeURL(this.settings.flash_url);	// Don't need to do this one since flash doesn't look at it
+		this.settings.upload_url = SWFUpload.completeURL(this.settings.upload_url);
+		this.settings.button_image_url = SWFUpload.completeURL(this.settings.button_image_url);
+	}
+	
+	delete this.ensureDefault;
+};
+
+// Private: loadFlash replaces the button_placeholder element with the flash movie.
+SWFUpload.prototype.loadFlash = function () {
+	var targetElement, tempParent;
+
+	// Make sure an element with the ID we are going to use doesn't already exist
+	if (document.getElementById(this.movieName) !== null) {
+		throw "ID " + this.movieName + " is already in use. The Flash Object could not be added";
+	}
+
+	// Get the element where we will be placing the flash movie
+	targetElement = document.getElementById(this.settings.button_placeholder_id) || this.settings.button_placeholder;
+
+	if (targetElement == undefined) {
+		throw "Could not find the placeholder element: " + this.settings.button_placeholder_id;
+	}
+
+	// Append the container and load the flash
+	tempParent = document.createElement("div");
+	tempParent.innerHTML = this.getFlashHTML();	// Using innerHTML is non-standard but the only sensible way to dynamically add Flash in IE (and maybe other browsers)
+	targetElement.parentNode.replaceChild(tempParent.firstChild, targetElement);
+
+	// Fix IE Flash/Form bug
+	if (window[this.movieName] == undefined) {
+		window[this.movieName] = this.getMovieElement();
+	}
+	
+};
+
+// Private: getFlashHTML generates the object tag needed to embed the flash in to the document
+SWFUpload.prototype.getFlashHTML = function () {
+	// Flash Satay object syntax: http://www.alistapart.com/articles/flashsatay
+	return ['<object id="', this.movieName, '" type="application/x-shockwave-flash" data="', this.settings.flash_url, '" width="', this.settings.button_width, '" height="', this.settings.button_height, '" class="swfupload">',
+				'<param name="wmode" value="', this.settings.button_window_mode, '" />',
+				'<param name="movie" value="', this.settings.flash_url, '" />',
+				'<param name="quality" value="high" />',
+				'<param name="menu" value="false" />',
+				'<param name="allowScriptAccess" value="always" />',
+				'<param name="flashvars" value="' + this.getFlashVars() + '" />',
+				'</object>'].join("");
+};
+
+// Private: getFlashVars builds the parameter string that will be passed
+// to flash in the flashvars param.
+SWFUpload.prototype.getFlashVars = function () {
+	// Build a string from the post param object
+	var paramString = this.buildParamString();
+	var httpSuccessString = this.settings.http_success.join(",");
+	
+	// Build the parameter string
+	return ["movieName=", encodeURIComponent(this.movieName),
+			"&amp;uploadURL=", encodeURIComponent(this.settings.upload_url),
+			"&amp;useQueryString=", encodeURIComponent(this.settings.use_query_string),
+			"&amp;requeueOnError=", encodeURIComponent(this.settings.requeue_on_error),
+			"&amp;httpSuccess=", encodeURIComponent(httpSuccessString),
+			"&amp;assumeSuccessTimeout=", encodeURIComponent(this.settings.assume_success_timeout),
+			"&amp;params=", encodeURIComponent(paramString),
+			"&amp;filePostName=", encodeURIComponent(this.settings.file_post_name),
+			"&amp;fileTypes=", encodeURIComponent(this.settings.file_types),
+			"&amp;fileTypesDescription=", encodeURIComponent(this.settings.file_types_description),
+			"&amp;fileSizeLimit=", encodeURIComponent(this.settings.file_size_limit),
+			"&amp;fileUploadLimit=", encodeURIComponent(this.settings.file_upload_limit),
+			"&amp;fileQueueLimit=", encodeURIComponent(this.settings.file_queue_limit),
+			"&amp;debugEnabled=", encodeURIComponent(this.settings.debug_enabled),
+			"&amp;buttonImageURL=", encodeURIComponent(this.settings.button_image_url),
+			"&amp;buttonWidth=", encodeURIComponent(this.settings.button_width),
+			"&amp;buttonHeight=", encodeURIComponent(this.settings.button_height),
+			"&amp;buttonText=", encodeURIComponent(this.settings.button_text),
+			"&amp;buttonTextTopPadding=", encodeURIComponent(this.settings.button_text_top_padding),
+			"&amp;buttonTextLeftPadding=", encodeURIComponent(this.settings.button_text_left_padding),
+			"&amp;buttonTextStyle=", encodeURIComponent(this.settings.button_text_style),
+			"&amp;buttonAction=", encodeURIComponent(this.settings.button_action),
+			"&amp;buttonDisabled=", encodeURIComponent(this.settings.button_disabled),
+			"&amp;buttonCursor=", encodeURIComponent(this.settings.button_cursor)
+		].join("");
+};
+
+// Public: getMovieElement retrieves the DOM reference to the Flash element added by SWFUpload
+// The element is cached after the first lookup
+SWFUpload.prototype.getMovieElement = function () {
+	if (this.movieElement == undefined) {
+		this.movieElement = document.getElementById(this.movieName);
+	}
+
+	if (this.movieElement === null) {
+		throw "Could not find Flash element";
+	}
+	
+	return this.movieElement;
+};
+
+// Private: buildParamString takes the name/value pairs in the post_params setting object
+// and joins them up in to a string formatted "name=value&amp;name=value"
+SWFUpload.prototype.buildParamString = function () {
+	var postParams = this.settings.post_params; 
+	var paramStringPairs = [];
+
+	if (typeof(postParams) === "object") {
+		for (var name in postParams) {
+			if (postParams.hasOwnProperty(name)) {
+				paramStringPairs.push(encodeURIComponent(name.toString()) + "=" + encodeURIComponent(postParams[name].toString()));
+			}
+		}
+	}
+
+	return paramStringPairs.join("&amp;");
+};
+
+// Public: Used to remove a SWFUpload instance from the page. This method strives to remove
+// all references to the SWF, and other objects so memory is properly freed.
+// Returns true if everything was destroyed. Returns a false if a failure occurs leaving SWFUpload in an inconsistant state.
+// Credits: Major improvements provided by steffen
+SWFUpload.prototype.destroy = function () {
+	try {
+		// Make sure Flash is done before we try to remove it
+		this.cancelUpload(null, false);
+		
+
+		// Remove the SWFUpload DOM nodes
+		var movieElement = null;
+		movieElement = this.getMovieElement();
+		
+		if (movieElement && typeof(movieElement.CallFunction) === "unknown") { // We only want to do this in IE
+			// Loop through all the movie's properties and remove all function references (DOM/JS IE 6/7 memory leak workaround)
+			for (var i in movieElement) {
+				try {
+					if (typeof(movieElement[i]) === "function") {
+						movieElement[i] = null;
+					}
+				} catch (ex1) {}
+			}
+
+			// Remove the Movie Element from the page
+			try {
+				movieElement.parentNode.removeChild(movieElement);
+			} catch (ex) {}
+		}
+		
+		// Remove IE form fix reference
+		window[this.movieName] = null;
+
+		// Destroy other references
+		SWFUpload.instances[this.movieName] = null;
+		delete SWFUpload.instances[this.movieName];
+
+		this.movieElement = null;
+		this.settings = null;
+		this.customSettings = null;
+		this.eventQueue = null;
+		this.movieName = null;
+		
+		
+		return true;
+	} catch (ex2) {
+		return false;
+	}
+};
+
+
+// Public: displayDebugInfo prints out settings and configuration
+// information about this SWFUpload instance.
+// This function (and any references to it) can be deleted when placing
+// SWFUpload in production.
+SWFUpload.prototype.displayDebugInfo = function () {
+	this.debug(
+		[
+			"---SWFUpload Instance Info---\n",
+			"Version: ", SWFUpload.version, "\n",
+			"Movie Name: ", this.movieName, "\n",
+			"Settings:\n",
+			"\t", "upload_url:               ", this.settings.upload_url, "\n",
+			"\t", "flash_url:                ", this.settings.flash_url, "\n",
+			"\t", "use_query_string:         ", this.settings.use_query_string.toString(), "\n",
+			"\t", "requeue_on_error:         ", this.settings.requeue_on_error.toString(), "\n",
+			"\t", "http_success:             ", this.settings.http_success.join(", "), "\n",
+			"\t", "assume_success_timeout:   ", this.settings.assume_success_timeout, "\n",
+			"\t", "file_post_name:           ", this.settings.file_post_name, "\n",
+			"\t", "post_params:              ", this.settings.post_params.toString(), "\n",
+			"\t", "file_types:               ", this.settings.file_types, "\n",
+			"\t", "file_types_description:   ", this.settings.file_types_description, "\n",
+			"\t", "file_size_limit:          ", this.settings.file_size_limit, "\n",
+			"\t", "file_upload_limit:        ", this.settings.file_upload_limit, "\n",
+			"\t", "file_queue_limit:         ", this.settings.file_queue_limit, "\n",
+			"\t", "debug:                    ", this.settings.debug.toString(), "\n",
+
+			"\t", "prevent_swf_caching:      ", this.settings.prevent_swf_caching.toString(), "\n",
+
+			"\t", "button_placeholder_id:    ", this.settings.button_placeholder_id.toString(), "\n",
+			"\t", "button_placeholder:       ", (this.settings.button_placeholder ? "Set" : "Not Set"), "\n",
+			"\t", "button_image_url:         ", this.settings.button_image_url.toString(), "\n",
+			"\t", "button_width:             ", this.settings.button_width.toString(), "\n",
+			"\t", "button_height:            ", this.settings.button_height.toString(), "\n",
+			"\t", "button_text:              ", this.settings.button_text.toString(), "\n",
+			"\t", "button_text_style:        ", this.settings.button_text_style.toString(), "\n",
+			"\t", "button_text_top_padding:  ", this.settings.button_text_top_padding.toString(), "\n",
+			"\t", "button_text_left_padding: ", this.settings.button_text_left_padding.toString(), "\n",
+			"\t", "button_action:            ", this.settings.button_action.toString(), "\n",
+			"\t", "button_disabled:          ", this.settings.button_disabled.toString(), "\n",
+
+			"\t", "custom_settings:          ", this.settings.custom_settings.toString(), "\n",
+			"Event Handlers:\n",
+			"\t", "swfupload_loaded_handler assigned:  ", (typeof this.settings.swfupload_loaded_handler === "function").toString(), "\n",
+			"\t", "file_dialog_start_handler assigned: ", (typeof this.settings.file_dialog_start_handler === "function").toString(), "\n",
+			"\t", "file_queued_handler assigned:       ", (typeof this.settings.file_queued_handler === "function").toString(), "\n",
+			"\t", "file_queue_error_handler assigned:  ", (typeof this.settings.file_queue_error_handler === "function").toString(), "\n",
+			"\t", "upload_start_handler assigned:      ", (typeof this.settings.upload_start_handler === "function").toString(), "\n",
+			"\t", "upload_progress_handler assigned:   ", (typeof this.settings.upload_progress_handler === "function").toString(), "\n",
+			"\t", "upload_error_handler assigned:      ", (typeof this.settings.upload_error_handler === "function").toString(), "\n",
+			"\t", "upload_success_handler assigned:    ", (typeof this.settings.upload_success_handler === "function").toString(), "\n",
+			"\t", "upload_complete_handler assigned:   ", (typeof this.settings.upload_complete_handler === "function").toString(), "\n",
+			"\t", "debug_handler assigned:             ", (typeof this.settings.debug_handler === "function").toString(), "\n"
+		].join("")
+	);
+};
+
+/* Note: addSetting and getSetting are no longer used by SWFUpload but are included
+	the maintain v2 API compatibility
+*/
+// Public: (Deprecated) addSetting adds a setting value. If the value given is undefined or null then the default_value is used.
+SWFUpload.prototype.addSetting = function (name, value, default_value) {
+    if (value == undefined) {
+        return (this.settings[name] = default_value);
+    } else {
+        return (this.settings[name] = value);
+	}
+};
+
+// Public: (Deprecated) getSetting gets a setting. Returns an empty string if the setting was not found.
+SWFUpload.prototype.getSetting = function (name) {
+    if (this.settings[name] != undefined) {
+        return this.settings[name];
+	}
+
+    return "";
+};
+
+
+
+// Private: callFlash handles function calls made to the Flash element.
+// Calls are made with a setTimeout for some functions to work around
+// bugs in the ExternalInterface library.
+SWFUpload.prototype.callFlash = function (functionName, argumentArray) {
+	argumentArray = argumentArray || [];
+	
+	var movieElement = this.getMovieElement();
+	var returnValue, returnString;
+
+	// Flash's method if calling ExternalInterface methods (code adapted from MooTools).
+	try {
+		returnString = movieElement.CallFunction('<invoke name="' + functionName + '" returntype="javascript">' + __flash__argumentsToXML(argumentArray, 0) + '</invoke>');
+		returnValue = eval(returnString);
+	} catch (ex) {
+		throw "Call to " + functionName + " failed";
+	}
+	
+	// Unescape file post param values
+	if (returnValue != undefined && typeof returnValue.post === "object") {
+		returnValue = this.unescapeFilePostParams(returnValue);
+	}
+
+	return returnValue;
+};
+
+/* *****************************
+	-- Flash control methods --
+	Your UI should use these
+	to operate SWFUpload
+   ***************************** */
+
+// WARNING: this function does not work in Flash Player 10
+// Public: selectFile causes a File Selection Dialog window to appear.  This
+// dialog only allows 1 file to be selected.
+SWFUpload.prototype.selectFile = function () {
+	this.callFlash("SelectFile");
+};
+
+// WARNING: this function does not work in Flash Player 10
+// Public: selectFiles causes a File Selection Dialog window to appear/ This
+// dialog allows the user to select any number of files
+// Flash Bug Warning: Flash limits the number of selectable files based on the combined length of the file names.
+// If the selection name length is too long the dialog will fail in an unpredictable manner.  There is no work-around
+// for this bug.
+SWFUpload.prototype.selectFiles = function () {
+	this.callFlash("SelectFiles");
+};
+
+
+// Public: startUpload starts uploading the first file in the queue unless
+// the optional parameter 'fileID' specifies the ID 
+SWFUpload.prototype.startUpload = function (fileID) {
+	this.callFlash("StartUpload", [fileID]);
+};
+
+// Public: cancelUpload cancels any queued file.  The fileID parameter may be the file ID or index.
+// If you do not specify a fileID the current uploading file or first file in the queue is cancelled.
+// If you do not want the uploadError event to trigger you can specify false for the triggerErrorEvent parameter.
+SWFUpload.prototype.cancelUpload = function (fileID, triggerErrorEvent) {
+	if (triggerErrorEvent !== false) {
+		triggerErrorEvent = true;
+	}
+	this.callFlash("CancelUpload", [fileID, triggerErrorEvent]);
+};
+
+// Public: stopUpload stops the current upload and requeues the file at the beginning of the queue.
+// If nothing is currently uploading then nothing happens.
+SWFUpload.prototype.stopUpload = function () {
+	this.callFlash("StopUpload");
+};
+
+/* ************************
+ * Settings methods
+ *   These methods change the SWFUpload settings.
+ *   SWFUpload settings should not be changed directly on the settings object
+ *   since many of the settings need to be passed to Flash in order to take
+ *   effect.
+ * *********************** */
+
+// Public: getStats gets the file statistics object.
+SWFUpload.prototype.getStats = function () {
+	return this.callFlash("GetStats");
+};
+
+// Public: setStats changes the SWFUpload statistics.  You shouldn't need to 
+// change the statistics but you can.  Changing the statistics does not
+// affect SWFUpload accept for the successful_uploads count which is used
+// by the upload_limit setting to determine how many files the user may upload.
+SWFUpload.prototype.setStats = function (statsObject) {
+	this.callFlash("SetStats", [statsObject]);
+};
+
+// Public: getFile retrieves a File object by ID or Index.  If the file is
+// not found then 'null' is returned.
+SWFUpload.prototype.getFile = function (fileID) {
+	if (typeof(fileID) === "number") {
+		return this.callFlash("GetFileByIndex", [fileID]);
+	} else {
+		return this.callFlash("GetFile", [fileID]);
+	}
+};
+
+// Public: addFileParam sets a name/value pair that will be posted with the
+// file specified by the Files ID.  If the name already exists then the
+// exiting value will be overwritten.
+SWFUpload.prototype.addFileParam = function (fileID, name, value) {
+	return this.callFlash("AddFileParam", [fileID, name, value]);
+};
+
+// Public: removeFileParam removes a previously set (by addFileParam) name/value
+// pair from the specified file.
+SWFUpload.prototype.removeFileParam = function (fileID, name) {
+	this.callFlash("RemoveFileParam", [fileID, name]);
+};
+
+// Public: setUploadUrl changes the upload_url setting.
+SWFUpload.prototype.setUploadURL = function (url) {
+	this.settings.upload_url = url.toString();
+	this.callFlash("SetUploadURL", [url]);
+};
+
+// Public: setPostParams changes the post_params setting
+SWFUpload.prototype.setPostParams = function (paramsObject) {
+	this.settings.post_params = paramsObject;
+	this.callFlash("SetPostParams", [paramsObject]);
+};
+
+// Public: addPostParam adds post name/value pair.  Each name can have only one value.
+SWFUpload.prototype.addPostParam = function (name, value) {
+	this.settings.post_params[name] = value;
+	this.callFlash("SetPostParams", [this.settings.post_params]);
+};
+
+// Public: removePostParam deletes post name/value pair.
+SWFUpload.prototype.removePostParam = function (name) {
+	delete this.settings.post_params[name];
+	this.callFlash("SetPostParams", [this.settings.post_params]);
+};
+
+// Public: setFileTypes changes the file_types setting and the file_types_description setting
+SWFUpload.prototype.setFileTypes = function (types, description) {
+	this.settings.file_types = types;
+	this.settings.file_types_description = description;
+	this.callFlash("SetFileTypes", [types, description]);
+};
+
+// Public: setFileSizeLimit changes the file_size_limit setting
+SWFUpload.prototype.setFileSizeLimit = function (fileSizeLimit) {
+	this.settings.file_size_limit = fileSizeLimit;
+	this.callFlash("SetFileSizeLimit", [fileSizeLimit]);
+};
+
+// Public: setFileUploadLimit changes the file_upload_limit setting
+SWFUpload.prototype.setFileUploadLimit = function (fileUploadLimit) {
+	this.settings.file_upload_limit = fileUploadLimit;
+	this.callFlash("SetFileUploadLimit", [fileUploadLimit]);
+};
+
+// Public: setFileQueueLimit changes the file_queue_limit setting
+SWFUpload.prototype.setFileQueueLimit = function (fileQueueLimit) {
+	this.settings.file_queue_limit = fileQueueLimit;
+	this.callFlash("SetFileQueueLimit", [fileQueueLimit]);
+};
+
+// Public: setFilePostName changes the file_post_name setting
+SWFUpload.prototype.setFilePostName = function (filePostName) {
+	this.settings.file_post_name = filePostName;
+	this.callFlash("SetFilePostName", [filePostName]);
+};
+
+// Public: setUseQueryString changes the use_query_string setting
+SWFUpload.prototype.setUseQueryString = function (useQueryString) {
+	this.settings.use_query_string = useQueryString;
+	this.callFlash("SetUseQueryString", [useQueryString]);
+};
+
+// Public: setRequeueOnError changes the requeue_on_error setting
+SWFUpload.prototype.setRequeueOnError = function (requeueOnError) {
+	this.settings.requeue_on_error = requeueOnError;
+	this.callFlash("SetRequeueOnError", [requeueOnError]);
+};
+
+// Public: setHTTPSuccess changes the http_success setting
+SWFUpload.prototype.setHTTPSuccess = function (http_status_codes) {
+	if (typeof http_status_codes === "string") {
+		http_status_codes = http_status_codes.replace(" ", "").split(",");
+	}
+	
+	this.settings.http_success = http_status_codes;
+	this.callFlash("SetHTTPSuccess", [http_status_codes]);
+};
+
+// Public: setHTTPSuccess changes the http_success setting
+SWFUpload.prototype.setAssumeSuccessTimeout = function (timeout_seconds) {
+	this.settings.assume_success_timeout = timeout_seconds;
+	this.callFlash("SetAssumeSuccessTimeout", [timeout_seconds]);
+};
+
+// Public: setDebugEnabled changes the debug_enabled setting
+SWFUpload.prototype.setDebugEnabled = function (debugEnabled) {
+	this.settings.debug_enabled = debugEnabled;
+	this.callFlash("SetDebugEnabled", [debugEnabled]);
+};
+
+// Public: setButtonImageURL loads a button image sprite
+SWFUpload.prototype.setButtonImageURL = function (buttonImageURL) {
+	if (buttonImageURL == undefined) {
+		buttonImageURL = "";
+	}
+	
+	this.settings.button_image_url = buttonImageURL;
+	this.callFlash("SetButtonImageURL", [buttonImageURL]);
+};
+
+// Public: setButtonDimensions resizes the Flash Movie and button
+SWFUpload.prototype.setButtonDimensions = function (width, height) {
+	this.settings.button_width = width;
+	this.settings.button_height = height;
+	
+	var movie = this.getMovieElement();
+	if (movie != undefined) {
+		movie.style.width = width + "px";
+		movie.style.height = height + "px";
+	}
+	
+	this.callFlash("SetButtonDimensions", [width, height]);
+};
+// Public: setButtonText Changes the text overlaid on the button
+SWFUpload.prototype.setButtonText = function (html) {
+	this.settings.button_text = html;
+	this.callFlash("SetButtonText", [html]);
+};
+// Public: setButtonTextPadding changes the top and left padding of the text overlay
+SWFUpload.prototype.setButtonTextPadding = function (left, top) {
+	this.settings.button_text_top_padding = top;
+	this.settings.button_text_left_padding = left;
+	this.callFlash("SetButtonTextPadding", [left, top]);
+};
+
+// Public: setButtonTextStyle changes the CSS used to style the HTML/Text overlaid on the button
+SWFUpload.prototype.setButtonTextStyle = function (css) {
+	this.settings.button_text_style = css;
+	this.callFlash("SetButtonTextStyle", [css]);
+};
+// Public: setButtonDisabled disables/enables the button
+SWFUpload.prototype.setButtonDisabled = function (isDisabled) {
+	this.settings.button_disabled = isDisabled;
+	this.callFlash("SetButtonDisabled", [isDisabled]);
+};
+// Public: setButtonAction sets the action that occurs when the button is clicked
+SWFUpload.prototype.setButtonAction = function (buttonAction) {
+	this.settings.button_action = buttonAction;
+	this.callFlash("SetButtonAction", [buttonAction]);
+};
+
+// Public: setButtonCursor changes the mouse cursor displayed when hovering over the button
+SWFUpload.prototype.setButtonCursor = function (cursor) {
+	this.settings.button_cursor = cursor;
+	this.callFlash("SetButtonCursor", [cursor]);
+};
+
+/* *******************************
+	Flash Event Interfaces
+	These functions are used by Flash to trigger the various
+	events.
+	
+	All these functions a Private.
+	
+	Because the ExternalInterface library is buggy the event calls
+	are added to a queue and the queue then executed by a setTimeout.
+	This ensures that events are executed in a determinate order and that
+	the ExternalInterface bugs are avoided.
+******************************* */
+
+SWFUpload.prototype.queueEvent = function (handlerName, argumentArray) {
+	// Warning: Don't call this.debug inside here or you'll create an infinite loop
+	
+	if (argumentArray == undefined) {
+		argumentArray = [];
+	} else if (!(argumentArray instanceof Array)) {
+		argumentArray = [argumentArray];
+	}
+	
+	var self = this;
+	if (typeof this.settings[handlerName] === "function") {
+		// Queue the event
+		this.eventQueue.push(function () {
+			this.settings[handlerName].apply(this, argumentArray);
+		});
+		
+		// Execute the next queued event
+		setTimeout(function () {
+			self.executeNextEvent();
+		}, 0);
+		
+	} else if (this.settings[handlerName] !== null) {
+		throw "Event handler " + handlerName + " is unknown or is not a function";
+	}
+};
+
+// Private: Causes the next event in the queue to be executed.  Since events are queued using a setTimeout
+// we must queue them in order to garentee that they are executed in order.
+SWFUpload.prototype.executeNextEvent = function () {
+	// Warning: Don't call this.debug inside here or you'll create an infinite loop
+
+	var  f = this.eventQueue ? this.eventQueue.shift() : null;
+	if (typeof(f) === "function") {
+		f.apply(this);
+	}
+};
+
+// Private: unescapeFileParams is part of a workaround for a flash bug where objects passed through ExternalInterface cannot have
+// properties that contain characters that are not valid for JavaScript identifiers. To work around this
+// the Flash Component escapes the parameter names and we must unescape again before passing them along.
+SWFUpload.prototype.unescapeFilePostParams = function (file) {
+	var reg = /[$]([0-9a-f]{4})/i;
+	var unescapedPost = {};
+	var uk;
+
+	if (file != undefined) {
+		for (var k in file.post) {
+			if (file.post.hasOwnProperty(k)) {
+				uk = k;
+				var match;
+				while ((match = reg.exec(uk)) !== null) {
+					uk = uk.replace(match[0], String.fromCharCode(parseInt("0x" + match[1], 16)));
+				}
+				unescapedPost[uk] = file.post[k];
+			}
+		}
+
+		file.post = unescapedPost;
+	}
+
+	return file;
+};
+
+// Private: Called by Flash to see if JS can call in to Flash (test if External Interface is working)
+SWFUpload.prototype.testExternalInterface = function () {
+	try {
+		return this.callFlash("TestExternalInterface");
+	} catch (ex) {
+		return false;
+	}
+};
+
+// Private: This event is called by Flash when it has finished loading. Don't modify this.
+// Use the swfupload_loaded_handler event setting to execute custom code when SWFUpload has loaded.
+SWFUpload.prototype.flashReady = function () {
+	// Check that the movie element is loaded correctly with its ExternalInterface methods defined
+	var movieElement = this.getMovieElement();
+
+	if (!movieElement) {
+		this.debug("Flash called back ready but the flash movie can't be found.");
+		return;
+	}
+
+	this.cleanUp(movieElement);
+	
+	this.queueEvent("swfupload_loaded_handler");
+};
+
+// Private: removes Flash added fuctions to the DOM node to prevent memory leaks in IE.
+// This function is called by Flash each time the ExternalInterface functions are created.
+SWFUpload.prototype.cleanUp = function (movieElement) {
+	// Pro-actively unhook all the Flash functions
+	try {
+		if (this.movieElement && typeof(movieElement.CallFunction) === "unknown") { // We only want to do this in IE
+			this.debug("Removing Flash functions hooks (this should only run in IE and should prevent memory leaks)");
+			for (var key in movieElement) {
+				try {
+					if (typeof(movieElement[key]) === "function") {
+						movieElement[key] = null;
+					}
+				} catch (ex) {
+				}
+			}
+		}
+	} catch (ex1) {
+	
+	}
+
+	// Fix Flashes own cleanup code so if the SWFMovie was removed from the page
+	// it doesn't display errors.
+	window["__flash__removeCallback"] = function (instance, name) {
+		try {
+			if (instance) {
+				instance[name] = null;
+			}
+		} catch (flashEx) {
+		
+		}
+	};
+
+};
+
+
+/* This is a chance to do something before the browse window opens */
+SWFUpload.prototype.fileDialogStart = function () {
+	this.queueEvent("file_dialog_start_handler");
+};
+
+
+/* Called when a file is successfully added to the queue. */
+SWFUpload.prototype.fileQueued = function (file) {
+	file = this.unescapeFilePostParams(file);
+	this.queueEvent("file_queued_handler", file);
+};
+
+
+/* Handle errors that occur when an attempt to queue a file fails. */
+SWFUpload.prototype.fileQueueError = function (file, errorCode, message) {
+	file = this.unescapeFilePostParams(file);
+	this.queueEvent("file_queue_error_handler", [file, errorCode, message]);
+};
+
+/* Called after the file dialog has closed and the selected files have been queued.
+	You could call startUpload here if you want the queued files to begin uploading immediately. */
+SWFUpload.prototype.fileDialogComplete = function (numFilesSelected, numFilesQueued, numFilesInQueue) {
+	this.queueEvent("file_dialog_complete_handler", [numFilesSelected, numFilesQueued, numFilesInQueue]);
+};
+
+SWFUpload.prototype.uploadStart = function (file) {
+	file = this.unescapeFilePostParams(file);
+	this.queueEvent("return_upload_start_handler", file);
+};
+
+SWFUpload.prototype.returnUploadStart = function (file) {
+	var returnValue;
+	if (typeof this.settings.upload_start_handler === "function") {
+		file = this.unescapeFilePostParams(file);
+		returnValue = this.settings.upload_start_handler.call(this, file);
+	} else if (this.settings.upload_start_handler != undefined) {
+		throw "upload_start_handler must be a function";
+	}
+
+	// Convert undefined to true so if nothing is returned from the upload_start_handler it is
+	// interpretted as 'true'.
+	if (returnValue === undefined) {
+		returnValue = true;
+	}
+	
+	returnValue = !!returnValue;
+	
+	this.callFlash("ReturnUploadStart", [returnValue]);
+};
+
+
+
+SWFUpload.prototype.uploadProgress = function (file, bytesComplete, bytesTotal) {
+	file = this.unescapeFilePostParams(file);
+	this.queueEvent("upload_progress_handler", [file, bytesComplete, bytesTotal]);
+};
+
+SWFUpload.prototype.uploadError = function (file, errorCode, message) {
+	file = this.unescapeFilePostParams(file);
+	this.queueEvent("upload_error_handler", [file, errorCode, message]);
+};
+
+SWFUpload.prototype.uploadSuccess = function (file, serverData, responseReceived) {
+	file = this.unescapeFilePostParams(file);
+	this.queueEvent("upload_success_handler", [file, serverData, responseReceived]);
+};
+
+SWFUpload.prototype.uploadComplete = function (file) {
+	file = this.unescapeFilePostParams(file);
+	this.queueEvent("upload_complete_handler", file);
+};
+
+/* Called by SWFUpload JavaScript and Flash functions when debug is enabled. By default it writes messages to the
+   internal debug console.  You can override this event and have messages written where you want. */
+SWFUpload.prototype.debug = function (message) {
+	this.queueEvent("debug_handler", message);
+};
+
+
+/* **********************************
+	Debug Console
+	The debug console is a self contained, in page location
+	for debug message to be sent.  The Debug Console adds
+	itself to the body if necessary.
+
+	The console is automatically scrolled as messages appear.
+	
+	If you are using your own debug handler or when you deploy to production and
+	have debug disabled you can remove these functions to reduce the file size
+	and complexity.
+********************************** */
+   
+// Private: debugMessage is the default debug_handler.  If you want to print debug messages
+// call the debug() function.  When overriding the function your own function should
+// check to see if the debug setting is true before outputting debug information.
+SWFUpload.prototype.debugMessage = function (message) {
+	if (this.settings.debug) {
+		var exceptionMessage, exceptionValues = [];
+
+		// Check for an exception object and print it nicely
+		if (typeof message === "object" && typeof message.name === "string" && typeof message.message === "string") {
+			for (var key in message) {
+				if (message.hasOwnProperty(key)) {
+					exceptionValues.push(key + ": " + message[key]);
+				}
+			}
+			exceptionMessage = exceptionValues.join("\n") || "";
+			exceptionValues = exceptionMessage.split("\n");
+			exceptionMessage = "EXCEPTION: " + exceptionValues.join("\nEXCEPTION: ");
+			SWFUpload.Console.writeLine(exceptionMessage);
+		} else {
+			SWFUpload.Console.writeLine(message);
+		}
+	}
+};
+
+SWFUpload.Console = {};
+SWFUpload.Console.writeLine = function (message) {
+	var console, documentForm;
+
+	try {
+		console = document.getElementById("SWFUpload_Console");
+
+		if (!console) {
+			documentForm = document.createElement("form");
+			document.getElementsByTagName("body")[0].appendChild(documentForm);
+
+			console = document.createElement("textarea");
+			console.id = "SWFUpload_Console";
+			console.style.fontFamily = "monospace";
+			console.setAttribute("wrap", "off");
+			console.wrap = "off";
+			console.style.overflow = "auto";
+			console.style.width = "700px";
+			console.style.height = "350px";
+			console.style.margin = "5px";
+			documentForm.appendChild(console);
+		}
+
+		console.value += message + "\n";
+
+		console.scrollTop = console.scrollHeight - console.clientHeight;
+	} catch (ex) {
+		alert("Exception: " + ex.name + " Message: " + ex.message);
+	}
+};
diff --git a/library/swfupload.swf b/library/swfupload.swf
new file mode 100755
index 0000000000000000000000000000000000000000..e3f767031ca8243a5f0b89bc0f154cc5962e01e9
GIT binary patch
literal 12787
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
FQw=c6g4F;3

literal 0
HcmV?d00001

diff --git a/swfupload.module b/swfupload.module
index 3d13779..f08ffbc 100644
--- a/swfupload.module
+++ b/swfupload.module
@@ -138,6 +138,22 @@ function swfupload_element_info() {
 }
 
 /**
+ * Implements hook_library()
+ */
+function swfupload_library() {
+  $libraries['swfupload'] = array(
+    'title' => 'SWFUpload',
+    'website' => 'http://swfupload.org/',
+    'version' => '2.2.0.1',
+    'js' => array(
+      drupal_get_path('module', 'swfupload') .'/library/swfupload.js' => array(),
+    ),
+  );
+
+  return $libraries;
+}
+
+/**
  * This function is called after the FAPI element is processed.
  * Here we can safely attach our javascript
  */
@@ -145,10 +161,9 @@ function swfupload_add_js($element) {
   // Get the path to the swfupload module.
   $path = drupal_get_path('module', 'swfupload');
 
-  $field = content_fields($element['#field_name'], $element['#type_name']);
-  $swfupload_library = jqp_library_load('swfupload');
+  $field = field_info_field($element['#field_name']);
 
-  if (drupal_add_library('swfupload', '2.2.0.1') !== FALSE) {
+  if (drupal_add_library('swfupload', 'swfupload') !== FALSE) {
     // Put the values of the list field and description field in the widget array
     // so we can pass it to our hook_swfupload implementation.
     $field['widget']['list_field'] = $field['list_field'];
@@ -157,12 +172,7 @@ function swfupload_add_js($element) {
 
     $limit = ($field['multiple'] == 1 ? 0 : ($field['multiple'] == 0 ? 1 : $field['multiple']));
 
-    // We need to store the variable $flash_url statically while the 2nd time the script is loaded,
-    // $swfupload_library->scripts['2.2.0.1'] will be empty.
-    static $flash_url;
-    if (!$flash_url) {
-      $flash_url = base_path() . str_replace('.js', '.swf', array_shift($swfupload_library->scripts['2.2.0.1']));
-    }
+    $flash_url = drupal_get_path('module', 'swfupload') .'/library/swfupload.swf';
 
     $settings['swfupload_settings'][$element['#id']] = array(
       'module_path' => $path,
-- 
1.7.7


From a3e8bcc5e8c8137dc86263f1db76aa456fa4c6ee Mon Sep 17 00:00:00 2001
From: Jonathan Jordan <jonathan@metaltoad.com>
Date: Fri, 11 Nov 2011 11:29:09 -0800
Subject: [PATCH 05/30] Removed the hook_jqp() implementation.

---
 swfupload.module |   15 ---------------
 1 files changed, 0 insertions(+), 15 deletions(-)

diff --git a/swfupload.module b/swfupload.module
index f08ffbc..733e12b 100644
--- a/swfupload.module
+++ b/swfupload.module
@@ -328,21 +328,6 @@ function swfupload_filefield_paths_process_file($new, $file, $settings, $node, $
 }
 
 /**
- * Implements hook_jqp().
- */
-function swfupload_jqp() {
-  $libraries['swfupload'] = array(
-    'name' => 'SWFUpload',
-    'description' => 'This library allows you to upload multiple files at once by ctrl/shift-selecting in dialog boxed.',
-    'project_url' => 'http://code.google.com/p/swfupload/',
-    'scripts' => array(
-      '2.2.0.1' => array('sites/all/libraries/swfupload/swfupload.js'),
-    ),
-  );
-  return $libraries;
-}
-
-/**
  * Given a file, return the path the image thumbnail used while editing.
  */
 function swfupload_thumb_path($file, $create_thumb = FALSE) {
-- 
1.7.7


From d77bb4f46743b14b83da414e408144bdf719701a Mon Sep 17 00:00:00 2001
From: Jonathan Jordan <jonathan@metaltoad.com>
Date: Fri, 11 Nov 2011 11:41:01 -0800
Subject: [PATCH 06/30] Changed hook_widget_info() to hook_field_widget_info()

---
 swfupload_widget.inc |   12 ++++++------
 1 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/swfupload_widget.inc b/swfupload_widget.inc
index d3519ea..612af08 100755
--- a/swfupload_widget.inc
+++ b/swfupload_widget.inc
@@ -6,16 +6,16 @@
  */
 
 /**
- * Implements hook_widget_info().
+ * Implements hook_field_widget_info().
  */
-function swfupload_widget_info() {
+function swfupload_field_widget_info() {
   return array(
     'swfupload_widget' => array(
       'label' => t('SWFUpload'),
-      'field types' => array('filefield'),
-      'multiple values' => CONTENT_HANDLE_MODULE,
-      'callbacks' => array(
-        'default value' => CONTENT_CALLBACK_CUSTOM,
+      'field types' => array('file'),
+      'behaviors' => array(
+        'multiple values' => FIELD_BEHAVIOR_DEFAULT,
+        'default value' => FIELD_BEHAVIOR_NONE,
       ),
     ),
   );
-- 
1.7.7


From bdf0f97db0b39cf7a636a078a3e718edf132682f Mon Sep 17 00:00:00 2001
From: Jonathan Jordan <jonathan@metaltoad.com>
Date: Fri, 11 Nov 2011 11:51:42 -0800
Subject: [PATCH 07/30] Changed hook_widget() to hook_field_widget_form()

---
 swfupload.module |    6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/swfupload.module b/swfupload.module
index 733e12b..20eeab5 100644
--- a/swfupload.module
+++ b/swfupload.module
@@ -99,10 +99,10 @@ function swfupload_upload_access() {
 }
 
 /**
- * Implements hook_widget().
+ * Implements hook_field_widget_form().
  */
-function swfupload_widget(&$form, &$form_state, $field, $items, $delta = 0) {
-  $element = array(
+function swfupload_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {
+  $element += array(
     '#type' => 'swfupload_widget',
     '#default_value' => $items,
   );
-- 
1.7.7


From 17baeb1230ba93ec92f193f8e65a2eefbcb4c4dc Mon Sep 17 00:00:00 2001
From: Jonathan Jordan <jonathan@metaltoad.com>
Date: Fri, 11 Nov 2011 12:16:42 -0800
Subject: [PATCH 08/30] Changed widget_settings_form function to implement
 hook_field_widget_settings_form.

---
 swfupload_widget.inc |   12 ++++++------
 1 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/swfupload_widget.inc b/swfupload_widget.inc
index 612af08..877cee6 100755
--- a/swfupload_widget.inc
+++ b/swfupload_widget.inc
@@ -133,15 +133,15 @@ function swfupload_widget_process($element, $edit, $form_state, $form) {
 }
 
 /**
- * Implements hook_widget_settings($op = 'form')().
+ * Implements hook_field_widget_settings_form().
  */
-function swfupload_widget_settings_form($widget) {
-  if (module_exists('imagefield')) {
-    module_load_include('inc', 'imagefield', 'imagefield_widget');
-    $form = imagefield_widget_settings_form($widget);
+function swfupload_field_widget_settings_form($field, $instance) {
+  if (module_exists('image')) {
+    module_load_include('inc', 'image', 'image.field');
+    $form = imagefield_field_widget_settings_form($field, $instance);
   }
   else {
-    $form = module_invoke('filefield', 'widget_settings', 'form', $widget);
+    $form = module_invoke('file', 'field_widget_settings_form', $field, $instance);
   }
   return $form;
 }
-- 
1.7.7


From 5a7971832a432f3cf262602bf9510fcc82d2f803 Mon Sep 17 00:00:00 2001
From: Jonathan Jordan <jonathan@metaltoad.com>
Date: Fri, 11 Nov 2011 12:44:00 -0800
Subject: [PATCH 09/30] Removed old widget_settings hooks.

---
 swfupload_widget.inc |   39 +++------------------------------------
 1 files changed, 3 insertions(+), 36 deletions(-)

diff --git a/swfupload_widget.inc b/swfupload_widget.inc
index 877cee6..924b4a8 100755
--- a/swfupload_widget.inc
+++ b/swfupload_widget.inc
@@ -22,23 +22,6 @@ function swfupload_field_widget_info() {
 }
 
 /**
- * Implements hook_widget_settings().
- *
- * Delegated to filefield.
- */
-function swfupload_widget_settings($op, $widget) {
-  module_load_include('inc', 'swfupload', 'swfupload_widget');
-  switch ($op) {
-    case 'form':
-      return swfupload_widget_settings_form($widget);
-    case 'validate':
-      return swfupload_widget_settings_validate($widget);
-    case 'save':
-      return swfupload_widget_settings_save($widget);
-  }
-}
-
-/**
  * An #element_validate callback for the filefield_widget field.
  */
 function swfupload_widget_validate(&$element, &$form_state) {
@@ -143,25 +126,9 @@ function swfupload_field_widget_settings_form($field, $instance) {
   else {
     $form = module_invoke('file', 'field_widget_settings_form', $field, $instance);
   }
-  return $form;
-}
 
-/**
- * Implements hook_widget_settings($op = 'validate')().
- */
-function swfupload_widget_settings_validate($widget) {
-  // Check that set resolutions are valid.
-  foreach (array('min_resolution', 'max_resolution') as $resolution) {
-    if (!empty($widget[$resolution]) && !preg_match('/^[0-9]+x[0-9]+$/', $widget[$resolution])) {
-      form_set_error($resolution, t('Please specify a resolution in the format WIDTHxHEIGHT (e.g. 640x480).'));
-    }
-  }
-}
+  $form['#submit'][] = 'swfupload_field_widget_settings_submit';
 
-/**
- * Implements hook_widget_settings($op = 'save')().
- */
-function swfupload_widget_settings_save($widget) {
-  $filefield_settings = module_invoke('filefield', 'widget_settings', 'save', $widget);
-  return array_merge($filefield_settings, array('max_resolution', 'min_resolution', 'alt', 'custom_alt', 'title', 'custom_title', 'title_type', 'default_image', 'use_default_image'));
+  return $form;
 }
+
-- 
1.7.7


From 344eb712df6fe98bf270350af6b75e762dfb6d70 Mon Sep 17 00:00:00 2001
From: Jonathan Jordan <jonathan@metaltoad.com>
Date: Fri, 11 Nov 2011 12:58:34 -0800
Subject: [PATCH 10/30] Changed imagefield and filefield instances to image
 and file.

---
 swfupload.module     |    4 ++--
 swfupload_widget.inc |   10 +++++-----
 2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/swfupload.module b/swfupload.module
index 20eeab5..b3f02c0 100644
--- a/swfupload.module
+++ b/swfupload.module
@@ -125,8 +125,8 @@ function swfupload_theme() {
  * Implements hook_element_info().
  */
 function swfupload_element_info() {
-  $filefield_elements = module_invoke('filefield', 'elements');
-  $elements['swfupload_widget'] = $filefield_elements['filefield_widget'];
+  $filefield_elements = module_invoke('file', 'elements');
+  $elements['swfupload_widget'] = $filefield_elements['file_widget'];
   $elements['swfupload_widget']['#process'] = array('swfupload_widget_process');
   $elements['swfupload_widget']['#element_validate'] = array('swfupload_widget_validate');
 
diff --git a/swfupload_widget.inc b/swfupload_widget.inc
index 924b4a8..2bfdf8b 100755
--- a/swfupload_widget.inc
+++ b/swfupload_widget.inc
@@ -93,15 +93,15 @@ function swfupload_widget_value($element, $edit = FALSE) {
  *
  * The $fields array is in $form['#field_info'][$element['#field_name']].
  */
-function swfupload_widget_process($element, $edit, $form_state, $form) {
-  if (module_exists('imagefield')) {
-    $element += imagefield_widget_process($element, $edit, $form_state, $form);
+function swfupload_widget_process($element, &$form_state, $form) {
+  if (module_exists('image')) {
+    $element += image_field_widget_process($element, $form_state, $form);
     unset($element['#theme']);
   }
 
   // Make sure that the thumbnails exist. $element['#value'] is
   // structured differently in our widget, so this is not handled by
-  // imagefield_widget_process().
+  // image_field_widget_process().
   if (is_array($element['#value'])) {
     foreach (element_children($element['#value']) as $key) {
       if (isset($element['#value'][$key]['filepath'])) {
@@ -121,7 +121,7 @@ function swfupload_widget_process($element, $edit, $form_state, $form) {
 function swfupload_field_widget_settings_form($field, $instance) {
   if (module_exists('image')) {
     module_load_include('inc', 'image', 'image.field');
-    $form = imagefield_field_widget_settings_form($field, $instance);
+    $form = image_field_widget_settings_form($field, $instance);
   }
   else {
     $form = module_invoke('file', 'field_widget_settings_form', $field, $instance);
-- 
1.7.7


From 23f32a7f399c4b7dc9106e41e9b8593ec658b498 Mon Sep 17 00:00:00 2001
From: Jonathan Jordan <jonathan@metaltoad.com>
Date: Fri, 11 Nov 2011 13:05:30 -0800
Subject: [PATCH 11/30] Replaced more instances of filefield.

---
 swfupload.module     |    6 +++---
 swfupload_widget.inc |    2 +-
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/swfupload.module b/swfupload.module
index b3f02c0..11cec80 100644
--- a/swfupload.module
+++ b/swfupload.module
@@ -4,7 +4,7 @@ module_load_include('inc', 'swfupload', 'swfupload_widget');
 /**
  * @file
  *
- * A widget for CCK's Filefield which enables multiple file uploads using the SWFUpload library.
+ * A widget for File fields which enables multiple file uploads using the SWFUpload library.
  */
 
 /**
@@ -125,8 +125,8 @@ function swfupload_theme() {
  * Implements hook_element_info().
  */
 function swfupload_element_info() {
-  $filefield_elements = module_invoke('file', 'elements');
-  $elements['swfupload_widget'] = $filefield_elements['file_widget'];
+  $file_field_elements = module_invoke('file', 'element_info');
+  $elements['swfupload_widget'] = $file_field_elements['file_widget'];
   $elements['swfupload_widget']['#process'] = array('swfupload_widget_process');
   $elements['swfupload_widget']['#element_validate'] = array('swfupload_widget_validate');
 
diff --git a/swfupload_widget.inc b/swfupload_widget.inc
index 2bfdf8b..8693398 100755
--- a/swfupload_widget.inc
+++ b/swfupload_widget.inc
@@ -22,7 +22,7 @@ function swfupload_field_widget_info() {
 }
 
 /**
- * An #element_validate callback for the filefield_widget field.
+ * An #element_validate callback for the file_field_widget field.
  */
 function swfupload_widget_validate(&$element, &$form_state) {
 
-- 
1.7.7


From 68d269c6bfba76493ab6e82e172b01576d058773 Mon Sep 17 00:00:00 2001
From: Jonathan Jordan <jonathan@metaltoad.com>
Date: Fri, 11 Nov 2011 13:10:00 -0800
Subject: [PATCH 12/30] Changed hook_element_info() to use the managed_file
 field type as a base.

---
 swfupload.module |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/swfupload.module b/swfupload.module
index 11cec80..6d395a4 100644
--- a/swfupload.module
+++ b/swfupload.module
@@ -126,7 +126,7 @@ function swfupload_theme() {
  */
 function swfupload_element_info() {
   $file_field_elements = module_invoke('file', 'element_info');
-  $elements['swfupload_widget'] = $file_field_elements['file_widget'];
+  $elements['swfupload_widget'] = $file_field_elements['managed_file'];
   $elements['swfupload_widget']['#process'] = array('swfupload_widget_process');
   $elements['swfupload_widget']['#element_validate'] = array('swfupload_widget_validate');
 
-- 
1.7.7


From 7e420322bfe954770a29a2839fac03406a3c12ad Mon Sep 17 00:00:00 2001
From: Jonathan Jordan <jonathan@metaltoad.com>
Date: Fri, 11 Nov 2011 14:15:06 -0800
Subject: [PATCH 13/30] Updated value callback and hook_field_widget_form()
 implemenations to make sure defaults are set.

---
 swfupload.module     |    6 ++++++
 swfupload_widget.inc |   12 ++++++------
 2 files changed, 12 insertions(+), 6 deletions(-)

diff --git a/swfupload.module b/swfupload.module
index 6d395a4..a3a4eda 100644
--- a/swfupload.module
+++ b/swfupload.module
@@ -102,6 +102,12 @@ function swfupload_upload_access() {
  * Implements hook_field_widget_form().
  */
 function swfupload_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {
+  if (module_exists('image')) {
+    $element += image_field_widget_form($form, $form_state, $field, $instance, $langcode, $items, $delta, $element);
+  } else {
+    $element += file_field_widget_form($form, $form_state, $field, $instance, $langcode, $items, $delta, $element);
+  }
+
   $element += array(
     '#type' => 'swfupload_widget',
     '#default_value' => $items,
diff --git a/swfupload_widget.inc b/swfupload_widget.inc
index 8693398..e8beec0 100755
--- a/swfupload_widget.inc
+++ b/swfupload_widget.inc
@@ -14,7 +14,7 @@ function swfupload_field_widget_info() {
       'label' => t('SWFUpload'),
       'field types' => array('file'),
       'behaviors' => array(
-        'multiple values' => FIELD_BEHAVIOR_DEFAULT,
+        'multiple values' => FIELD_BEHAVIOR_CUSTOM,
         'default value' => FIELD_BEHAVIOR_NONE,
       ),
     ),
@@ -49,12 +49,12 @@ function swfupload_widget_validate(&$element, &$form_state) {
 /**
  * The #value_callback for the swfupload_widget type element.
  */
-function swfupload_widget_value($element, $edit = FALSE) {
-  if (is_string($edit)) {
-    $edit = json_decode($edit, TRUE);
+function swfupload_widget_value($element, $input = FALSE, $form_state) {
+  if (is_string($input)) {
+    $input = json_decode($input, TRUE);
   }
 
-  if ($edit === false) {
+  if ($input === FALSE) {
     $default_value = array();
 
     if (is_array($element['#default_value'])) {
@@ -81,7 +81,7 @@ function swfupload_widget_value($element, $edit = FALSE) {
     return $default_value;
   }
   else {
-    return $edit;
+    return $input;
   }
 }
 
-- 
1.7.7


From efe9fd70042a755b7396776d4659591a29dcce90 Mon Sep 17 00:00:00 2001
From: Jonathan Jordan <jonathan@metaltoad.com>
Date: Tue, 15 Nov 2011 09:35:08 -0800
Subject: [PATCH 14/30] Changed db_query to db_select.

---
 swfupload.module |   12 ++++++++----
 1 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/swfupload.module b/swfupload.module
index a3a4eda..409837e 100644
--- a/swfupload.module
+++ b/swfupload.module
@@ -54,15 +54,18 @@ function swfupload_upload_access() {
     }
 
     // Get all session for the provided user
-    $result = db_query("SELECT sid FROM {sessions} WHERE uid = :uid", array(':uid' => $uid));
+    $result = db_select('sessions')
+      ->fields('sid')
+      ->condition('uid', $uid)
+      ->execute();
     // There is no user with that uid, deny permission.
-    if ($result == false) {
-      return false;
+    if ($result == FALSE) {
+      return FALSE;
     }
 
     $valid_sids = array();
     // create our hashes we need for verification
-    while ($row = db_fetch_object($result)) {
+    foreach ($result as $row) {
       $valid_sids[$row->sid] = md5($row->sid);
     }
 
@@ -111,6 +114,7 @@ function swfupload_field_widget_form(&$form, &$form_state, $field, $instance, $l
   $element += array(
     '#type' => 'swfupload_widget',
     '#default_value' => $items,
+    '#theme' => 'swfupload_widget',
   );
   return $element;
 }
-- 
1.7.7


From 114a850f48b2118b1b5f93337205bceeb8e28c05 Mon Sep 17 00:00:00 2001
From: Jonathan Jordan <jonathan@metaltoad.com>
Date: Tue, 15 Nov 2011 10:01:40 -0800
Subject: [PATCH 15/30] Made changes to get theme function to fire.

---
 swfupload.module |    9 ++++-----
 1 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/swfupload.module b/swfupload.module
index 409837e..fd3bfab 100644
--- a/swfupload.module
+++ b/swfupload.module
@@ -111,11 +111,10 @@ function swfupload_field_widget_form(&$form, &$form_state, $field, $instance, $l
     $element += file_field_widget_form($form, $form_state, $field, $instance, $langcode, $items, $delta, $element);
   }
 
-  $element += array(
-    '#type' => 'swfupload_widget',
-    '#default_value' => $items,
-    '#theme' => 'swfupload_widget',
-  );
+  $element['#type'] = 'swfupload_widget';
+  $element['#default_value'] = $items;
+  $element['#theme'] = 'swfupload_widget';
+
   return $element;
 }
 
-- 
1.7.7


From 1a36b88feb32d83c2dec2f2d8975a17cfef8cb01 Mon Sep 17 00:00:00 2001
From: Jonathan Jordan <jonathan@metaltoad.com>
Date: Tue, 15 Nov 2011 11:08:33 -0800
Subject: [PATCH 16/30] Updated widget javascript to fix changes to D7.

---
 js/swfupload_widget.js | 1590 ++++++++++++++++++++++++------------------------
 1 files changed, 797 insertions(+), 793 deletions(-)

diff --git a/js/swfupload_widget.js b/js/swfupload_widget.js
index b3949bc..8b4e482 100755
--- a/js/swfupload_widget.js
+++ b/js/swfupload_widget.js
@@ -1,946 +1,950 @@
 /**
- * 
+ *
  */
-function SWFU(id, settings) {
-  var ref = {};
-  ref.settings = {};
 
-  ref.ajax_settings = {};
-  ref.queue = {};
-  ref.stats = {};
-  ref.instance = {};
-  ref.upload_stack_length = 0;
-  ref.max_queue_size = 0;
-  ref.upload_stack = {};
-  ref.upload_stack_obj;
-  ref.upload_button_obj;
-  ref.upload_stack_size = 0;
-  ref.wrapper_obj;
-  ref.wrapper_id;
-  ref.num_elements;
-  ref.key_pressed;
-  ref.message_wrapper_obj;
-  ref.messages_timeout;
 
-  /**
-   * 
-   */
-  ref.init = function() {
-    ref.settings = settings;
-    ref.upload_button_obj = $('#' + ref.settings.upload_button_id);
-    ref.instance = {name:settings.file_post_name};
-    ref.ajax_settings = {
-      type:"post",
-      url:ref.settings.upload_url,
-      data:{
-        op:'init',
-        file_path:ref.settings.post_params.file_path,
-        instance:ref.toJson(ref.instance),
-        widget:ref.settings.post_params.widget
-      },
-      success:function(result) {
-        ref.ajaxResponse(result);
-      }
-    };
-
-    ref.prepareSWFButton();
-    // Get the instance data by an AJAX request in order to let other modules change the callbacks and elements for this instance (using hook_swfupload);
-    $.ajax(ref.ajax_settings);
+/**
+ * Overwrite for the TableDrag markChanged function
+ * Allows to place the marker in an other table drawer than the first one.
+ */
+Drupal.tableDrag.prototype.row.prototype.markChanged = function() {
+  var marker = Drupal.theme('tableDragChangedMarker');
+  var cell = ($('td.drag .wrapper', this.element)) || $('td:first', this.element);
+  if ($('span.tabledrag-changed', cell).length == 0) {
+    cell.append(marker);
   };
+};
 
-  /**
-   * Prepares the swfupload button.
-   */
-  ref.prepareSWFButton = function() {
-    // Create a copy of the button to get it's dimensions.
-    // If we'd use the original button, we could end up with dimensions equal to 0px when the button is inside a hidden fieldset.
-    var tmp_button = ref.upload_button_obj.clone().css({'position':'absolute'}).prependTo('body');
+/**
+ * Disables text selection on the DOM element the behavior is attached to.
+*/
+jQuery.fn.disableTextSelect = function() {
+  return this.each(function() {
+    $(this).css({
+      'MozUserSelect' : 'none'
+    }).bind('selectstart', function() {
+      return false;
+    }).mousedown(function() {
+      return false;
+    });
+  });
+};
 
-    // Set the dimensions of the swf so it matches exactly the dimensions of the upload button
-    // swfupload.swf will be placed exactly over the upload button
-    ref.settings.button_width = (tmp_button.find('.left').width() + tmp_button.find('.center').width() + tmp_button.find('.right').width());
-    ref.settings.button_height = tmp_button.find('.center').height();
-    tmp_button.remove();
+(function($) {
+  function SWFU(id, settings) {
+    var ref = {};
+    ref.settings = {};
 
-    // Add the other button settings to the settings object
-    ref.settings.button_placeholder_id = ref.settings.file_post_name + '-swfwrapper';
-    ref.settings.button_window_mode = SWFUpload.WINDOW_MODE.TRANSPARENT;
-    ref.settings.button_cursor = SWFUpload.CURSOR.HAND;
-  };
+    ref.ajax_settings = {};
+    ref.queue = {};
+    ref.stats = {};
+    ref.instance = {};
+    ref.upload_stack_length = 0;
+    ref.max_queue_size = 0;
+    ref.upload_stack = {};
+    ref.upload_stack_obj;
+    ref.upload_button_obj;
+    ref.upload_stack_size = 0;
+    ref.wrapper_obj;
+    ref.wrapper_id;
+    ref.num_elements;
+    ref.key_pressed;
+    ref.message_wrapper_obj;
+    ref.messages_timeout;
 
-  /**
-   * Creates a hidden input field which will contain a JSON formatted string containing all uploaded files
-   */
-  ref.createStackObj = function() {
-    var upload_stack_value = settings.custom_settings.upload_stack_value;
-    ref.max_queue_size = settings.custom_settings.max_queue_size;
-    ref.upload_stack_obj = $('<input type="hidden" />').attr('name', ref.instance.name).val(upload_stack_value).prependTo(ref.upload_button_obj);
-    ref.upload_stack = Drupal.parseJson(upload_stack_value);
-    ref.upload_stack_length = ref.objectLength(ref.upload_stack);
-  };
+    /**
+     *
+     */
+    ref.init = function() {
+      ref.settings = settings;
+      ref.upload_button_obj = $('#' + ref.settings.upload_button_id);
+      ref.instance = {name:settings.file_post_name};
+      ref.ajax_settings = {
+        type:"post",
+        url:ref.settings.upload_url,
+        data:{
+          op:'init',
+          file_path:ref.settings.post_params.file_path,
+          instance:ref.toJson(ref.instance),
+          widget:ref.settings.post_params.widget
+        },
+        success:function(result) {
+          ref.ajaxResponse(result);
+        }
+      };
 
-  /**
-   * 
-   */
-  ref.newSWFUpload = function() {
-    ref.swfu = new SWFUpload(ref.settings);
-  };
+      ref.prepareSWFButton();
+      // Get the instance data by an AJAX request in order to let other modules change the callbacks and elements for this instance (using hook_swfupload);
+      $.ajax(ref.ajax_settings);
+    };
 
-  /**
-   * 
-   */
-  ref.ajaxResponse = function(result) {
-    var result = Drupal.parseJson(result);
+    /**
+     * Prepares the swfupload button.
+     */
+    ref.prepareSWFButton = function() {
+      // Create a copy of the button to get it's dimensions.
+      // If we'd use the original button, we could end up with dimensions equal to 0px when the button is inside a hidden fieldset.
+      var tmp_button = ref.upload_button_obj.clone().css({'position':'absolute'}).prependTo('body');
 
-    switch (result.op) {
-      case 'init':
-        ref.instance = result.instance;
-        ref.num_elements = ref.objectLength(ref.instance.elements);
-        $.each(result.instance.callbacks, function(setting, callback) {
-          ref.settings[setting] = eval(callback);
-        });
-        ref.newSWFUpload();
-        ref.settings.init_complete_handler(result);
-        break;
+      // Set the dimensions of the swf so it matches exactly the dimensions of the upload button
+      // swfupload.swf will be placed exactly over the upload button
+      ref.settings.button_width = (tmp_button.find('.left').width() + tmp_button.find('.center').width() + tmp_button.find('.right').width());
+      ref.settings.button_height = tmp_button.find('.center').height();
+      tmp_button.remove();
+
+      // Add the other button settings to the settings object
+      ref.settings.button_placeholder_id = ref.settings.file_post_name + '-swfwrapper';
+      ref.settings.button_window_mode = SWFUpload.WINDOW_MODE.TRANSPARENT;
+      ref.settings.button_cursor = SWFUpload.CURSOR.HAND;
     };
-    ref.addEventHandlers(result.op);
-  };
 
-  /**
-   * Custom function for when the initialization is complete
-   * This event handler is defined in swfupload.module as an instance callback function 
-   */
-  ref.initComplete = function(result) {
-    ref.createWrapper(result.instance.name);
-    ref.createStackObj();
-    ref.addStoredFiles();
+    /**
+     * Creates a hidden input field which will contain a JSON formatted string containing all uploaded files
+     */
+    ref.createStackObj = function() {
+      var upload_stack_value = settings.custom_settings.upload_stack_value;
+      ref.max_queue_size = settings.custom_settings.max_queue_size;
+      ref.upload_stack_obj = $('<input type="hidden" />').attr('name', ref.instance.name).val(upload_stack_value).prependTo(ref.upload_button_obj);
+      ref.upload_stack = jQuery.parseJSON(upload_stack_value);
+      ref.upload_stack_length = ref.objectLength(ref.upload_stack);
+    };
 
-    // Enable the upload button if the current stack is smaller than the allowed stack size,
-    // or when there's no limit at all.
-    if ((ref.settings.file_upload_limit && (ref.upload_stack_length < ref.settings.file_upload_limit)) || ref.settings.file_upload_limit === 0) {
-      ref.upload_button_obj.removeClass('disabled').css({opacity:1});
-    }
-    else {
-      ref.upload_button_obj.addClass('disabled').css({opacity:0.4});
+    /**
+     *
+     */
+    ref.newSWFUpload = function() {
+      ref.swfu = new SWFUpload(ref.settings);
     };
-  };
 
-  /**
-   * This will process all file elements stored in the upload stack.
-   * The upload represents all files submitted in the upload form.
-   * For all files in the stack, a file element will be added to the wrapper using ref.addFileItem().
-   */
-  ref.addStoredFiles = function() {
-    for(var i in ref.upload_stack) {
-      if (ref.upload_stack[i] == 0) {
-        break;
-      };
-      ref.upload_stack[i].id = i;
-      ref.upload_stack[i].fid = i;
-      ref.upload_stack[i].extension = ref.getExtension(ref.upload_stack[i].filename);
-      ref.addFileItem(ref.upload_stack[i]);
+    /**
+     *
+     */
+    ref.ajaxResponse = function(result) {
+      var result = jQuery.parseJSON(result);
 
-      // Adjust the bytes in the stack.
-      ref.upload_stack_size += parseInt(ref.upload_stack[i].filesize);
+      switch (result.op) {
+        case 'init':
+          ref.instance = result.instance;
+          ref.num_elements = ref.objectLength(ref.instance.elements);
+          $.each(result.instance.callbacks, function(setting, callback) {
+            ref.settings[setting] = eval(callback);
+          });
+          ref.newSWFUpload();
+          ref.settings.init_complete_handler(result);
+          break;
+      };
+      ref.addEventHandlers(result.op);
     };
-    ref.addEventHandlers('drag_enable');
-  };
 
-  /**
-   * Places the wrapper markup above the upload button
-   * Depending on what type isset by the instance, a table or a list element is created.
-   */
-  ref.createWrapper = function(field_name) {
-    var use_header = false;
-    var element;
+    /**
+     * Custom function for when the initialization is complete
+     * This event handler is defined in swfupload.module as an instance callback function
+     */
+    ref.initComplete = function(result) {
+      ref.createWrapper(result.instance.name);
+      ref.createStackObj();
+      ref.addStoredFiles();
 
-    if (ref.num_elements > 1 && ref.instance.type == 'table') {
-      // First we'll check if we need to create a header 
-      for (var name in ref.instance.elements) {
-        if (ref.instance.elements[name].title) {
-           use_header = true;
-        };
+      // Enable the upload button if the current stack is smaller than the allowed stack size,
+      // or when there's no limit at all.
+      if ((ref.settings.file_upload_limit && (ref.upload_stack_length < ref.settings.file_upload_limit)) || ref.settings.file_upload_limit === 0) {
+        ref.upload_button_obj.removeClass('disabled').css({opacity:1});
+      }
+      else {
+        ref.upload_button_obj.addClass('disabled').css({opacity:0.4});
       };
+    };
 
-      ref.wrapper_id = 'swfupload_file_wrapper-' + field_name;
-      ref.wrapper_obj = $('<table />').attr({'id': ref.wrapper_id, 'class':'swfupload'});
-      if (use_header) {
-        ref.wrapper_obj.append($('<thead />').append(ref.tableRow(true)));
-      };
-      ref.wrapper_obj.append($('<tbody />').append(ref.tableRow()));
-      ref.upload_button_obj.before(ref.wrapper_obj);
+    /**
+     * This will process all file elements stored in the upload stack.
+     * The upload represents all files submitted in the upload form.
+     * For all files in the stack, a file element will be added to the wrapper using ref.addFileItem().
+     */
+    ref.addStoredFiles = function() {
+      for(var i in ref.upload_stack) {
+        if (ref.upload_stack[i] == 0) {
+          break;
+        };
+        ref.upload_stack[i].id = i;
+        ref.upload_stack[i].fid = i;
+        ref.upload_stack[i].extension = ref.getExtension(ref.upload_stack[i].filename);
+        ref.addFileItem(ref.upload_stack[i]);
 
-      if (!Drupal.settings.tableDrag) {
-        Drupal.settings.tableDrag = {};
+        // Adjust the bytes in the stack.
+        ref.upload_stack_size += parseInt(ref.upload_stack[i].filesize);
       };
-
-      Drupal.settings.tableDrag['swfupload_file_wrapper-' + field_name] = {};
+      ref.addEventHandlers('drag_enable');
     };
-  };    
 
-  /**
-   * Creates or changes a tablerow
-   * @param header Boolean Wheter or not the tablerow should contain th's. If sety to false, td's will be generated.
-   * @param file Object A completed file object 
-   *   - If this is not set, a row is created including the progressbar, which replaces the td's with contains_progressbar set to true.
-   *   - If file is set, the progressbar will be replaced with the appropriate td's
-   */
-  ref.tableRow = function(header, file) {
-    var counter = 0;
-    var colspan = 0;
-    var fid = (file) ? file.fid : 0;
-    var progress_td_counter = 0;
-    var element, colum, content, input, progress_td, elem_value, value;
+    /**
+     * Places the wrapper markup above the upload button
+     * Depending on what type isset by the instance, a table or a list element is created.
+     */
+    ref.createWrapper = function(field_name) {
+      var use_header = false;
+      var element;
 
-    var tr = (file) ? $('#' + file.fid) : $('<tr />');
-    var wrapper = $('<div />').addClass('wrapper');
-    var left_span = $('<div />').addClass('left').html('&nbsp;');
-    var center_span = $('<div />').addClass('center');
-    var right_span = $('<div />').addClass('right').html('&nbsp;');
-
-    // A tablerow will be created containing all elements defined in ref.instance.elements.
-    // If file is set, all elements will be skipped exept the ones with 'contains_progressbar'
-    // If file isn't set, this tablerow will be hidden.
-    for (var name in ref.instance.elements) {
-      counter++;
-      element = ref.instance.elements[name];
+      if (ref.num_elements > 1 && ref.instance.type == 'table') {
+        // First we'll check if we need to create a header
+        for (var name in ref.instance.elements) {
+          if (ref.instance.elements[name].title) {
+             use_header = true;
+          };
+        };
 
-      if (file) {
-        if(!element.contains_progressbar) {
-          // The current td doesn't have to be replaced.
-          // We only need to replace fid of the id and name of the input field
-          tr.find('#edit-' + name + '_0').attr({'name':name +'_' + fid, 'id':'edit-' + name + '_' + fid});
-          continue;
+        ref.wrapper_id = 'swfupload_file_wrapper-' + field_name;
+        ref.wrapper_obj = $('<table />').attr({'id': ref.wrapper_id, 'class':'swfupload'});
+        if (use_header) {
+          ref.wrapper_obj.append($('<thead />').append(ref.tableRow(true)));
         };
-      }
-      else {
-        if (!header && element.contains_progressbar) {
-          if (!progress_td) {
-            progress_td = $('<td />').addClass('progress').append($('<div />').addClass('sfwupload-list-progressbar').append($('<div />').addClass('sfwupload-list-progressbar-status')).append($('<div />').addClass('sfwupload-list-progressbar-glow'))).appendTo(tr);
-          };
-          progress_td_counter++;
-          continue;
+        ref.wrapper_obj.append($('<tbody />').append(ref.tableRow()));
+        ref.upload_button_obj.before(ref.wrapper_obj);
+
+        if (!Drupal.settings.tableDrag) {
+          Drupal.settings.tableDrag = {};
         };
+
+        Drupal.settings.tableDrag['swfupload_file_wrapper-' + field_name] = {};
       };
+    };
 
-      column = $((header ? '<th />' : '<td />'));
-      content = wrapper.clone().appendTo(column);
-      input = $((element.type == 'textarea' ? '<textarea />' : '<input type="' + element.type + '" />')).attr({'name':name +'_' + fid, 'id':'edit-' + name + '_' + fid}).addClass('form-' + element.type);
+    /**
+     * Creates or changes a tablerow
+     * @param header Boolean Wheter or not the tablerow should contain th's. If sety to false, td's will be generated.
+     * @param file Object A completed file object
+     *   - If this is not set, a row is created including the progressbar, which replaces the td's with contains_progressbar set to true.
+     *   - If file is set, the progressbar will be replaced with the appropriate td's
+     */
+    ref.tableRow = function(header, file) {
+      var counter = 0;
+      var colspan = 0;
+      var fid = (file) ? file.fid : 0;
+      var progress_td_counter = 0;
+      var element, colum, content, input, progress_td, elem_value, value;
 
-      if (header) {
-        // Keep track of colspans 
-        if (colspan > 0) colspan--;
-        if (element.colspan) {
-          colspan = element.colspan;
+      var tr = (file) ? $('#' + file.fid) : $('<tr />');
+      var wrapper = $('<div />').addClass('wrapper');
+      var left_span = $('<div />').addClass('left').html('&nbsp;');
+      var center_span = $('<div />').addClass('center');
+      var right_span = $('<div />').addClass('right').html('&nbsp;');
+
+      // A tablerow will be created containing all elements defined in ref.instance.elements.
+      // If file is set, all elements will be skipped exept the ones with 'contains_progressbar'
+      // If file isn't set, this tablerow will be hidden.
+      for (var name in ref.instance.elements) {
+        counter++;
+        element = ref.instance.elements[name];
+
+        if (file) {
+          if(!element.contains_progressbar) {
+            // The current td doesn't have to be replaced.
+            // We only need to replace fid of the id and name of the input field
+            tr.find('#edit-' + name + '_0').attr({'name':name +'_' + fid, 'id':'edit-' + name + '_' + fid});
+            continue;
+          };
         }
-        else if (colspan !== 0) {
-          continue;
+        else {
+          if (!header && element.contains_progressbar) {
+            if (!progress_td) {
+              progress_td = $('<td />').addClass('progress').append($('<div />').addClass('sfwupload-list-progressbar').append($('<div />').addClass('sfwupload-list-progressbar-status')).append($('<div />').addClass('sfwupload-list-progressbar-glow'))).appendTo(tr);
+            };
+            progress_td_counter++;
+            continue;
+          };
         };
 
-        // Add the colspan if set.
-        if (element.colspan) {
-          column.attr({'colSpan':element.colspan});
+        column = $((header ? '<th />' : '<td />'));
+        content = wrapper.clone().appendTo(column);
+        input = $((element.type == 'textarea' ? '<textarea />' : '<input type="' + element.type + '" />')).attr({'name':name +'_' + fid, 'id':'edit-' + name + '_' + fid}).addClass('form-' + element.type);
+
+        if (header) {
+          // Keep track of colspans
+          if (colspan > 0) colspan--;
+          if (element.colspan) {
+            colspan = element.colspan;
+          }
+          else if (colspan !== 0) {
+            continue;
+          };
+
+          // Add the colspan if set.
+          if (element.colspan) {
+            column.attr({'colSpan':element.colspan});
+          };
+
+          // Add a separator only if we're not dealing with the first or last column
+          if (counter !== ref.num_elements && (counter + (colspan - 1) !== ref.num_elements) && element.add_separator) {
+            content.append(left_span.clone()).append(right_span.clone());
+          };
+
+          content.append(center_span.clone().html((element.title ? element.title : '&nbsp;')));
+        }
+        else {
+          elem_value = (element.value) || element.default_value;
+          // Create the content for this td
+          // Depending on the type the appropriate input field is appended to store the values of this type
+          switch (element.type) {
+            case 'icon':
+            case 'cancel':
+              content.append($('<div />').addClass('sfwupload-list-' + (element.type == 'icon' ? 'mime' : element.type)));
+              break;
+            case 'textfield':
+            case 'textarea':
+              value = (file ? ref.replaceMacros(elem_value, file) : elem_value);
+              content.append($('<span />').html((value !== '' ? value : '&nbsp;'))).append(input.css({'display':'none'}).val((value ? value : '')));
+              break;
+            case 'checkbox':
+              value = (file[name] !== undefined) ? (typeof(file[name]) == 'string' ? (file[name] == '1') : file[name]) : elem_value;
+              // For IE we need to check the checkbox after the content has been added to the tr.
+              // We'll temporarily store it's value in a classname
+              content.append(input.addClass('checkbox ' + (value ? 'checked' : '')));
+              break;
+            case 'markup':
+              value = (file) ? (file[name] !== undefined) ? file[name] : ref.replaceMacros(elem_value, file) : elem_value;
+              content.append($('<div />').addClass('swfupload-markup').attr('id', 'swfupload-markup-' + name).html(value));
+              break;
+            default:
+              break;
+          };
         };
 
-        // Add a separator only if we're not dealing with the first or last column
-        if (counter !== ref.num_elements && (counter + (colspan - 1) !== ref.num_elements) && element.add_separator) {
-          content.append(left_span.clone()).append(right_span.clone());
+        // Add a classname if set.
+        if (element.classname) {
+          column.addClass(element.classname);
         };
 
-        content.append(center_span.clone().html((element.title ? element.title : '&nbsp;')));
-      }
-      else {
-        elem_value = (element.value) || element.default_value;
-        // Create the content for this td
-        // Depending on the type the appropriate input field is appended to store the values of this type
-        switch (element.type) {
-          case 'icon':
-          case 'cancel':
-            content.append($('<div />').addClass('sfwupload-list-' + (element.type == 'icon' ? 'mime' : element.type)));
-            break;
-          case 'textfield':
-          case 'textarea':
-            value = (file ? ref.replaceMacros(elem_value, file) : elem_value);
-            content.append($('<span />').html((value !== '' ? value : '&nbsp;'))).append(input.css({'display':'none'}).val((value ? value : '')));
-            break;
-          case 'checkbox':
-            value = (file[name] !== undefined) ? (typeof(file[name]) == 'string' ? (file[name] == '1') : file[name]) : elem_value;
-            // For IE we need to check the checkbox after the content has been added to the tr.
-            // We'll temporarily store it's value in a classname
-            content.append(input.addClass('checkbox ' + (value ? 'checked' : '')));
-            break;
-          case 'markup':
-            value = (file) ? (file[name] !== undefined) ? file[name] : ref.replaceMacros(elem_value, file) : elem_value;
-            content.append($('<div />').addClass('swfupload-markup').attr('id', 'swfupload-markup-' + name).html(value));
-            break;
-          default:
-            break;
+        if (file && element.contains_progressbar) {
+          column.insertBefore(tr.find('td.progress'));
+        }
+        else {
+          tr.append(column);
         };
       };
 
-      // Add a classname if set.
-      if (element.classname) {
-        column.addClass(element.classname);
+      if (!header && !file) {
+        // Hide the tablerow
+        tr.addClass('hidden');
       };
 
-      if (file && element.contains_progressbar) {
-        column.insertBefore(tr.find('td.progress'));
-      }
-      else {
-        tr.append(column);
+      if (progress_td) {
+        progress_td.attr({'colSpan':progress_td_counter});
       };
-    };
 
-    if (!header && !file) {
-      // Hide the tablerow
-      tr.addClass('hidden');
-    };
+      // Update the checked value of all added checkboxes
+      tr.find('input.checkbox').each(function() {
+        $(this).attr('checked', $(this).hasClass('checked'));
+      });
 
-    if (progress_td) {
-      progress_td.attr({'colSpan':progress_td_counter});
+      if (file) {
+        tr.addClass('processed').find('td.progress').remove();
+      }
+      else {
+        // Create borders
+        var border = $(header ? '<th />' : '<td />').addClass('border').append($('<img />').attr({'src':Drupal.settings.basePath + ref.settings.module_path + '/images/spacer.gif'}).css({'width':'1px'}));
+        tr.prepend(border.clone()).append(border);
+        return tr;
+      };
     };
 
-    // Update the checked value of all added checkboxes 
-    tr.find('input.checkbox').each(function() {
-      $(this).attr('checked', $(this).hasClass('checked'));
-    });
+    /**
+     * A file has been selected. This function creates the markup referring to the new file object
+     */
+    ref.addFileItem = function(file) {
+      // Create the markup for the new file by copying the hidden template
+      var new_file_obj = ref.wrapper_obj.find('.hidden').clone().attr({'id':file.id}).appendTo(ref.wrapper_obj);
+      var dom_obj, value, elem_value;
 
-    if (file) {
-      tr.addClass('processed').find('td.progress').remove();
-    }
-    else {
-      // Create borders
-      var border = $(header ? '<th />' : '<td />').addClass('border').append($('<img />').attr({'src':Drupal.settings.basePath + ref.settings.module_path + '/images/spacer.gif'}).css({'width':'1px'}));
-      tr.prepend(border.clone()).append(border);
-      return tr;
-    };
-  };
+      // Remove tabledrag elements
+      new_file_obj.find('a.tabledrag-handle').remove();
 
-  /**
-   * A file has been selected. This function creates the markup referring to the new file object
-   */
-  ref.addFileItem = function(file) {
-    // Create the markup for the new file by copying the hidden template 
-    var new_file_obj = ref.wrapper_obj.find('.hidden').clone().attr({'id':file.id}).appendTo(ref.wrapper_obj);
-    var dom_obj, value, elem_value;
-
-    // Remove tabledrag elements
-    new_file_obj.find('a.tabledrag-handle').remove();
+      // If it is a file earlier stored (a file in the upload_stack), remove it's progressbar.
+      if (file.filestatus !== -1) {
+        ref.tableRow(false, file);
+      };
 
-    // If it is a file earlier stored (a file in the upload_stack), remove it's progressbar.
-    if (file.filestatus !== -1) {
-      ref.tableRow(false, file);
-    };
+      // Replace macro's
+      for (var name in ref.instance.elements) {
+        dom_obj = new_file_obj.find('#edit-' + name + '_' + (file.fid || '0') + ', #swfupload-markup-' + name);
+        if (dom_obj.size() > 0) {
+          elem_value = (ref.instance.elements[name].value) || ref.instance.elements[name].default_value;
+          value = (file[name] !== undefined) ? file[name] : ref.replaceMacros(elem_value, file);
 
-    // Replace macro's
-    for (var name in ref.instance.elements) {
-      dom_obj = new_file_obj.find('#edit-' + name + '_' + (file.fid || '0') + ', #swfupload-markup-' + name);
-      if (dom_obj.size() > 0) {
-        elem_value = (ref.instance.elements[name].value) || ref.instance.elements[name].default_value;
-        value = (file[name] !== undefined) ? file[name] : ref.replaceMacros(elem_value, file);
+          if (dom_obj[0].tagName.toLowerCase() == 'input' || dom_obj[0].tagName.toLowerCase() == 'textarea') {
+            dom_obj.val(value);
+          }
+          else {
+            dom_obj.html(value).show();
+          };
 
-        if (dom_obj[0].tagName.toLowerCase() == 'input' || dom_obj[0].tagName.toLowerCase() == 'textarea') {
-          dom_obj.val(value);
-        }
-        else {
-          dom_obj.html(value).show();
+          // If the inputfield is hidden, we're dealing with a string.
+          // Look if there is a span of which the text can be replaced
+          if (dom_obj.css('display') == 'none') {
+            dom_obj.parent().find('span').text(value);
+          };
         };
+      };
 
-        // If the inputfield is hidden, we're dealing with a string. 
-        // Look if there is a span of which the text can be replaced
-        if (dom_obj.css('display') == 'none') {
-          dom_obj.parent().find('span').text(value);
-        };
+      if (file.thumb) {
+        // Attach the thumbnail image
+        new_file_obj.find('.sfwupload-list-mime').css({'background-image': 'url(' + file.thumb + ')'});
+      }
+      else {
+        // Add the extension to the mime icon
+        new_file_obj.find('.sfwupload-list-mime').addClass(file.extension);
       };
-    };
 
-    if (file.thumb) {
-      // Attach the thumbnail image
-      new_file_obj.find('.sfwupload-list-mime').css({'background-image': 'url(' + file.thumb + ')'});
-    }
-    else {
-      // Add the extension to the mime icon
-      new_file_obj.find('.sfwupload-list-mime').addClass(file.extension);
-    };
+      // Fix transparency for IE6
+      if ($.cssPNGFix) {
+        new_file_obj.find('.sfwupload-list-mime').cssPNGFix();
+      };
 
-    // Fix transparency for IE6
-    if ($.cssPNGFix) {
-      new_file_obj.find('.sfwupload-list-mime').cssPNGFix();
+      new_file_obj.removeClass('hidden').addClass('draggable');
+      ref.addEventHandlers((file.filestatus == -1 ? 'file_queued' : 'file_added'), file);
     };
 
-    new_file_obj.removeClass('hidden').addClass('draggable');
-    ref.addEventHandlers((file.filestatus == -1 ? 'file_queued' : 'file_added'), file);
-  };
-
-  /**
-   * Attaches all event handlers to the loaded markup
-   */
-  ref.addEventHandlers = function(op, file) {
-    switch (op) {
-      case 'flash_loaded':
-        ref.upload_button_obj.find('.swfupload-wrapper .swfupload').mousedown(function() {
-          $(this).parent().parent().addClass('active');
-        }).mouseup(function() {
-          $(this).parent().parent().removeClass('active');
-        });
-        break;
+    /**
+     * Attaches all event handlers to the loaded markup
+     */
+    ref.addEventHandlers = function(op, file) {
+      switch (op) {
+        case 'flash_loaded':
+          ref.upload_button_obj.find('.swfupload-wrapper .swfupload').mousedown(function() {
+            $(this).parent().parent().addClass('active');
+          }).mouseup(function() {
+            $(this).parent().parent().removeClass('active');
+          });
+          break;
 
-      case 'file_queued':
-        $('#' + file.id).find('.sfwupload-list-cancel').click(function() {
-          ref.cancelUpload(file);
-        });
-        break;
+        case 'file_queued':
+          $('#' + file.id).find('.sfwupload-list-cancel').click(function() {
+            ref.cancelUpload(file);
+          });
+          break;
 
-      case 'file_added':
-        var file_element_obj = $('#' + file.fid);
-        file_element_obj.find('.sfwupload-list-cancel').unbind('click').click(function() {
-          ref.removeFileItem(file);
-        }).disableTextSelect();
-        file_element_obj.find('input:checkbox').bind('click', function() {
-          ref.updateStack(file);
-        });
-        file_element_obj.find('input:text, textarea').blur(function() {
-          ref.toggleInput($(this), false, file);
-        }).keydown(function(e) {
-          ref.key_pressed = e.keyCode;
-          if ((e.keyCode == 27) || (e.keyCode == 13 && $(this).get(0).tagName.toLowerCase() !== 'textarea')) {
-            $(this).blur();
+        case 'file_added':
+          var file_element_obj = $('#' + file.fid);
+          file_element_obj.find('.sfwupload-list-cancel').unbind('click').click(function() {
+            ref.removeFileItem(file);
+          }).disableTextSelect();
+          file_element_obj.find('input:checkbox').bind('click', function() {
+            ref.updateStack(file);
+          });
+          file_element_obj.find('input:text, textarea').blur(function() {
+            ref.toggleInput($(this), false, file);
+          }).keydown(function(e) {
+            ref.key_pressed = e.keyCode;
+            if ((e.keyCode == 27) || (e.keyCode == 13 && $(this).get(0).tagName.toLowerCase() !== 'textarea')) {
+              $(this).blur();
+              return false;
+            };
+          }).parents('td').dblclick(function() {
+            ref.toggleInput($(this).find('span'), true, file);
+          }).find('.wrapper').append($('<a href="#" />').text(Drupal.t('edit')).addClass('toggle-editable').click(function() {
+            ref.toggleInput($(this).parent().find('span'), true, file);
             return false;
-          };
-        }).parents('td').dblclick(function() {
-          ref.toggleInput($(this).find('span'), true, file);
-        }).find('.wrapper').append($('<a href="#" />').text(Drupal.t('edit')).addClass('toggle-editable').click(function() {
-          ref.toggleInput($(this).parent().find('span'), true, file);
-          return false;
-        }));
-        break;
+          }));
+          break;
 
-      case 'drag_enable':
-        // Attach the tabledrag behavior
-        // This will we only executed once.
-        Drupal.attachBehaviors(ref.wrapper_obj);
-    
-        $('tbody tr', ref.wrapper_obj).not('.hidden, .tabledrag-handle-swfupload-moved').each(function() {
-    
-          if (!$('a.tabledrag-handle', $(this)).size()) {
-            Drupal.tableDrag[ref.wrapper_id].makeDraggable(this);
-          };
-    
-          $('a.tabledrag-handle', $(this)).not('.tabledrag-handle-swfupload-moved').each(function() {
-            $(this).appendTo($(this).parents('tr').addClass('tabledrag-handle-swfupload-moved').find('td.drag div.wrapper')).bind('mousedown', function() {
-              $(this).parents('tr').addClass('dragging');
-            });
-          });
-        });
-    
-        $(document).unbind('mouseup', ref.tableDragStop).bind('mouseup', ref.tableDragStop);
-        break;
+        case 'drag_enable':
+          // Attach the tabledrag behavior
+          // This will we only executed once.
+          Drupal.attachBehaviors(ref.wrapper_obj);
 
-      default:
-        break;
-    };
-  };
+          $('tbody tr', ref.wrapper_obj).not('.hidden, .tabledrag-handle-swfupload-moved').each(function() {
 
-  /**
-   * Triggered when the user has stopped dragging a tablerow.
-   */
-  ref.tableDragStop = function() {
-    $('tr', ref.wrapper_obj).removeClass('dragging');
-    $(ref.wrapper_obj).parent().children('.warning').css({'visibility':'hidden'}).remove();
-    ref.updateStack();
-  };
+            if (!$('a.tabledrag-handle', $(this)).size()) {
+              Drupal.tableDrag[ref.wrapper_id].makeDraggable(this);
+            };
 
-  /**
-   * Toggles editability of text spans inside tablerows
-   */
-  ref.toggleInput = function(obj, start, file) {
-    obj.hide().parent().toggleClass('editable-enabled');
-    if (start) {
-      obj.hide().parent().find('input:text, textarea').show().focus().select();
-    }
-    else {
-      if (ref.key_pressed == 27) {
-        obj.val(obj.parent().find('span').html()).hide().parent().find('span').show();
-        return;
-      };
+            $('a.tabledrag-handle', $(this)).not('.tabledrag-handle-swfupload-moved').each(function() {
+              $(this).appendTo($(this).parents('tr').addClass('tabledrag-handle-swfupload-moved').find('td.drag div.wrapper')).bind('mousedown', function() {
+                $(this).parents('tr').addClass('dragging');
+              });
+            });
+          });
 
-      var value = obj.val();
-      if (value == '') {
-        obj.hide().parent().find('span').html('&nbsp;').show();
-      }
-      else {
-        obj.hide().parent().find('span').text((value == '&nbsp;' ? '' : value)).show();
+          $(document).unbind('mouseup', ref.tableDragStop).bind('mouseup', ref.tableDragStop);
+          break;
+
+        default:
+          break;
       };
     };
-    ref.updateStack(file);
-  };
-
-  /**
-   * Launched when the swf has been loaded.
-   */
-  ref.swfUploadLoaded = function() {
-    // Update the stats object in order to let SWFUpload know we've already got some files stored
-    ref.swfu.setStats({successful_uploads: ref.upload_stack_length});
-    ref.addEventHandlers('flash_loaded');
-  };
 
-  /**
-   * The file(s) have been selected.
-   */
-  ref.dialogComplete = function(files_selected, files_queued) {
-    if (ref.settings.file_upload_limit && ref.settings.file_upload_limit !== 0 && (files_selected > ref.settings.file_upload_limit)) {
-      ref.displayMessage(Drupal.t('You can upload only !num !file!', {'!num':ref.settings.file_upload_limit, '!file': Drupal.formatPlural(ref.settings.file_upload_limit, 'file', 'files')}), 'error');
-    }
-    else {
-      ref.uploadNextInQueue();
+    /**
+     * Triggered when the user has stopped dragging a tablerow.
+     */
+    ref.tableDragStop = function() {
+      $('tr', ref.wrapper_obj).removeClass('dragging');
+      $(ref.wrapper_obj).parent().children('.warning').css({'visibility':'hidden'}).remove();
+      ref.updateStack();
     };
-  };
 
-  /**
-   * The file(s) have been selected by the user and added to the upload queue
-   */
-  ref.fileQueued = function(file) {
-    if (ref.settings.file_upload_limit && ref.settings.file_upload_limit !== 0) {
-      // Check if the queued file(s) do not exceed the max number of files
-      var stats = ref.swfu.getStats();
-      if ((ref.upload_stack_length + stats.files_queued) > ref.settings.file_upload_limit) {
-        ref.swfu.cancelUpload(file.id);
-        var queue_space = (ref.settings.file_upload_limit - ref.upload_stack_length);
-        if (queue_space == 0) {
-          ref.displayMessage(Drupal.t('You are not allowed to add more than !num !file!', {'!num':ref.settings.file_upload_limit, '!file': Drupal.formatPlural(ref.settings.file_upload_limit, 'file', 'files')}), 'error');
+    /**
+     * Toggles editability of text spans inside tablerows
+     */
+    ref.toggleInput = function(obj, start, file) {
+      obj.hide().parent().toggleClass('editable-enabled');
+      if (start) {
+        obj.hide().parent().find('input:text, textarea').show().focus().select();
+      }
+      else {
+        if (ref.key_pressed == 27) {
+          obj.val(obj.parent().find('span').html()).hide().parent().find('span').show();
+          return;
+        };
+
+        var value = obj.val();
+        if (value == '') {
+          obj.hide().parent().find('span').html('&nbsp;').show();
         }
         else {
-          ref.displayMessage(Drupal.t('You can upload only !num more !file!', {'!num':queue_space, '!file':Drupal.formatPlural(queue_space, 'file', 'files')}), 'error');
+          obj.hide().parent().find('span').text((value == '&nbsp;' ? '' : value)).show();
         };
-        return;
       };
+      ref.updateStack(file);
     };
-    if (ref.max_queue_size && ref.max_queue_size !== 0) {
-      // Check if the new file does not exceed the max queue size
-      if ((ref.upload_stack_size + file.size) > ref.max_queue_size) {
-        var max_queue_mbs = ref.getMbs(ref.max_queue_size);
-        var file_mbs = ((file.size / 1024) / 1024);
-        ref.swfu.cancelUpload(file.id);
-        ref.displayMessage(Drupal.t('The file size (!num1 MB) exceeds the upload size (!num2 MB) for this page!', {'!num1':file_mbs.toFixed(2), '!num2':max_queue_mbs.toFixed(2)}), 'error');
-        return;
-      };
+
+    /**
+     * Launched when the swf has been loaded.
+     */
+    ref.swfUploadLoaded = function() {
+      // Update the stats object in order to let SWFUpload know we've already got some files stored
+      ref.swfu.setStats({successful_uploads: ref.upload_stack_length});
+      ref.addEventHandlers('flash_loaded');
     };
-    // No problems found, add the new file to the stack.
-    file.extension = ref.getExtension(file.name);
-    ref.queue[file.id] = file;
-    ref.addFileItem(file);
-  };
 
-  /**
-   * Responds on file queue errors 
-   */
-  ref.fileQueueError = function(file, code, message) {
-    switch (code) {
-      case -110: // The file selected is too large
-        var max_file_mbs = ref.getMbs(ref.settings.file_size_limit);
-        var file_mbs = ((file.size / 1024) / 1024);
-        ref.displayMessage(Drupal.t('The file size (!num1 MB) exceeds the file size limit (!num2 MB)!', {'!num1':file_mbs.toFixed(2), '!num2':max_file_mbs.toFixed(2)}), 'error');
-        break;
-      default:
-        break;
+    /**
+     * The file(s) have been selected.
+     */
+    ref.dialogComplete = function(files_selected, files_queued) {
+      if (ref.settings.file_upload_limit && ref.settings.file_upload_limit !== 0 && (files_selected > ref.settings.file_upload_limit)) {
+        ref.displayMessage(Drupal.t('You can upload only !num !file!', {'!num':ref.settings.file_upload_limit, '!file': Drupal.formatPlural(ref.settings.file_upload_limit, 'file', 'files')}), 'error');
+      }
+      else {
+        ref.uploadNextInQueue();
+      };
     };
-  };
 
-  /**
-   * Calculates the MB's from a given string
-   */
-  ref.getMbs = function(size) {
-    // B, KB, MB and GB
-    if (size.indexOf('MB') > -1) {
-      return parseInt(size);
-    }
-    else if (size.indexOf('GB') > -1) {
-      return (parseInt(size) * 1024);
-    }
-    else if (size.indexOf('KB') > -1) {
-      return (parseInt(size) / 1024);
-    }
-    else if (size.indexOf('B') > -1) {
-      return ((parseInt(size) / 1024) / 1024);
+    /**
+     * The file(s) have been selected by the user and added to the upload queue
+     */
+    ref.fileQueued = function(file) {
+      if (ref.settings.file_upload_limit && ref.settings.file_upload_limit !== 0) {
+        // Check if the queued file(s) do not exceed the max number of files
+        var stats = ref.swfu.getStats();
+        if ((ref.upload_stack_length + stats.files_queued) > ref.settings.file_upload_limit) {
+          ref.swfu.cancelUpload(file.id);
+          var queue_space = (ref.settings.file_upload_limit - ref.upload_stack_length);
+          if (queue_space == 0) {
+            ref.displayMessage(Drupal.t('You are not allowed to add more than !num !file!', {'!num':ref.settings.file_upload_limit, '!file': Drupal.formatPlural(ref.settings.file_upload_limit, 'file', 'files')}), 'error');
+          }
+          else {
+            ref.displayMessage(Drupal.t('You can upload only !num more !file!', {'!num':queue_space, '!file':Drupal.formatPlural(queue_space, 'file', 'files')}), 'error');
+          };
+          return;
+        };
+      };
+      if (ref.max_queue_size && ref.max_queue_size !== 0) {
+        // Check if the new file does not exceed the max queue size
+        if ((ref.upload_stack_size + file.size) > ref.max_queue_size) {
+          var max_queue_mbs = ref.getMbs(ref.max_queue_size);
+          var file_mbs = ((file.size / 1024) / 1024);
+          ref.swfu.cancelUpload(file.id);
+          ref.displayMessage(Drupal.t('The file size (!num1 MB) exceeds the upload size (!num2 MB) for this page!', {'!num1':file_mbs.toFixed(2), '!num2':max_queue_mbs.toFixed(2)}), 'error');
+          return;
+        };
+      };
+      // No problems found, add the new file to the stack.
+      file.extension = ref.getExtension(file.name);
+      ref.queue[file.id] = file;
+      ref.addFileItem(file);
     };
-    return false;
-  };
 
-  /**
-   * Displays messages
-   */
-  ref.displayMessage = function(messages, type) {
-    if (typeof(messages) == 'object') {
-      var multiple = (messages.length > 1);
-      var messages_tmp = (multiple ? '<ul>' : '');
-      for (var i in messages) {
-        messages_tmp += (multiple ? '<li>' + messages[i] + '</li>' : messages[i]);
+    /**
+     * Responds on file queue errors
+     */
+    ref.fileQueueError = function(file, code, message) {
+      switch (code) {
+        case -110: // The file selected is too large
+          var max_file_mbs = ref.getMbs(ref.settings.file_size_limit);
+          var file_mbs = ((file.size / 1024) / 1024);
+          ref.displayMessage(Drupal.t('The file size (!num1 MB) exceeds the file size limit (!num2 MB)!', {'!num1':file_mbs.toFixed(2), '!num2':max_file_mbs.toFixed(2)}), 'error');
+          break;
+        default:
+          break;
       };
-      messages = (multiple ? messages_tmp + '</ul>' : messages_tmp);
     };
 
-    if (!ref.message_wrapper_obj) {
-      ref.message_wrapper_obj = $('<div />').addClass('swfupload-messages').insertAfter(ref.wrapper_obj);
-      ref.messages_timeout = setTimeout(function() {ref.hideMessages();}, 5000);
+    /**
+     * Calculates the MB's from a given string
+     */
+    ref.getMbs = function(size) {
+      // B, KB, MB and GB
+      if (size.indexOf('MB') > -1) {
+        return parseInt(size);
+      }
+      else if (size.indexOf('GB') > -1) {
+        return (parseInt(size) * 1024);
+      }
+      else if (size.indexOf('KB') > -1) {
+        return (parseInt(size) / 1024);
+      }
+      else if (size.indexOf('B') > -1) {
+        return ((parseInt(size) / 1024) / 1024);
+      };
+      return false;
     };
 
-    if (!$('div.' + type, ref.message_wrapper_obj).size()) {
-      ref.message_wrapper_obj.append($('<div />').css({'height':'auto', 'opacity':1}).addClass('messages ' + type).html(messages));
-    }
-    else {
-      // The messagewrapper already exists. Add the new message to the wrapper and reset the timeout.
+    /**
+     * Displays messages
+     */
+    ref.displayMessage = function(messages, type) {
+      if (typeof(messages) == 'object') {
+        var multiple = (messages.length > 1);
+        var messages_tmp = (multiple ? '<ul>' : '');
+        for (var i in messages) {
+          messages_tmp += (multiple ? '<li>' + messages[i] + '</li>' : messages[i]);
+        };
+        messages = (multiple ? messages_tmp + '</ul>' : messages_tmp);
+      };
 
-      // Check if the message isn't already displayed
-      if (ref.message_wrapper_obj.html().indexOf(messages) > -1) {
-        return;
+      if (!ref.message_wrapper_obj) {
+        ref.message_wrapper_obj = $('<div />').addClass('swfupload-messages').insertAfter(ref.wrapper_obj);
+        ref.messages_timeout = setTimeout(function() {ref.hideMessages();}, 5000);
       };
 
-      // If the new type differs from the current type, we'll remove the old message.
-      if ((ref.message_wrapper_obj.hasClass('status') && type !== 'status') || (ref.message_wrapper_obj.hasClass('error') && type !== 'error')) {
-        ref.message_wrapper_obj.removeClass('status error').addClass(type).html(messages);
+      if (!$('div.' + type, ref.message_wrapper_obj).size()) {
+        ref.message_wrapper_obj.append($('<div />').css({'height':'auto', 'opacity':1}).addClass('messages ' + type).html(messages));
       }
       else {
-        ref.message_wrapper_obj.append('<br />' + messages);
+        // The messagewrapper already exists. Add the new message to the wrapper and reset the timeout.
+
+        // Check if the message isn't already displayed
+        if (ref.message_wrapper_obj.html().indexOf(messages) > -1) {
+          return;
+        };
+
+        // If the new type differs from the current type, we'll remove the old message.
+        if ((ref.message_wrapper_obj.hasClass('status') && type !== 'status') || (ref.message_wrapper_obj.hasClass('error') && type !== 'error')) {
+          ref.message_wrapper_obj.removeClass('status error').addClass(type).html(messages);
+        }
+        else {
+          ref.message_wrapper_obj.append('<br />' + messages);
+        };
+        clearInterval(ref.messages_timeout);
+        ref.messages_timeout = setTimeout(function() {ref.hideMessages();}, 5000);
       };
-      clearInterval(ref.messages_timeout);
-      ref.messages_timeout = setTimeout(function() {ref.hideMessages();}, 5000);
     };
-  };
 
-  /**
-   * Slowly hides the messages wrapper
-   */
-  ref.hideMessages = function() {
-    ref.message_wrapper_obj.animate({'height':'0px', 'opacity':0}, 'slow', function() {
-      ref.message_wrapper_obj.remove();
-      ref.message_wrapper_obj = false;
-    });
-  };
-
-  /**
-   * Triggers a new upload.
-   */
-  ref.uploadNextInQueue = function() {
-		try {
-		  ref.swfu.startUpload();
-		}
-		catch (err) {
-		  ref.swfu.debug(err);
-		};
-  };
+    /**
+     * Slowly hides the messages wrapper
+     */
+    ref.hideMessages = function() {
+      ref.message_wrapper_obj.animate({'height':'0px', 'opacity':0}, 'slow', function() {
+        ref.message_wrapper_obj.remove();
+        ref.message_wrapper_obj = false;
+      });
+    };
 
-  /**
-   * Adjusts the progress indicator.
-   */
-  ref.uploadProgress = function(file, complete, total) {
-     // We don't want this one to end up to 100% when all bytes are loaded. The progressbar will have an width of 100% on uploadFileComplete
-    var done = Math.round((96 / total)  * complete);
-    $('#' + file.id + ' .sfwupload-list-progressbar-status').css({'width': done + '%'});
-  };
+    /**
+     * Triggers a new upload.
+     */
+    ref.uploadNextInQueue = function() {
+      try {
+        ref.swfu.startUpload();
+      }
+      catch (err) {
+        ref.swfu.debug(err);
+      };
+    };
 
-  /**
-   * Handles upload errors
-   */
-  ref.uploadError = function(file, code, message) {
-    // Check for messages which can be handled as 'status' messages
-    switch (code) {
-      case -240:
-        ref.displayMessage(Drupal.t('The upload limit (!num) has been reached!', {'!num': ref.settings.file_upload_limit}), 'status');
-        return;
-      case -200:
-        message = Drupal.t('Server error!', {'!num': ref.settings.file_upload_limit});
+    /**
+     * Adjusts the progress indicator.
+     */
+    ref.uploadProgress = function(file, complete, total) {
+       // We don't want this one to end up to 100% when all bytes are loaded. The progressbar will have an width of 100% on uploadFileComplete
+      var done = Math.round((96 / total)  * complete);
+      $('#' + file.id + ' .sfwupload-list-progressbar-status').css({'width': done + '%'});
     };
 
-    // Give the user some visual indicators of the event
-    $('#' + file.id + ' .sfwupload-list-progressbar').addClass('stopped').find('.sfwupload-list-progressbar-status').css({'width':'100%'});
-    $('#' + file.id + ' .sfwupload-list-progressbar-glow').append((typeof(message) == 'object' ? message[0] : message));
+    /**
+     * Handles upload errors
+     */
+    ref.uploadError = function(file, code, message) {
+      // Check for messages which can be handled as 'status' messages
+      switch (code) {
+        case -240:
+          ref.displayMessage(Drupal.t('The upload limit (!num) has been reached!', {'!num': ref.settings.file_upload_limit}), 'status');
+          return;
+        case -200:
+          message = Drupal.t('Server error!', {'!num': ref.settings.file_upload_limit});
+      };
+
+      // Give the user some visual indicators of the event
+      $('#' + file.id + ' .sfwupload-list-progressbar').addClass('stopped').find('.sfwupload-list-progressbar-status').css({'width':'100%'});
+      $('#' + file.id + ' .sfwupload-list-progressbar-glow').append((typeof(message) == 'object' ? message[0] : message));
 
-    // If a file is set, we need to remove the added file DOM element
-    if (file) {
-      setTimeout(function() {
-        ref.removeFileItem(file);
-      }, 2000);
+      // If a file is set, we need to remove the added file DOM element
+      if (file) {
+        setTimeout(function() {
+          ref.removeFileItem(file);
+        }, 2000);
+      };
     };
-  };
 
-  /**
-   * Triggered after the upload is succesfully completed.
-   */
-  ref.uploadComplete = function(file) {
-    if (ref.queue[file.id] && !ref.queue[file.id].cancelled) {
-      setTimeout(function() {
-        $('#' + ref.queue[file.id].fid).find('.sfwupload-list-progressbar').animate({'opacity':0}, "slow", function() {
-          file.fid = ref.queue[file.id].fid;
-          ref.tableRow(false, file);
-          ref.updateStack(file);
-          ref.addEventHandlers('file_added', file);
+    /**
+     * Triggered after the upload is succesfully completed.
+     */
+    ref.uploadComplete = function(file) {
+      if (ref.queue[file.id] && !ref.queue[file.id].cancelled) {
+        setTimeout(function() {
+          $('#' + ref.queue[file.id].fid).find('.sfwupload-list-progressbar').animate({'opacity':0}, "slow", function() {
+            file.fid = ref.queue[file.id].fid;
+            ref.tableRow(false, file);
+            ref.updateStack(file);
+            ref.addEventHandlers('file_added', file);
 
-          if (ref.queue[file.id].thumb) {
-            $('.sfwupload-list-mime', $('#' + ref.queue[file.id].fid)).css({'background-image': 'url(' + ref.queue[file.id].thumb + ')'});
-          };
-          ref.upload_button_obj.removeClass('swfupload-error');
-        });
-      }, 1000);
+            if (ref.queue[file.id].thumb) {
+              $('.sfwupload-list-mime', $('#' + ref.queue[file.id].fid)).css({'background-image': 'url(' + ref.queue[file.id].thumb + ')'});
+            };
+            ref.upload_button_obj.removeClass('swfupload-error');
+          });
+        }, 1000);
+      };
+      ref.uploadNextInQueue();
     };
-		ref.uploadNextInQueue();
-  };
 
-  /**
-   * Retrieves the data returned by the server
-   */
-  ref.uploadSuccess = function(file, server_data) {
-    var server_data = Drupal.parseJson(server_data);
+    /**
+     * Retrieves the data returned by the server
+     */
+    ref.uploadSuccess = function(file, server_data) {
+      var server_data = jQuery.parseJSON(server_data);
 
-    // Check for messages returned by the server.
-    if (server_data.messages) {
-
-      // Check if the server returned status messages
+      // Check for messages returned by the server.
       if (server_data.messages) {
-        for (var type in server_data.messages) {
-          if (type !== 'swfupload_error') {
-            ref.displayMessage(server_data.messages[type], type);
+
+        // Check if the server returned status messages
+        if (server_data.messages) {
+          for (var type in server_data.messages) {
+            if (type !== 'swfupload_error') {
+              ref.displayMessage(server_data.messages[type], type);
+            };
           };
         };
-      };
 
-      // Check if the server returned an error
-      if (server_data.messages.swfupload_error) {
-        ref.uploadError(file, null, server_data.messages.swfupload_error);
-        ref.queue[file.id].cancelled = true;
-        return;
+        // Check if the server returned an error
+        if (server_data.messages.swfupload_error) {
+          ref.uploadError(file, null, server_data.messages.swfupload_error);
+          ref.queue[file.id].cancelled = true;
+          return;
+        };
       };
-    };
 
-    // No errors. Complete the fileupload.
-    ref.queue[file.id].fid = server_data.file.fid;
-    $('#' + file.id).attr({'id':server_data.file.fid}).find('.sfwupload-list-progressbar-status').css({'width':'100%'}).parent().addClass('complete');
+      // No errors. Complete the fileupload.
+      ref.queue[file.id].fid = server_data.file.fid;
+      $('#' + file.id).attr({'id':server_data.file.fid}).find('.sfwupload-list-progressbar-status').css({'width':'100%'}).parent().addClass('complete');
 
-    if (server_data.file.thumb) {
-      ref.queue[file.id].thumb = server_data.file.thumb;
+      if (server_data.file.thumb) {
+        ref.queue[file.id].thumb = server_data.file.thumb;
+      };
     };
-  };
 
-  /**
-   * Updates the value of the hidden input field which stores all uploaded files
-   */
-  ref.updateStack = function(file) {
-    var fid, input_field, element;
-    var old_upload_stack = ref.upload_stack;
-    var total_size = 0;
-    ref.upload_stack = {};
+    /**
+     * Updates the value of the hidden input field which stores all uploaded files
+     */
+    ref.updateStack = function(file) {
+      var fid, input_field, element;
+      var old_upload_stack = ref.upload_stack;
+      var total_size = 0;
+      ref.upload_stack = {};
 
-    ref.wrapper_obj.find('.processed').each(function() {
-      fid = $(this).attr('id');
+      ref.wrapper_obj.find('.processed').each(function() {
+        fid = $(this).attr('id');
 
-      // If no file is secified, the function is called after sorting
-      // There are no new values so the file object is not needed
-      // We only need to change the order of the stack 
-      if (!file) {
-        ref.upload_stack[fid] = old_upload_stack[fid];
-      }
-      else {
-        ref.upload_stack[fid] = {filename:file.filename || file.name, fid:fid};
-        total_size += parseInt(file.size);
-        for (var name in ref.instance.elements) {
-          input_field = $('#edit-' + name + '_' + fid);
-          if (input_field.size() !== 0) {
-            ref.upload_stack[fid][name] = (input_field.attr('type') == 'checkbox') ? input_field.attr('checked') : input_field.val();
+        // If no file is secified, the function is called after sorting
+        // There are no new values so the file object is not needed
+        // We only need to change the order of the stack
+        if (!file) {
+          ref.upload_stack[fid] = old_upload_stack[fid];
+        }
+        else {
+          ref.upload_stack[fid] = {filename:file.filename || file.name, fid:fid};
+          total_size += parseInt(file.size);
+          for (var name in ref.instance.elements) {
+            input_field = $('#edit-' + name + '_' + fid);
+            if (input_field.size() !== 0) {
+              ref.upload_stack[fid][name] = (input_field.attr('type') == 'checkbox') ? input_field.attr('checked') : input_field.val();
+            };
           };
         };
-      };
-    });
-    ref.upload_stack_size = total_size;
-    ref.upload_stack_length = ref.objectLength(ref.upload_stack);
-    ref.upload_stack_obj.val(ref.toJson(ref.upload_stack));
-    ref.addEventHandlers('drag_enable');
+      });
+      ref.upload_stack_size = total_size;
+      ref.upload_stack_length = ref.objectLength(ref.upload_stack);
+      ref.upload_stack_obj.val(ref.toJson(ref.upload_stack));
+      ref.addEventHandlers('drag_enable');
 
-    if ((ref.settings.file_upload_limit > ref.upload_stack_length) || ref.settings.file_upload_limit === 0) {
-      ref.upload_button_obj.removeClass('disabled').css({opacity:1});
-    }
-    else {
-      ref.upload_button_obj.addClass('disabled').css({opacity:0.4});
+      if ((ref.settings.file_upload_limit > ref.upload_stack_length) || ref.settings.file_upload_limit === 0) {
+        ref.upload_button_obj.removeClass('disabled').css({opacity:1});
+      }
+      else {
+        ref.upload_button_obj.addClass('disabled').css({opacity:0.4});
+      };
     };
-  };
 
-  /**
-   * Aborts a file upload
-   */
-  ref.cancelUpload = function(file) {
-    // Check if the file is still being uploaded.
-    if (ref.swfu.getFile(file.id)) {
-      // Abort the upload
-      ref.swfu.cancelUpload(file.id);
-      ref.queue[file.id].cancelled = true;
-      setTimeout(function() {
-        ref.removeFileItem(file);
-      }, 1000);
+    /**
+     * Aborts a file upload
+     */
+    ref.cancelUpload = function(file) {
+      // Check if the file is still being uploaded.
+      if (ref.swfu.getFile(file.id)) {
+        // Abort the upload
+        ref.swfu.cancelUpload(file.id);
+        ref.queue[file.id].cancelled = true;
+        setTimeout(function() {
+          ref.removeFileItem(file);
+        }, 1000);
+      };
     };
-  };
 
-  /**
-   * Removes a file form the list
-   */
-  ref.removeFileItem = function(file) {
-    var file_tr = $('#' + (file.fid ? file.fid : file.id)).removeClass('processed');
-    var file_tds = file_tr.find('td');
-    var current_height = file_tr.height();
-    var cleared = false;
+    /**
+     * Removes a file form the list
+     */
+    ref.removeFileItem = function(file) {
+      var file_tr = $('#' + (file.fid ? file.fid : file.id)).removeClass('processed');
+      var file_tds = file_tr.find('td');
+      var current_height = file_tr.height();
+      var cleared = false;
 
-    // Delete the file from the queue
-    delete(ref.queue[file.id]);
+      // Delete the file from the queue
+      delete(ref.queue[file.id]);
 
-    // Animate the deletion of the file's table row
-    // First fade out the contents of the td's
-    file_tds.find('div, input').animate({opacity:0}, 'fast', function() {
-      file_tds.each(function() {
-        // The contents are not visible anymore, so we can remove it.
-        $(this).html('');
-      });
+      // Animate the deletion of the file's table row
+      // First fade out the contents of the td's
+      file_tds.find('div, input').animate({opacity:0}, 'fast', function() {
+        file_tds.each(function() {
+          // The contents are not visible anymore, so we can remove it.
+          $(this).html('');
+        });
 
-      // Since animate({height:0}) does not work for tr and td's, we need to declare our own interval
-      var intv = setInterval(function() {
-        current_height -= 5;
-        file_tds.height(current_height);
-        file_tr.css({opacity: current_height * 4});
+        // Since animate({height:0}) does not work for tr and td's, we need to declare our own interval
+        var intv = setInterval(function() {
+          current_height -= 5;
+          file_tds.height(current_height);
+          file_tr.css({opacity: current_height * 4});
 
-        // The animation is complete
-        if(current_height <= 5) {
-          if (!cleared) {
-            cleared = true;
-            file_tr.remove();
-            clearInterval(intv);
+          // The animation is complete
+          if(current_height <= 5) {
+            if (!cleared) {
+              cleared = true;
+              file_tr.remove();
+              clearInterval(intv);
 
-            // Reset the successfull upload queue
-            var stats = ref.swfu.getStats();
-            stats.successful_uploads--;
-            ref.swfu.setStats(stats);
+              // Reset the successfull upload queue
+              var stats = ref.swfu.getStats();
+              stats.successful_uploads--;
+              ref.swfu.setStats(stats);
 
-            if (file_tr) {
-              // Update the hidden input field
-              ref.updateStack(file);
+              if (file_tr) {
+                // Update the hidden input field
+                ref.updateStack(file);
+              };
             };
           };
-        };
-      }, 50);
-    });
-  };
+        }, 50);
+      });
+    };
 
-  /**
-   * Retrieve the number of elements in an object
-   */
-  ref.objectLength = function(obj) {
-    if (obj.status !== undefined && obj.status == 0) return 0;
+    /**
+     * Retrieve the number of elements in an object
+     */
+    ref.objectLength = function(obj) {
+      if (obj.status !== undefined && obj.status == 0) return 0;
 
-    var count = 0;
-    for (var i in obj)
-    count++;
-    return count;
-  };
+      var count = 0;
+      for (var i in obj)
+      count++;
+      return count;
+    };
 
-  /**
-   * Parses an object to a json formatted string
-   */
-  ref.toJson = function(v) {
-    switch (typeof v) {
-      case 'boolean':
-        return v == true ? 'true' : 'false';
-      case 'number':
-        return v;
-      case 'string':
-        return '"'+ v.replace(/\n/g, '\\n') +'"';
-      case 'object':
-        var output = '';
-        for(i in v) {
-          output += (output ? ',' : '') + '"' + i + '":' + ref.toJson(v[i]);
-        }
-        return '{' + output + '}';
-      default:
-        return 'null';
+    /**
+     * Parses an object to a json formatted string
+     */
+    ref.toJson = function(v) {
+      switch (typeof v) {
+        case 'boolean':
+          return v == true ? 'true' : 'false';
+        case 'number':
+          return v;
+        case 'string':
+          return '"'+ v.replace(/\n/g, '\\n') +'"';
+        case 'object':
+          var output = '';
+          for(i in v) {
+            output += (output ? ',' : '') + '"' + i + '":' + ref.toJson(v[i]);
+          }
+          return '{' + output + '}';
+        default:
+          return 'null';
+      };
     };
-  };
 
-  /**
-   * 
-   */
-  ref.getExtension = function(file_name) {
-    return file_name.substring(file_name.lastIndexOf('.') + 1).toLowerCase();
-  };
+    /**
+     *
+     */
+    ref.getExtension = function(file_name) {
+      return file_name.substring(file_name.lastIndexOf('.') + 1).toLowerCase();
+    };
 
-  /**
-   * Replaces default values from ref.instance.elements to file values
-   * @see ref.uploadComplete
-   */
-  ref.replaceMacros = function(value, file) {
-    if (!value || value == 0) {
-      return false;
-    }
-    else if (value == 1) {
-      return true;
-    }
-    else {
-      var macros = {'[filename]':file.name, '{fid}':file.fid};
-      for (var i in macros) {
-        value = value.replace(i, macros[i]);
+    /**
+     * Replaces default values from ref.instance.elements to file values
+     * @see ref.uploadComplete
+     */
+    ref.replaceMacros = function(value, file) {
+      if (!value || value == 0) {
+        return false;
+      }
+      else if (value == 1) {
+        return true;
+      }
+      else {
+        var macros = {'[filename]':file.name, '{fid}':file.fid};
+        for (var i in macros) {
+          value = value.replace(i, macros[i]);
+        };
+        return value;
       };
-      return value;
     };
-  };
 
-  /**
-   * Reverses the order of an object
-   */
-  ref.objReverse = function(obj) {
-    var temp_arr = [];
-    var temp_obj = {};
+    /**
+     * Reverses the order of an object
+     */
+    ref.objReverse = function(obj) {
+      var temp_arr = [];
+      var temp_obj = {};
 
-    for (var i in obj) {
-      temp_arr.push({key:i, data:obj[i]});
+      for (var i in obj) {
+        temp_arr.push({key:i, data:obj[i]});
+      };
+      temp_arr = temp_arr.reverse();
+      for (var i in temp_arr) {
+        temp_obj[temp_arr[i].key] = temp_arr[i].data;
+      };
+      return temp_obj;
     };
-    temp_arr = temp_arr.reverse();
-    for (var i in temp_arr) {
-      temp_obj[temp_arr[i].key] = temp_arr[i].data;
-    };    
-    return temp_obj;
-  };
 
-  return ref;
-};
-
-/**
- * Overwrite for the TableDrag markChanged function
- * Allows to place the marker in an other table drawer than the first one.
- */
-Drupal.tableDrag.prototype.row.prototype.markChanged = function() {
-  var marker = Drupal.theme('tableDragChangedMarker');
-  var cell = ($('td.drag .wrapper', this.element)) || $('td:first', this.element);
-  if ($('span.tabledrag-changed', cell).length == 0) {
-    cell.append(marker);
+    return ref;
   };
-};
-
-/**
- * Disables text selection on the DOM element the behavior is attached to.
- */
-jQuery.fn.disableTextSelect = function() {
-  return this.each(function() {
-    $(this).css({
-      'MozUserSelect' : 'none'
-    }).bind('selectstart', function() {
-      return false;
-    }).mousedown(function() {
-      return false;
-    });
-  });
-};
 
-$(function() {
-  if (Drupal.settings.swfupload_settings) {
-    Drupal.swfu = {};
-    var settings = Drupal.settings.swfupload_settings;
+  $(function() {
+    if (Drupal.settings.swfupload_settings) {
+      Drupal.swfu = {};
+      var settings = Drupal.settings.swfupload_settings;
 
-    for (var id in settings) {
-      Drupal.swfu[id] = new SWFU(id, settings[id]);
-      Drupal.swfu[id].init();
+      for (var id in settings) {
+        Drupal.swfu[id] = new SWFU(id, settings[id]);
+        Drupal.swfu[id].init();
+      };
     };
-  };
-});
+  });
+})(jQuery);
\ No newline at end of file
-- 
1.7.7


From e9cd28dfcb2c0bc313672f70e6c2f82ea52f4056 Mon Sep 17 00:00:00 2001
From: Jonathan Jordan <jonathan@metaltoad.com>
Date: Tue, 15 Nov 2011 11:29:02 -0800
Subject: [PATCH 17/30] Changed list_field and list_default to new settings
 display_field and display_default.

---
 swfupload.module |   14 +++++++-------
 1 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/swfupload.module b/swfupload.module
index fd3bfab..505eeb2 100644
--- a/swfupload.module
+++ b/swfupload.module
@@ -114,6 +114,7 @@ function swfupload_field_widget_form(&$form, &$form_state, $field, $instance, $l
   $element['#type'] = 'swfupload_widget';
   $element['#default_value'] = $items;
   $element['#theme'] = 'swfupload_widget';
+  $element['#after_build'] = array('swfupload_add_js');
 
   return $element;
 }
@@ -166,17 +167,16 @@ function swfupload_library() {
  * This function is called after the FAPI element is processed.
  * Here we can safely attach our javascript
  */
-function swfupload_add_js($element) {
+function swfupload_add_js($element, $form_state) {
   // Get the path to the swfupload module.
   $path = drupal_get_path('module', 'swfupload');
 
-  $field = field_info_field($element['#field_name']);
-
+  $field = $form_state['field'][$element['#field_name']][$element['#language']]['field'];
   if (drupal_add_library('swfupload', 'swfupload') !== FALSE) {
     // Put the values of the list field and description field in the widget array
     // so we can pass it to our hook_swfupload implementation.
-    $field['widget']['list_field'] = $field['list_field'];
-    $field['widget']['list_default'] = $field['list_default'];
+    $field['widget']['display_field'] = $field['settings']['display_field'];
+    $field['widget']['display_default'] = $field['settings']['display_default'];
     $field['widget']['description_field'] = $field['description_field'];
 
     $limit = ($field['multiple'] == 1 ? 0 : ($field['multiple'] == 0 ? 1 : $field['multiple']));
@@ -249,11 +249,11 @@ function swfupload_swfupload(&$file, $op, &$instance, $widget) {
         $instance->elements['drag']['title'] = t('Description');
         unset($instance->elements['filename']);
       }
-      if ($widget->list_field) {
+      if ($widget->display_field) {
         $instance->elements['list'] = array(
           'title' => t('List'),
           'type' => 'checkbox',
-          'default_value' => $widget->list_default,
+          'default_value' => $widget->display_default,
           'class' => 'checkbox',
           'contains_progressbar' => TRUE,
           'add_separator' => TRUE,
-- 
1.7.7


From 5223e16ff8f7c9fc69f12dab485bbc0bada1f68c Mon Sep 17 00:00:00 2001
From: Jonathan Jordan <jonathan@metaltoad.com>
Date: Mon, 21 Nov 2011 13:02:03 -0800
Subject: [PATCH 18/30] Replaced multiple with cardinality.

---
 swfupload.module |    5 +++--
 1 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/swfupload.module b/swfupload.module
index 505eeb2..a46830b 100644
--- a/swfupload.module
+++ b/swfupload.module
@@ -172,14 +172,15 @@ function swfupload_add_js($element, $form_state) {
   $path = drupal_get_path('module', 'swfupload');
 
   $field = $form_state['field'][$element['#field_name']][$element['#language']]['field'];
+
   if (drupal_add_library('swfupload', 'swfupload') !== FALSE) {
     // Put the values of the list field and description field in the widget array
     // so we can pass it to our hook_swfupload implementation.
     $field['widget']['display_field'] = $field['settings']['display_field'];
     $field['widget']['display_default'] = $field['settings']['display_default'];
-    $field['widget']['description_field'] = $field['description_field'];
+    //$field['widget']['description_field'] = $field['description_field'];
 
-    $limit = ($field['multiple'] == 1 ? 0 : ($field['multiple'] == 0 ? 1 : $field['multiple']));
+    $limit = ($field['cardinality'] == -1) ? 0 : $field['cardinality'];
 
     $flash_url = drupal_get_path('module', 'swfupload') .'/library/swfupload.swf';
 
-- 
1.7.7


From 2b0550669caf01d652c2df8c6dfeba5c4a3b90b1 Mon Sep 17 00:00:00 2001
From: Jonathan Jordan <jonathan@metaltoad.com>
Date: Tue, 22 Nov 2011 09:39:43 -0800
Subject: [PATCH 19/30] Fixed settings that have moved to instance settings.

---
 swfupload.module |   14 +++++++-------
 1 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/swfupload.module b/swfupload.module
index a46830b..c670474 100644
--- a/swfupload.module
+++ b/swfupload.module
@@ -170,15 +170,15 @@ function swfupload_library() {
 function swfupload_add_js($element, $form_state) {
   // Get the path to the swfupload module.
   $path = drupal_get_path('module', 'swfupload');
-
+  
   $field = $form_state['field'][$element['#field_name']][$element['#language']]['field'];
-
+  $instance = $form_state['field'][$element['#field_name']][$element['#language']]['instance'];
   if (drupal_add_library('swfupload', 'swfupload') !== FALSE) {
     // Put the values of the list field and description field in the widget array
     // so we can pass it to our hook_swfupload implementation.
     $field['widget']['display_field'] = $field['settings']['display_field'];
     $field['widget']['display_default'] = $field['settings']['display_default'];
-    //$field['widget']['description_field'] = $field['description_field'];
+    $field['widget']['description_field'] = $instance['settings']['description_field'];
 
     $limit = ($field['cardinality'] == -1) ? 0 : $field['cardinality'];
 
@@ -193,18 +193,18 @@ function swfupload_add_js($element, $form_state) {
       'file_queue_limit' => $limit,
       'post_params' => array(
         'sid' => _post_key(),
-        'file_path' => file_directory_path() . '/' . $field['widget']['file_path'],
+        'file_path' => file_directory_path() . '/' . $instance['settings']['file_directory'],
         'op' => 'move_uploaded_file',
         'instance' => swfupload_to_js(array('name' => $element['#field_name'])),
         'widget' => swfupload_to_js($field['widget']),
       ),
-      'file_size_limit' => ($field['widget']['max_filesize_per_file'] ? (parse_size($field['widget']['max_filesize_per_file']) / 1048576) . 'MB' : 0),
-      'file_types' => (empty($field['widget']['file_extensions']) ? '' : '*.' . str_replace(" ", ";*.", $field['widget']['file_extensions'])),
+      'file_size_limit' => ($instance['settings']['max_filesize'] ? (parse_size($instance['settings']['max_filesize']) / 1048576) . 'MB' : 0),
+      'file_types' => (empty($instance['settings']['file_extensions']) ? '' : '*.' . str_replace(" ", ";*.", $instance['settings']['file_extensions'])),
       'file_types_description' => ($element['#description'] ? $element['#description'] : ''),
       'file_upload_limit' => $limit,
       'custom_settings' => array(
         'upload_stack_value' => (!empty($element['#value'])) ? swfupload_to_js($element['#value']) : '[]',
-        'max_queue_size' => ($field['widget']['max_filesize_per_node'] ? $field['widget']['max_filesize_per_node'] : 0),
+        'max_queue_size' => 0,
       ),
     );
     drupal_add_js('misc/tabledrag.js', array('type' => 'file', 'weight' => JS_LIBRARY));
-- 
1.7.7


From 575c65c5654e6fb4239302c44441d00c3a0e2513 Mon Sep 17 00:00:00 2001
From: Jonathan Jordan <jonathan@metaltoad.com>
Date: Wed, 23 Nov 2011 14:54:10 -0800
Subject: [PATCH 20/30] Added missing settings to get rid of PHP warnings.

---
 swfupload.module     |    7 ++++++-
 swfupload_widget.inc |    5 ++++-
 2 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/swfupload.module b/swfupload.module
index c670474..27a65ff 100644
--- a/swfupload.module
+++ b/swfupload.module
@@ -105,6 +105,8 @@ function swfupload_upload_access() {
  * Implements hook_field_widget_form().
  */
 function swfupload_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {
+  $instance['settings']['max_resolution'] = 0;
+  $instance['settings']['min_resolution'] = 0;
   if (module_exists('image')) {
     $element += image_field_widget_form($form, $form_state, $field, $instance, $langcode, $items, $delta, $element);
   } else {
@@ -170,7 +172,7 @@ function swfupload_library() {
 function swfupload_add_js($element, $form_state) {
   // Get the path to the swfupload module.
   $path = drupal_get_path('module', 'swfupload');
-  
+
   $field = $form_state['field'][$element['#field_name']][$element['#language']]['field'];
   $instance = $form_state['field'][$element['#field_name']][$element['#language']]['instance'];
   if (drupal_add_library('swfupload', 'swfupload') !== FALSE) {
@@ -179,6 +181,9 @@ function swfupload_add_js($element, $form_state) {
     $field['widget']['display_field'] = $field['settings']['display_field'];
     $field['widget']['display_default'] = $field['settings']['display_default'];
     $field['widget']['description_field'] = $instance['settings']['description_field'];
+    $field['widget']['file_extensions'] = $instance['settings']['file_extensions'];
+    $field['widget']['max_filesize_per_file'] = $instance['settings']['max_filesize'];
+    $field['widget']['max_filesize_per_node'] = 0;
 
     $limit = ($field['cardinality'] == -1) ? 0 : $field['cardinality'];
 
diff --git a/swfupload_widget.inc b/swfupload_widget.inc
index e8beec0..0b96b2f 100755
--- a/swfupload_widget.inc
+++ b/swfupload_widget.inc
@@ -13,6 +13,10 @@ function swfupload_field_widget_info() {
     'swfupload_widget' => array(
       'label' => t('SWFUpload'),
       'field types' => array('file'),
+      'settings' => array(
+        'progress_indicator' => 'throbber',
+        'preview_image_style' => 'thumbnail',
+      ),
       'behaviors' => array(
         'multiple values' => FIELD_BEHAVIOR_CUSTOM,
         'default value' => FIELD_BEHAVIOR_NONE,
@@ -131,4 +135,3 @@ function swfupload_field_widget_settings_form($field, $instance) {
 
   return $form;
 }
-
-- 
1.7.7


From a87b01dc2d7ee1ba1b5a73516634d0670e70171d Mon Sep 17 00:00:00 2001
From: Jonathan Jordan <jonathan@metaltoad.com>
Date: Wed, 23 Nov 2011 15:08:23 -0800
Subject: [PATCH 21/30] Added leading slash to flash url to avoid a 404 error,
 which was being passed to Drupal in the default
 htaccess, resulting in a 302, causing issues on Macs
 (http://demo.swfupload.org/Documentation/).

---
 swfupload.module |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/swfupload.module b/swfupload.module
index 27a65ff..5744017 100644
--- a/swfupload.module
+++ b/swfupload.module
@@ -187,8 +187,8 @@ function swfupload_add_js($element, $form_state) {
 
     $limit = ($field['cardinality'] == -1) ? 0 : $field['cardinality'];
 
-    $flash_url = drupal_get_path('module', 'swfupload') .'/library/swfupload.swf';
-
+    $flash_url = '/'. drupal_get_path('module', 'swfupload') .'/library/swfupload.swf';
+    
     $settings['swfupload_settings'][$element['#id']] = array(
       'module_path' => $path,
       'flash_url' => $flash_url,
-- 
1.7.7


From 127857a5912e52247d4cb1596769c0fa3313e433 Mon Sep 17 00:00:00 2001
From: Jonathan Jordan <jonathan@metaltoad.com>
Date: Mon, 28 Nov 2011 08:53:36 -0800
Subject: [PATCH 22/30] Modified so that image field functions are only used
 when it is an image field.

---
 swfupload.admin.inc  |    7 +++-
 swfupload.module     |   68 ++++++++++++++++++++++++++++----------------------
 swfupload_widget.inc |    6 ++--
 3 files changed, 46 insertions(+), 35 deletions(-)

diff --git a/swfupload.admin.inc b/swfupload.admin.inc
index 6953384..cff914c 100755
--- a/swfupload.admin.inc
+++ b/swfupload.admin.inc
@@ -11,13 +11,16 @@
  */
 function swfupload_js() {
   $p = (object) $_POST;
+
   $op = $p->op;
-  $file = json_decode($p->file);
+  $file = (property_exists($p, 'file')) ? json_decode($p->file) : new stdClass();
   $instance = json_decode($p->instance);
   $widget = json_decode($p->widget);
   $file_path = $p->file_path;
   unset($p);
 
+  $instance->elements = array();
+
   switch ($op) {
     case 'init':
       // Add the default callback functions for the SWF Upload
@@ -118,7 +121,7 @@ function theme_swfupload_widget($variables) {
   $title = ($element['#title']) ? $element['#title'] : t('Upload new !file', array('!file' => ($element['#max_files'] > 1 ? t('file(s)') : t('file'))));
   $output[] = '<div id="' . $element['#id'] . '" ' . drupal_attributes($element['#attributes']) . '>';
   $output[] = '  <div class="swfupload-wrapper">';
-  $output[] = '    <div id="' . $element['#name'] . '-swfwrapper">&nbsp;</div>';
+  $output[] = '    <div id="' . $element['#field_name'] . '-swfwrapper">&nbsp;</div>';
   $output[] = '  </div>';
   $output[] = '  <div class="left">&nbsp;</div>';
   $output[] = '  <div class="center">' . $title . '</div>';
diff --git a/swfupload.module b/swfupload.module
index 5744017..f040300 100644
--- a/swfupload.module
+++ b/swfupload.module
@@ -43,7 +43,7 @@ function swfupload_upload_access() {
   if (!empty($p->sid)) {
     // $hash_arr[0] is the uid the user wants to athenticate for.
     // $hash_arr[1] is the md5-hashed sid of drupals authetication token.
-    $hash_arr = split("\*", hex2bin($p->sid));
+    $hash_arr = explode("*", hex2bin($p->sid));
     $uid = $hash_arr[0];
     $token = $hash_arr[1];
 
@@ -54,8 +54,8 @@ function swfupload_upload_access() {
     }
 
     // Get all session for the provided user
-    $result = db_select('sessions')
-      ->fields('sid')
+    $result = db_select('sessions', 's')
+      ->fields('s', array('sid'))
       ->condition('uid', $uid)
       ->execute();
     // There is no user with that uid, deny permission.
@@ -105,15 +105,13 @@ function swfupload_upload_access() {
  * Implements hook_field_widget_form().
  */
 function swfupload_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {
-  $instance['settings']['max_resolution'] = 0;
-  $instance['settings']['min_resolution'] = 0;
-  if (module_exists('image')) {
+  if (module_exists('image') && $field['type'] == 'image') {
     $element += image_field_widget_form($form, $form_state, $field, $instance, $langcode, $items, $delta, $element);
   } else {
     $element += file_field_widget_form($form, $form_state, $field, $instance, $langcode, $items, $delta, $element);
   }
 
-  $element['#type'] = 'swfupload_widget';
+  //$element['#type'] = 'swfupload_widget';
   $element['#default_value'] = $items;
   $element['#theme'] = 'swfupload_widget';
   $element['#after_build'] = array('swfupload_add_js');
@@ -172,29 +170,31 @@ function swfupload_library() {
 function swfupload_add_js($element, $form_state) {
   // Get the path to the swfupload module.
   $path = drupal_get_path('module', 'swfupload');
-
+dpm($element);
   $field = $form_state['field'][$element['#field_name']][$element['#language']]['field'];
   $instance = $form_state['field'][$element['#field_name']][$element['#language']]['instance'];
   if (drupal_add_library('swfupload', 'swfupload') !== FALSE) {
     // Put the values of the list field and description field in the widget array
     // so we can pass it to our hook_swfupload implementation.
-    $field['widget']['display_field'] = $field['settings']['display_field'];
-    $field['widget']['display_default'] = $field['settings']['display_default'];
-    $field['widget']['description_field'] = $instance['settings']['description_field'];
+    $field['widget']['display_field'] = isset($field['settings']['display_field']) ? $field['settings']['display_field'] : 0;
+    $field['widget']['display_default'] = isset($field['settings']['display_default']) ? $field['settings']['display_default'] : 0;
+    $field['widget']['description_field'] = isset($field['settings']['description_field']) ? $instance['settings']['description_field'] : 0;
     $field['widget']['file_extensions'] = $instance['settings']['file_extensions'];
     $field['widget']['max_filesize_per_file'] = $instance['settings']['max_filesize'];
     $field['widget']['max_filesize_per_node'] = 0;
+    $field['widget']['max_resolution'] = isset($instance['settings']['max_resolution']) ? $instance['settings']['max_resolution'] : 0;
+    $field['widget']['min_resolution'] = isset($instance['settings']['min_resolution']) ? $instance['settings']['min_resolution'] : 0;
 
     $limit = ($field['cardinality'] == -1) ? 0 : $field['cardinality'];
 
     $flash_url = '/'. drupal_get_path('module', 'swfupload') .'/library/swfupload.swf';
-    
+
     $settings['swfupload_settings'][$element['#id']] = array(
       'module_path' => $path,
       'flash_url' => $flash_url,
       'upload_url' => url('swfupload'), // Relative to the SWF file
       'upload_button_id' => $element['#id'],
-      'file_post_name' => $element['#name'],
+      'file_post_name' => $element['#field_name'],
       'file_queue_limit' => $limit,
       'post_params' => array(
         'sid' => _post_key(),
@@ -246,6 +246,7 @@ function hex2bin($h) {
  * Implements hook_swfupload().
  */
 function swfupload_swfupload(&$file, $op, &$instance, $widget) {
+  watchdog('swfupload', 'File (@type): @file; @op; @instance; @widget', array('@type' => gettype($file), '@file' => print_r($file, 1), '@op' => $op, '@instance' => print_r($instance, 1), '@widget' => print_r($widget, 1)));
   switch ($op) {
     case 'init':
       $columns = 0;
@@ -270,7 +271,7 @@ function swfupload_swfupload(&$file, $op, &$instance, $widget) {
         'alt' => t('Alt'),
         'title' => t('Title'),
       ) as $elem => $title) {
-        if ($widget->{"custom_$elem"}) {
+        if (property_exists($widget, "custom_$elem") && $widget->{"custom_$elem"}) {
           $instance->elements[$elem] = array(
             'title' => $title,
             'type' => ($widget->{$elem . '_type'} ? $widget->{$elem . '_type'} : 'textfield'),
@@ -304,28 +305,35 @@ function swfupload_swfupload(&$file, $op, &$instance, $widget) {
         return;
       }
 
-      $_FILES['files']['name'][$instance->name] = $_FILES[$instance->name]['name'];
-      $_FILES['files']['type'][$instance->name] = $_FILES[$instance->name]['type'];
-      $_FILES['files']['tmp_name'][$instance->name] = $_FILES[$instance->name]['tmp_name'];
-      $_FILES['files']['error'][$instance->name] = $_FILES[$instance->name]['error'];
-      $_FILES['files']['size'][$instance->name] = $_FILES[$instance->name]['size'];
+      watchdog('swfupload', 'File array: @filearr', array('@filearr' => print_r($_FILES, 1)));
 
-      // Replace tokens.
-      if (module_exists('token')) {
-        $file->file_path = token_replace($file->file_path, 'user');
-      }
+      $langs = array_keys($_FILES[$instance->name]['name']);
 
-      // Check if the file directory exists
-      field_file_check_directory($file->file_path, FILE_CREATE_DIRECTORY);
+      foreach ($langs as $lang) {
+        $upload_name = $instance->name .'_'. $lang;
+        $_FILES['files']['name'][$upload_name] = $_FILES[$instance->name]['name'][$lang];
+        $_FILES['files']['type'][$upload_name] = $_FILES[$instance->name]['type'][$lang];
+        $_FILES['files']['tmp_name'][$upload_name] = $_FILES[$instance->name]['tmp_name'][$lang];
+        $_FILES['files']['error'][$upload_name] = $_FILES[$instance->name]['error'][$lang];
+        $_FILES['files']['size'][$upload_name] = $_FILES[$instance->name]['size'][$lang];
 
-      if (user_access('upload files with swfupload') && ($file = file_save_upload($instance->name, $file->validators, $file->file_path))) {
-        if (image_get_info($file->filepath)) {
-          $file->thumb = file_create_url(drupal_encode_path(swfupload_thumb_path($file, TRUE)));
+        // Replace tokens.
+        if (module_exists('token')) {
+          $file->file_path = token_replace($file->file_path, array('user' => NULL));
         }
+
+        // Check if the file directory exists
+        file_prepare_directory($file->file_path, FILE_CREATE_DIRECTORY);
+
+        if (user_access('upload files with swfupload') && ($file = file_save_upload($upload_name, $file->validators, $file->file_path))) {
+          if (image_get_info($file->filepath)) {
+            $file->thumb = file_create_url(drupal_encode_path(swfupload_thumb_path($file, TRUE)));
+          }
+          break;
+        }
+        drupal_set_message(t('There was an error uploading the file'), 'swfupload_error');
         break;
       }
-      drupal_set_message(t('There was an error uploading the file'), 'swfupload_error');
-      break;
   }
 }
 
diff --git a/swfupload_widget.inc b/swfupload_widget.inc
index 0b96b2f..76a8670 100755
--- a/swfupload_widget.inc
+++ b/swfupload_widget.inc
@@ -12,7 +12,7 @@ function swfupload_field_widget_info() {
   return array(
     'swfupload_widget' => array(
       'label' => t('SWFUpload'),
-      'field types' => array('file'),
+      'field types' => array('file', 'image'),
       'settings' => array(
         'progress_indicator' => 'throbber',
         'preview_image_style' => 'thumbnail',
@@ -29,7 +29,6 @@ function swfupload_field_widget_info() {
  * An #element_validate callback for the file_field_widget field.
  */
 function swfupload_widget_validate(&$element, &$form_state) {
-
   $element_value = $element['#value'];
   if (!empty($element_value)) {
     foreach (array_values($element_value) as $key => $file) {
@@ -98,6 +97,7 @@ function swfupload_widget_value($element, $input = FALSE, $form_state) {
  * The $fields array is in $form['#field_info'][$element['#field_name']].
  */
 function swfupload_widget_process($element, &$form_state, $form) {
+  dpm($element);
   if (module_exists('image')) {
     $element += image_field_widget_process($element, $form_state, $form);
     unset($element['#theme']);
@@ -123,7 +123,7 @@ function swfupload_widget_process($element, &$form_state, $form) {
  * Implements hook_field_widget_settings_form().
  */
 function swfupload_field_widget_settings_form($field, $instance) {
-  if (module_exists('image')) {
+  if (module_exists('image') && $field['type'] == 'image') {
     module_load_include('inc', 'image', 'image.field');
     $form = image_field_widget_settings_form($field, $instance);
   }
-- 
1.7.7


From d82f0d2adbcc71566e6f7fe657aaae42f221d9a3 Mon Sep 17 00:00:00 2001
From: Jonathan Jordan <jonathan@metaltoad.com>
Date: Mon, 28 Nov 2011 09:24:56 -0800
Subject: [PATCH 23/30] Fixed issue with $_FILES array and file destination.

---
 swfupload.module |   42 +++++++++++++++++++-----------------------
 1 files changed, 19 insertions(+), 23 deletions(-)

diff --git a/swfupload.module b/swfupload.module
index f040300..d583875 100644
--- a/swfupload.module
+++ b/swfupload.module
@@ -170,7 +170,7 @@ function swfupload_library() {
 function swfupload_add_js($element, $form_state) {
   // Get the path to the swfupload module.
   $path = drupal_get_path('module', 'swfupload');
-dpm($element);
+
   $field = $form_state['field'][$element['#field_name']][$element['#language']]['field'];
   $instance = $form_state['field'][$element['#field_name']][$element['#language']]['instance'];
   if (drupal_add_library('swfupload', 'swfupload') !== FALSE) {
@@ -198,7 +198,7 @@ dpm($element);
       'file_queue_limit' => $limit,
       'post_params' => array(
         'sid' => _post_key(),
-        'file_path' => file_directory_path() . '/' . $instance['settings']['file_directory'],
+        'file_path' => $field['settings']['uri_scheme'] . '://' . $instance['settings']['file_directory'],
         'op' => 'move_uploaded_file',
         'instance' => swfupload_to_js(array('name' => $element['#field_name'])),
         'widget' => swfupload_to_js($field['widget']),
@@ -307,33 +307,29 @@ function swfupload_swfupload(&$file, $op, &$instance, $widget) {
 
       watchdog('swfupload', 'File array: @filearr', array('@filearr' => print_r($_FILES, 1)));
 
-      $langs = array_keys($_FILES[$instance->name]['name']);
-
-      foreach ($langs as $lang) {
-        $upload_name = $instance->name .'_'. $lang;
-        $_FILES['files']['name'][$upload_name] = $_FILES[$instance->name]['name'][$lang];
-        $_FILES['files']['type'][$upload_name] = $_FILES[$instance->name]['type'][$lang];
-        $_FILES['files']['tmp_name'][$upload_name] = $_FILES[$instance->name]['tmp_name'][$lang];
-        $_FILES['files']['error'][$upload_name] = $_FILES[$instance->name]['error'][$lang];
-        $_FILES['files']['size'][$upload_name] = $_FILES[$instance->name]['size'][$lang];
+      $upload_name = $instance->name;
+      $_FILES['files']['name'][$upload_name] = $_FILES[$instance->name]['name'];
+      $_FILES['files']['type'][$upload_name] = $_FILES[$instance->name]['type'];
+      $_FILES['files']['tmp_name'][$upload_name] = $_FILES[$instance->name]['tmp_name'];
+      $_FILES['files']['error'][$upload_name] = $_FILES[$instance->name]['error'];
+      $_FILES['files']['size'][$upload_name] = $_FILES[$instance->name]['size'];
 
-        // Replace tokens.
-        if (module_exists('token')) {
-          $file->file_path = token_replace($file->file_path, array('user' => NULL));
-        }
+      // Replace tokens.
+      if (module_exists('token')) {
+        $file->file_path = token_replace($file->file_path, array('user' => NULL));
+      }
 
-        // Check if the file directory exists
-        file_prepare_directory($file->file_path, FILE_CREATE_DIRECTORY);
+      // Check if the file directory exists
+      file_prepare_directory($file->file_path, FILE_CREATE_DIRECTORY);
 
-        if (user_access('upload files with swfupload') && ($file = file_save_upload($upload_name, $file->validators, $file->file_path))) {
-          if (image_get_info($file->filepath)) {
-            $file->thumb = file_create_url(drupal_encode_path(swfupload_thumb_path($file, TRUE)));
-          }
-          break;
+      if (user_access('upload files with swfupload') && ($file = file_save_upload($upload_name, $file->validators, $file->file_path))) {
+        if (image_get_info($file->filepath)) {
+          $file->thumb = file_create_url(drupal_encode_path(swfupload_thumb_path($file, TRUE)));
         }
-        drupal_set_message(t('There was an error uploading the file'), 'swfupload_error');
         break;
       }
+      drupal_set_message(t('There was an error uploading the file'), 'swfupload_error');
+      break;
   }
 }
 
-- 
1.7.7


From b139dc85533ffc59a0b2fe0d28d84a12ae30eced Mon Sep 17 00:00:00 2001
From: Jonathan Jordan <jonathan@metaltoad.com>
Date: Mon, 28 Nov 2011 12:13:00 -0800
Subject: [PATCH 24/30] Changed filepath to destination, see
 file_save_upload().

---
 swfupload.module     |    2 +-
 swfupload_widget.inc |    1 -
 2 files changed, 1 insertions(+), 2 deletions(-)

diff --git a/swfupload.module b/swfupload.module
index d583875..d63ce61 100644
--- a/swfupload.module
+++ b/swfupload.module
@@ -323,7 +323,7 @@ function swfupload_swfupload(&$file, $op, &$instance, $widget) {
       file_prepare_directory($file->file_path, FILE_CREATE_DIRECTORY);
 
       if (user_access('upload files with swfupload') && ($file = file_save_upload($upload_name, $file->validators, $file->file_path))) {
-        if (image_get_info($file->filepath)) {
+        if (image_get_info($file->destination)) {
           $file->thumb = file_create_url(drupal_encode_path(swfupload_thumb_path($file, TRUE)));
         }
         break;
diff --git a/swfupload_widget.inc b/swfupload_widget.inc
index 76a8670..68f1455 100755
--- a/swfupload_widget.inc
+++ b/swfupload_widget.inc
@@ -97,7 +97,6 @@ function swfupload_widget_value($element, $input = FALSE, $form_state) {
  * The $fields array is in $form['#field_info'][$element['#field_name']].
  */
 function swfupload_widget_process($element, &$form_state, $form) {
-  dpm($element);
   if (module_exists('image')) {
     $element += image_field_widget_process($element, $form_state, $form);
     unset($element['#theme']);
-- 
1.7.7


From f13d268149b5635f23796db5bfcea1ca2037dd09 Mon Sep 17 00:00:00 2001
From: Jonathan Jordan <jonathan@metaltoad.com>
Date: Mon, 28 Nov 2011 14:23:37 -0800
Subject: [PATCH 25/30] Fixed a reference to $ instead of jQuery, and
 commented out some tabledrag stuff that isn't
 working.

---
 js/swfupload_widget.js |    9 +++++----
 1 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/js/swfupload_widget.js b/js/swfupload_widget.js
index 8b4e482..57790b2 100755
--- a/js/swfupload_widget.js
+++ b/js/swfupload_widget.js
@@ -20,7 +20,7 @@ Drupal.tableDrag.prototype.row.prototype.markChanged = function() {
 */
 jQuery.fn.disableTextSelect = function() {
   return this.each(function() {
-    $(this).css({
+    jQuery(this).css({
       'MozUserSelect' : 'none'
     }).bind('selectstart', function() {
       return false;
@@ -193,7 +193,7 @@ jQuery.fn.disableTextSelect = function() {
         };
 
         ref.wrapper_id = 'swfupload_file_wrapper-' + field_name;
-        ref.wrapper_obj = $('<table />').attr({'id': ref.wrapper_id, 'class':'swfupload'});
+        ref.wrapper_obj = $('<table />').attr({'id': ref.wrapper_id, 'class':'swfupload tabledrag'});
         if (use_header) {
           ref.wrapper_obj.append($('<thead />').append(ref.tableRow(true)));
         };
@@ -449,7 +449,7 @@ jQuery.fn.disableTextSelect = function() {
           // Attach the tabledrag behavior
           // This will we only executed once.
           Drupal.attachBehaviors(ref.wrapper_obj);
-
+/*
           $('tbody tr', ref.wrapper_obj).not('.hidden, .tabledrag-handle-swfupload-moved').each(function() {
 
             if (!$('a.tabledrag-handle', $(this)).size()) {
@@ -464,6 +464,7 @@ jQuery.fn.disableTextSelect = function() {
           });
 
           $(document).unbind('mouseup', ref.tableDragStop).bind('mouseup', ref.tableDragStop);
+*/
           break;
 
         default:
@@ -762,7 +763,7 @@ jQuery.fn.disableTextSelect = function() {
       ref.wrapper_obj.find('.processed').each(function() {
         fid = $(this).attr('id');
 
-        // If no file is secified, the function is called after sorting
+        // If no file is specified, the function is called after sorting
         // There are no new values so the file object is not needed
         // We only need to change the order of the stack
         if (!file) {
-- 
1.7.7


From 7055674df7bc951c0f80120792649fee5d05c44e Mon Sep 17 00:00:00 2001
From: Jonathan Jordan <jonathan@metaltoad.com>
Date: Mon, 28 Nov 2011 14:24:58 -0800
Subject: [PATCH 26/30] Simplified thumbnail creation and other changes to
 image api.

---
 swfupload.admin.inc |   45 +++++----------------------------------------
 swfupload.module    |    4 ++--
 2 files changed, 7 insertions(+), 42 deletions(-)

diff --git a/swfupload.admin.inc b/swfupload.admin.inc
index cff914c..4012c41 100755
--- a/swfupload.admin.inc
+++ b/swfupload.admin.inc
@@ -145,51 +145,16 @@ function _class_to_classname(&$element) {
 /**
  * Create a thumbnail to be shown in the swfupload table
  */
-function swfupload_thumb($file) {
-  if (!is_file($file->filepath)) {
-    return FALSE;
-  }
-  $short_path = preg_replace('/^' . preg_quote(file_directory_path(), '/') . '/', '', $file->filepath);
-  $destination_path = file_directory_path() . '/imagefield_thumbs' . $short_path;
-
-  $info = image_get_info($file->filepath);
+function swfupload_thumb($file, $destination) {
   $size = explode('x', variable_get('swfupload_thumb_size', '32x32'));
 
-  // Check if the destination image needs to be regenerated to match a new size.
-  if (is_file($destination_path)) {
-    $thumb_info = image_get_info($destination_path);
-    if ($thumb_info['width'] != $size[0] && $thumb_info['height'] != $size[1] && ($info['width'] > $size[0] || $info['height'] > $size[1])) {
-      unlink($destination_path);
-    }
-    else {
-      return;
-    }
-  }
-
-  // Ensure the destination directory exists and is writable.
-  $directories = explode('/', $destination_path);
-  array_pop($directories); // Remove the file itself.
-  // Get the file system directory.
-  $file_system = file_directory_path();
-  foreach ($directories as $directory) {
-    $full_path = isset($full_path) ? $full_path . '/' . $directory : $directory;
-    // Don't check directories outside the file system path.
-    if (strpos($full_path, $file_system) === 0) {
-      field_file_check_directory($full_path, FILE_CREATE_DIRECTORY);
-    }
-  }
-
-  // Create the thumbnail.
-  if ($info['width'] <= $size[0] && $info['height'] <= $size[1]) {
-    file_copy($file->filepath, $destination_path);
-  }
-  elseif (image_get_toolkit() && @image_scale($file->filepath, $destination_path, $size[0], $size[1])) {
-    // Set permissions. This is done for us when using file_copy().
-    @chmod($destination, 0664);
+  $image = image_load($file->destination);
+  if (file_prepare_directory(dirname($destination), FILE_CREATE_DIRECTORY) && @image_scale($image, $size[0], $size[1])) {
+    image_save($image, $destination);
   }
   else {
     drupal_set_message(t('An image thumbnail was not able to be created.'), 'error');
     return FALSE;
   }
-  return $destination_path;
+  return $destination;
 }
diff --git a/swfupload.module b/swfupload.module
index d63ce61..6dc4720 100644
--- a/swfupload.module
+++ b/swfupload.module
@@ -351,8 +351,8 @@ function swfupload_filefield_paths_process_file($new, $file, $settings, $node, $
  */
 function swfupload_thumb_path($file, $create_thumb = FALSE) {
   $file = (object) $file;
-  $short_path = preg_replace('/^' . preg_quote(file_directory_path(), '/') . '/', '', $file->filepath);
-  $filepath = file_directory_path() . '/imagefield_thumbs' . $short_path;
+  $short_path = substr($file->destination, strpos($file->destination, '://')+3);
+  $filepath = file_directory_path() .'/imagefield_thumbs/' . $short_path;
 
   if ($create_thumb) {
     module_load_include('inc', 'swfupload', 'swfupload.admin');
-- 
1.7.7


From b6cdadf93e273fe276c9fd3257b324ce5baa31fc Mon Sep 17 00:00:00 2001
From: Jonathan Jordan <jonathan@metaltoad.com>
Date: Mon, 19 Dec 2011 16:11:24 -0800
Subject: [PATCH 27/30] Removed the swfupload external library, changed from
 using hook_library to using the Libraries API to keep
 the library separate from this module as a best
 practice.

---
 library/swfupload.js  |  980 -------------------------------------------------
 library/swfupload.swf |  Bin 12787 -> 0 bytes
 swfupload.info        |    1 +
 swfupload.module      |   30 +-
 4 files changed, 10 insertions(+), 1001 deletions(-)
 delete mode 100755 library/swfupload.js
 delete mode 100755 library/swfupload.swf

diff --git a/library/swfupload.js b/library/swfupload.js
deleted file mode 100755
index 969e200..0000000
--- a/library/swfupload.js
+++ /dev/null
@@ -1,980 +0,0 @@
-/**
- * SWFUpload: http://www.swfupload.org, http://swfupload.googlecode.com
- *
- * mmSWFUpload 1.0: Flash upload dialog - http://profandesign.se/swfupload/,  http://www.vinterwebb.se/
- *
- * SWFUpload is (c) 2006-2007 Lars Huring, Olov Nilzén and Mammon Media and is released under the MIT License:
- * http://www.opensource.org/licenses/mit-license.php
- *
- * SWFUpload 2 is (c) 2007-2008 Jake Roberts and is released under the MIT License:
- * http://www.opensource.org/licenses/mit-license.php
- *
- */
-
-
-/* ******************* */
-/* Constructor & Init  */
-/* ******************* */
-var SWFUpload;
-
-if (SWFUpload == undefined) {
-	SWFUpload = function (settings) {
-		this.initSWFUpload(settings);
-	};
-}
-
-SWFUpload.prototype.initSWFUpload = function (settings) {
-	try {
-		this.customSettings = {};	// A container where developers can place their own settings associated with this instance.
-		this.settings = settings;
-		this.eventQueue = [];
-		this.movieName = "SWFUpload_" + SWFUpload.movieCount++;
-		this.movieElement = null;
-
-
-		// Setup global control tracking
-		SWFUpload.instances[this.movieName] = this;
-
-		// Load the settings.  Load the Flash movie.
-		this.initSettings();
-		this.loadFlash();
-		this.displayDebugInfo();
-	} catch (ex) {
-		delete SWFUpload.instances[this.movieName];
-		throw ex;
-	}
-};
-
-/* *************** */
-/* Static Members  */
-/* *************** */
-SWFUpload.instances = {};
-SWFUpload.movieCount = 0;
-SWFUpload.version = "2.2.0 2009-03-25";
-SWFUpload.QUEUE_ERROR = {
-	QUEUE_LIMIT_EXCEEDED	  		: -100,
-	FILE_EXCEEDS_SIZE_LIMIT  		: -110,
-	ZERO_BYTE_FILE			  		: -120,
-	INVALID_FILETYPE		  		: -130
-};
-SWFUpload.UPLOAD_ERROR = {
-	HTTP_ERROR				  		: -200,
-	MISSING_UPLOAD_URL	      		: -210,
-	IO_ERROR				  		: -220,
-	SECURITY_ERROR			  		: -230,
-	UPLOAD_LIMIT_EXCEEDED	  		: -240,
-	UPLOAD_FAILED			  		: -250,
-	SPECIFIED_FILE_ID_NOT_FOUND		: -260,
-	FILE_VALIDATION_FAILED	  		: -270,
-	FILE_CANCELLED			  		: -280,
-	UPLOAD_STOPPED					: -290
-};
-SWFUpload.FILE_STATUS = {
-	QUEUED		 : -1,
-	IN_PROGRESS	 : -2,
-	ERROR		 : -3,
-	COMPLETE	 : -4,
-	CANCELLED	 : -5
-};
-SWFUpload.BUTTON_ACTION = {
-	SELECT_FILE  : -100,
-	SELECT_FILES : -110,
-	START_UPLOAD : -120
-};
-SWFUpload.CURSOR = {
-	ARROW : -1,
-	HAND : -2
-};
-SWFUpload.WINDOW_MODE = {
-	WINDOW : "window",
-	TRANSPARENT : "transparent",
-	OPAQUE : "opaque"
-};
-
-// Private: takes a URL, determines if it is relative and converts to an absolute URL
-// using the current site. Only processes the URL if it can, otherwise returns the URL untouched
-SWFUpload.completeURL = function(url) {
-	if (typeof(url) !== "string" || url.match(/^https?:\/\//i) || url.match(/^\//)) {
-		return url;
-	}
-	
-	var currentURL = window.location.protocol + "//" + window.location.hostname + (window.location.port ? ":" + window.location.port : "");
-	
-	var indexSlash = window.location.pathname.lastIndexOf("/");
-	if (indexSlash <= 0) {
-		path = "/";
-	} else {
-		path = window.location.pathname.substr(0, indexSlash) + "/";
-	}
-	
-	return /*currentURL +*/ path + url;
-	
-};
-
-
-/* ******************** */
-/* Instance Members  */
-/* ******************** */
-
-// Private: initSettings ensures that all the
-// settings are set, getting a default value if one was not assigned.
-SWFUpload.prototype.initSettings = function () {
-	this.ensureDefault = function (settingName, defaultValue) {
-		this.settings[settingName] = (this.settings[settingName] == undefined) ? defaultValue : this.settings[settingName];
-	};
-	
-	// Upload backend settings
-	this.ensureDefault("upload_url", "");
-	this.ensureDefault("preserve_relative_urls", false);
-	this.ensureDefault("file_post_name", "Filedata");
-	this.ensureDefault("post_params", {});
-	this.ensureDefault("use_query_string", false);
-	this.ensureDefault("requeue_on_error", false);
-	this.ensureDefault("http_success", []);
-	this.ensureDefault("assume_success_timeout", 0);
-	
-	// File Settings
-	this.ensureDefault("file_types", "*.*");
-	this.ensureDefault("file_types_description", "All Files");
-	this.ensureDefault("file_size_limit", 0);	// Default zero means "unlimited"
-	this.ensureDefault("file_upload_limit", 0);
-	this.ensureDefault("file_queue_limit", 0);
-
-	// Flash Settings
-	this.ensureDefault("flash_url", "swfupload.swf");
-	this.ensureDefault("prevent_swf_caching", true);
-	
-	// Button Settings
-	this.ensureDefault("button_image_url", "");
-	this.ensureDefault("button_width", 1);
-	this.ensureDefault("button_height", 1);
-	this.ensureDefault("button_text", "");
-	this.ensureDefault("button_text_style", "color: #000000; font-size: 16pt;");
-	this.ensureDefault("button_text_top_padding", 0);
-	this.ensureDefault("button_text_left_padding", 0);
-	this.ensureDefault("button_action", SWFUpload.BUTTON_ACTION.SELECT_FILES);
-	this.ensureDefault("button_disabled", false);
-	this.ensureDefault("button_placeholder_id", "");
-	this.ensureDefault("button_placeholder", null);
-	this.ensureDefault("button_cursor", SWFUpload.CURSOR.ARROW);
-	this.ensureDefault("button_window_mode", SWFUpload.WINDOW_MODE.WINDOW);
-	
-	// Debug Settings
-	this.ensureDefault("debug", false);
-	this.settings.debug_enabled = this.settings.debug;	// Here to maintain v2 API
-	
-	// Event Handlers
-	this.settings.return_upload_start_handler = this.returnUploadStart;
-	this.ensureDefault("swfupload_loaded_handler", null);
-	this.ensureDefault("file_dialog_start_handler", null);
-	this.ensureDefault("file_queued_handler", null);
-	this.ensureDefault("file_queue_error_handler", null);
-	this.ensureDefault("file_dialog_complete_handler", null);
-	
-	this.ensureDefault("upload_start_handler", null);
-	this.ensureDefault("upload_progress_handler", null);
-	this.ensureDefault("upload_error_handler", null);
-	this.ensureDefault("upload_success_handler", null);
-	this.ensureDefault("upload_complete_handler", null);
-	
-	this.ensureDefault("debug_handler", this.debugMessage);
-
-	this.ensureDefault("custom_settings", {});
-
-	// Other settings
-	this.customSettings = this.settings.custom_settings;
-	
-	// Update the flash url if needed
-	if (!!this.settings.prevent_swf_caching) {
-		this.settings.flash_url = this.settings.flash_url + (this.settings.flash_url.indexOf("?") < 0 ? "?" : "&") + "preventswfcaching=" + new Date().getTime();
-	}
-	
-	if (!this.settings.preserve_relative_urls) {
-		//this.settings.flash_url = SWFUpload.completeURL(this.settings.flash_url);	// Don't need to do this one since flash doesn't look at it
-		this.settings.upload_url = SWFUpload.completeURL(this.settings.upload_url);
-		this.settings.button_image_url = SWFUpload.completeURL(this.settings.button_image_url);
-	}
-	
-	delete this.ensureDefault;
-};
-
-// Private: loadFlash replaces the button_placeholder element with the flash movie.
-SWFUpload.prototype.loadFlash = function () {
-	var targetElement, tempParent;
-
-	// Make sure an element with the ID we are going to use doesn't already exist
-	if (document.getElementById(this.movieName) !== null) {
-		throw "ID " + this.movieName + " is already in use. The Flash Object could not be added";
-	}
-
-	// Get the element where we will be placing the flash movie
-	targetElement = document.getElementById(this.settings.button_placeholder_id) || this.settings.button_placeholder;
-
-	if (targetElement == undefined) {
-		throw "Could not find the placeholder element: " + this.settings.button_placeholder_id;
-	}
-
-	// Append the container and load the flash
-	tempParent = document.createElement("div");
-	tempParent.innerHTML = this.getFlashHTML();	// Using innerHTML is non-standard but the only sensible way to dynamically add Flash in IE (and maybe other browsers)
-	targetElement.parentNode.replaceChild(tempParent.firstChild, targetElement);
-
-	// Fix IE Flash/Form bug
-	if (window[this.movieName] == undefined) {
-		window[this.movieName] = this.getMovieElement();
-	}
-	
-};
-
-// Private: getFlashHTML generates the object tag needed to embed the flash in to the document
-SWFUpload.prototype.getFlashHTML = function () {
-	// Flash Satay object syntax: http://www.alistapart.com/articles/flashsatay
-	return ['<object id="', this.movieName, '" type="application/x-shockwave-flash" data="', this.settings.flash_url, '" width="', this.settings.button_width, '" height="', this.settings.button_height, '" class="swfupload">',
-				'<param name="wmode" value="', this.settings.button_window_mode, '" />',
-				'<param name="movie" value="', this.settings.flash_url, '" />',
-				'<param name="quality" value="high" />',
-				'<param name="menu" value="false" />',
-				'<param name="allowScriptAccess" value="always" />',
-				'<param name="flashvars" value="' + this.getFlashVars() + '" />',
-				'</object>'].join("");
-};
-
-// Private: getFlashVars builds the parameter string that will be passed
-// to flash in the flashvars param.
-SWFUpload.prototype.getFlashVars = function () {
-	// Build a string from the post param object
-	var paramString = this.buildParamString();
-	var httpSuccessString = this.settings.http_success.join(",");
-	
-	// Build the parameter string
-	return ["movieName=", encodeURIComponent(this.movieName),
-			"&amp;uploadURL=", encodeURIComponent(this.settings.upload_url),
-			"&amp;useQueryString=", encodeURIComponent(this.settings.use_query_string),
-			"&amp;requeueOnError=", encodeURIComponent(this.settings.requeue_on_error),
-			"&amp;httpSuccess=", encodeURIComponent(httpSuccessString),
-			"&amp;assumeSuccessTimeout=", encodeURIComponent(this.settings.assume_success_timeout),
-			"&amp;params=", encodeURIComponent(paramString),
-			"&amp;filePostName=", encodeURIComponent(this.settings.file_post_name),
-			"&amp;fileTypes=", encodeURIComponent(this.settings.file_types),
-			"&amp;fileTypesDescription=", encodeURIComponent(this.settings.file_types_description),
-			"&amp;fileSizeLimit=", encodeURIComponent(this.settings.file_size_limit),
-			"&amp;fileUploadLimit=", encodeURIComponent(this.settings.file_upload_limit),
-			"&amp;fileQueueLimit=", encodeURIComponent(this.settings.file_queue_limit),
-			"&amp;debugEnabled=", encodeURIComponent(this.settings.debug_enabled),
-			"&amp;buttonImageURL=", encodeURIComponent(this.settings.button_image_url),
-			"&amp;buttonWidth=", encodeURIComponent(this.settings.button_width),
-			"&amp;buttonHeight=", encodeURIComponent(this.settings.button_height),
-			"&amp;buttonText=", encodeURIComponent(this.settings.button_text),
-			"&amp;buttonTextTopPadding=", encodeURIComponent(this.settings.button_text_top_padding),
-			"&amp;buttonTextLeftPadding=", encodeURIComponent(this.settings.button_text_left_padding),
-			"&amp;buttonTextStyle=", encodeURIComponent(this.settings.button_text_style),
-			"&amp;buttonAction=", encodeURIComponent(this.settings.button_action),
-			"&amp;buttonDisabled=", encodeURIComponent(this.settings.button_disabled),
-			"&amp;buttonCursor=", encodeURIComponent(this.settings.button_cursor)
-		].join("");
-};
-
-// Public: getMovieElement retrieves the DOM reference to the Flash element added by SWFUpload
-// The element is cached after the first lookup
-SWFUpload.prototype.getMovieElement = function () {
-	if (this.movieElement == undefined) {
-		this.movieElement = document.getElementById(this.movieName);
-	}
-
-	if (this.movieElement === null) {
-		throw "Could not find Flash element";
-	}
-	
-	return this.movieElement;
-};
-
-// Private: buildParamString takes the name/value pairs in the post_params setting object
-// and joins them up in to a string formatted "name=value&amp;name=value"
-SWFUpload.prototype.buildParamString = function () {
-	var postParams = this.settings.post_params; 
-	var paramStringPairs = [];
-
-	if (typeof(postParams) === "object") {
-		for (var name in postParams) {
-			if (postParams.hasOwnProperty(name)) {
-				paramStringPairs.push(encodeURIComponent(name.toString()) + "=" + encodeURIComponent(postParams[name].toString()));
-			}
-		}
-	}
-
-	return paramStringPairs.join("&amp;");
-};
-
-// Public: Used to remove a SWFUpload instance from the page. This method strives to remove
-// all references to the SWF, and other objects so memory is properly freed.
-// Returns true if everything was destroyed. Returns a false if a failure occurs leaving SWFUpload in an inconsistant state.
-// Credits: Major improvements provided by steffen
-SWFUpload.prototype.destroy = function () {
-	try {
-		// Make sure Flash is done before we try to remove it
-		this.cancelUpload(null, false);
-		
-
-		// Remove the SWFUpload DOM nodes
-		var movieElement = null;
-		movieElement = this.getMovieElement();
-		
-		if (movieElement && typeof(movieElement.CallFunction) === "unknown") { // We only want to do this in IE
-			// Loop through all the movie's properties and remove all function references (DOM/JS IE 6/7 memory leak workaround)
-			for (var i in movieElement) {
-				try {
-					if (typeof(movieElement[i]) === "function") {
-						movieElement[i] = null;
-					}
-				} catch (ex1) {}
-			}
-
-			// Remove the Movie Element from the page
-			try {
-				movieElement.parentNode.removeChild(movieElement);
-			} catch (ex) {}
-		}
-		
-		// Remove IE form fix reference
-		window[this.movieName] = null;
-
-		// Destroy other references
-		SWFUpload.instances[this.movieName] = null;
-		delete SWFUpload.instances[this.movieName];
-
-		this.movieElement = null;
-		this.settings = null;
-		this.customSettings = null;
-		this.eventQueue = null;
-		this.movieName = null;
-		
-		
-		return true;
-	} catch (ex2) {
-		return false;
-	}
-};
-
-
-// Public: displayDebugInfo prints out settings and configuration
-// information about this SWFUpload instance.
-// This function (and any references to it) can be deleted when placing
-// SWFUpload in production.
-SWFUpload.prototype.displayDebugInfo = function () {
-	this.debug(
-		[
-			"---SWFUpload Instance Info---\n",
-			"Version: ", SWFUpload.version, "\n",
-			"Movie Name: ", this.movieName, "\n",
-			"Settings:\n",
-			"\t", "upload_url:               ", this.settings.upload_url, "\n",
-			"\t", "flash_url:                ", this.settings.flash_url, "\n",
-			"\t", "use_query_string:         ", this.settings.use_query_string.toString(), "\n",
-			"\t", "requeue_on_error:         ", this.settings.requeue_on_error.toString(), "\n",
-			"\t", "http_success:             ", this.settings.http_success.join(", "), "\n",
-			"\t", "assume_success_timeout:   ", this.settings.assume_success_timeout, "\n",
-			"\t", "file_post_name:           ", this.settings.file_post_name, "\n",
-			"\t", "post_params:              ", this.settings.post_params.toString(), "\n",
-			"\t", "file_types:               ", this.settings.file_types, "\n",
-			"\t", "file_types_description:   ", this.settings.file_types_description, "\n",
-			"\t", "file_size_limit:          ", this.settings.file_size_limit, "\n",
-			"\t", "file_upload_limit:        ", this.settings.file_upload_limit, "\n",
-			"\t", "file_queue_limit:         ", this.settings.file_queue_limit, "\n",
-			"\t", "debug:                    ", this.settings.debug.toString(), "\n",
-
-			"\t", "prevent_swf_caching:      ", this.settings.prevent_swf_caching.toString(), "\n",
-
-			"\t", "button_placeholder_id:    ", this.settings.button_placeholder_id.toString(), "\n",
-			"\t", "button_placeholder:       ", (this.settings.button_placeholder ? "Set" : "Not Set"), "\n",
-			"\t", "button_image_url:         ", this.settings.button_image_url.toString(), "\n",
-			"\t", "button_width:             ", this.settings.button_width.toString(), "\n",
-			"\t", "button_height:            ", this.settings.button_height.toString(), "\n",
-			"\t", "button_text:              ", this.settings.button_text.toString(), "\n",
-			"\t", "button_text_style:        ", this.settings.button_text_style.toString(), "\n",
-			"\t", "button_text_top_padding:  ", this.settings.button_text_top_padding.toString(), "\n",
-			"\t", "button_text_left_padding: ", this.settings.button_text_left_padding.toString(), "\n",
-			"\t", "button_action:            ", this.settings.button_action.toString(), "\n",
-			"\t", "button_disabled:          ", this.settings.button_disabled.toString(), "\n",
-
-			"\t", "custom_settings:          ", this.settings.custom_settings.toString(), "\n",
-			"Event Handlers:\n",
-			"\t", "swfupload_loaded_handler assigned:  ", (typeof this.settings.swfupload_loaded_handler === "function").toString(), "\n",
-			"\t", "file_dialog_start_handler assigned: ", (typeof this.settings.file_dialog_start_handler === "function").toString(), "\n",
-			"\t", "file_queued_handler assigned:       ", (typeof this.settings.file_queued_handler === "function").toString(), "\n",
-			"\t", "file_queue_error_handler assigned:  ", (typeof this.settings.file_queue_error_handler === "function").toString(), "\n",
-			"\t", "upload_start_handler assigned:      ", (typeof this.settings.upload_start_handler === "function").toString(), "\n",
-			"\t", "upload_progress_handler assigned:   ", (typeof this.settings.upload_progress_handler === "function").toString(), "\n",
-			"\t", "upload_error_handler assigned:      ", (typeof this.settings.upload_error_handler === "function").toString(), "\n",
-			"\t", "upload_success_handler assigned:    ", (typeof this.settings.upload_success_handler === "function").toString(), "\n",
-			"\t", "upload_complete_handler assigned:   ", (typeof this.settings.upload_complete_handler === "function").toString(), "\n",
-			"\t", "debug_handler assigned:             ", (typeof this.settings.debug_handler === "function").toString(), "\n"
-		].join("")
-	);
-};
-
-/* Note: addSetting and getSetting are no longer used by SWFUpload but are included
-	the maintain v2 API compatibility
-*/
-// Public: (Deprecated) addSetting adds a setting value. If the value given is undefined or null then the default_value is used.
-SWFUpload.prototype.addSetting = function (name, value, default_value) {
-    if (value == undefined) {
-        return (this.settings[name] = default_value);
-    } else {
-        return (this.settings[name] = value);
-	}
-};
-
-// Public: (Deprecated) getSetting gets a setting. Returns an empty string if the setting was not found.
-SWFUpload.prototype.getSetting = function (name) {
-    if (this.settings[name] != undefined) {
-        return this.settings[name];
-	}
-
-    return "";
-};
-
-
-
-// Private: callFlash handles function calls made to the Flash element.
-// Calls are made with a setTimeout for some functions to work around
-// bugs in the ExternalInterface library.
-SWFUpload.prototype.callFlash = function (functionName, argumentArray) {
-	argumentArray = argumentArray || [];
-	
-	var movieElement = this.getMovieElement();
-	var returnValue, returnString;
-
-	// Flash's method if calling ExternalInterface methods (code adapted from MooTools).
-	try {
-		returnString = movieElement.CallFunction('<invoke name="' + functionName + '" returntype="javascript">' + __flash__argumentsToXML(argumentArray, 0) + '</invoke>');
-		returnValue = eval(returnString);
-	} catch (ex) {
-		throw "Call to " + functionName + " failed";
-	}
-	
-	// Unescape file post param values
-	if (returnValue != undefined && typeof returnValue.post === "object") {
-		returnValue = this.unescapeFilePostParams(returnValue);
-	}
-
-	return returnValue;
-};
-
-/* *****************************
-	-- Flash control methods --
-	Your UI should use these
-	to operate SWFUpload
-   ***************************** */
-
-// WARNING: this function does not work in Flash Player 10
-// Public: selectFile causes a File Selection Dialog window to appear.  This
-// dialog only allows 1 file to be selected.
-SWFUpload.prototype.selectFile = function () {
-	this.callFlash("SelectFile");
-};
-
-// WARNING: this function does not work in Flash Player 10
-// Public: selectFiles causes a File Selection Dialog window to appear/ This
-// dialog allows the user to select any number of files
-// Flash Bug Warning: Flash limits the number of selectable files based on the combined length of the file names.
-// If the selection name length is too long the dialog will fail in an unpredictable manner.  There is no work-around
-// for this bug.
-SWFUpload.prototype.selectFiles = function () {
-	this.callFlash("SelectFiles");
-};
-
-
-// Public: startUpload starts uploading the first file in the queue unless
-// the optional parameter 'fileID' specifies the ID 
-SWFUpload.prototype.startUpload = function (fileID) {
-	this.callFlash("StartUpload", [fileID]);
-};
-
-// Public: cancelUpload cancels any queued file.  The fileID parameter may be the file ID or index.
-// If you do not specify a fileID the current uploading file or first file in the queue is cancelled.
-// If you do not want the uploadError event to trigger you can specify false for the triggerErrorEvent parameter.
-SWFUpload.prototype.cancelUpload = function (fileID, triggerErrorEvent) {
-	if (triggerErrorEvent !== false) {
-		triggerErrorEvent = true;
-	}
-	this.callFlash("CancelUpload", [fileID, triggerErrorEvent]);
-};
-
-// Public: stopUpload stops the current upload and requeues the file at the beginning of the queue.
-// If nothing is currently uploading then nothing happens.
-SWFUpload.prototype.stopUpload = function () {
-	this.callFlash("StopUpload");
-};
-
-/* ************************
- * Settings methods
- *   These methods change the SWFUpload settings.
- *   SWFUpload settings should not be changed directly on the settings object
- *   since many of the settings need to be passed to Flash in order to take
- *   effect.
- * *********************** */
-
-// Public: getStats gets the file statistics object.
-SWFUpload.prototype.getStats = function () {
-	return this.callFlash("GetStats");
-};
-
-// Public: setStats changes the SWFUpload statistics.  You shouldn't need to 
-// change the statistics but you can.  Changing the statistics does not
-// affect SWFUpload accept for the successful_uploads count which is used
-// by the upload_limit setting to determine how many files the user may upload.
-SWFUpload.prototype.setStats = function (statsObject) {
-	this.callFlash("SetStats", [statsObject]);
-};
-
-// Public: getFile retrieves a File object by ID or Index.  If the file is
-// not found then 'null' is returned.
-SWFUpload.prototype.getFile = function (fileID) {
-	if (typeof(fileID) === "number") {
-		return this.callFlash("GetFileByIndex", [fileID]);
-	} else {
-		return this.callFlash("GetFile", [fileID]);
-	}
-};
-
-// Public: addFileParam sets a name/value pair that will be posted with the
-// file specified by the Files ID.  If the name already exists then the
-// exiting value will be overwritten.
-SWFUpload.prototype.addFileParam = function (fileID, name, value) {
-	return this.callFlash("AddFileParam", [fileID, name, value]);
-};
-
-// Public: removeFileParam removes a previously set (by addFileParam) name/value
-// pair from the specified file.
-SWFUpload.prototype.removeFileParam = function (fileID, name) {
-	this.callFlash("RemoveFileParam", [fileID, name]);
-};
-
-// Public: setUploadUrl changes the upload_url setting.
-SWFUpload.prototype.setUploadURL = function (url) {
-	this.settings.upload_url = url.toString();
-	this.callFlash("SetUploadURL", [url]);
-};
-
-// Public: setPostParams changes the post_params setting
-SWFUpload.prototype.setPostParams = function (paramsObject) {
-	this.settings.post_params = paramsObject;
-	this.callFlash("SetPostParams", [paramsObject]);
-};
-
-// Public: addPostParam adds post name/value pair.  Each name can have only one value.
-SWFUpload.prototype.addPostParam = function (name, value) {
-	this.settings.post_params[name] = value;
-	this.callFlash("SetPostParams", [this.settings.post_params]);
-};
-
-// Public: removePostParam deletes post name/value pair.
-SWFUpload.prototype.removePostParam = function (name) {
-	delete this.settings.post_params[name];
-	this.callFlash("SetPostParams", [this.settings.post_params]);
-};
-
-// Public: setFileTypes changes the file_types setting and the file_types_description setting
-SWFUpload.prototype.setFileTypes = function (types, description) {
-	this.settings.file_types = types;
-	this.settings.file_types_description = description;
-	this.callFlash("SetFileTypes", [types, description]);
-};
-
-// Public: setFileSizeLimit changes the file_size_limit setting
-SWFUpload.prototype.setFileSizeLimit = function (fileSizeLimit) {
-	this.settings.file_size_limit = fileSizeLimit;
-	this.callFlash("SetFileSizeLimit", [fileSizeLimit]);
-};
-
-// Public: setFileUploadLimit changes the file_upload_limit setting
-SWFUpload.prototype.setFileUploadLimit = function (fileUploadLimit) {
-	this.settings.file_upload_limit = fileUploadLimit;
-	this.callFlash("SetFileUploadLimit", [fileUploadLimit]);
-};
-
-// Public: setFileQueueLimit changes the file_queue_limit setting
-SWFUpload.prototype.setFileQueueLimit = function (fileQueueLimit) {
-	this.settings.file_queue_limit = fileQueueLimit;
-	this.callFlash("SetFileQueueLimit", [fileQueueLimit]);
-};
-
-// Public: setFilePostName changes the file_post_name setting
-SWFUpload.prototype.setFilePostName = function (filePostName) {
-	this.settings.file_post_name = filePostName;
-	this.callFlash("SetFilePostName", [filePostName]);
-};
-
-// Public: setUseQueryString changes the use_query_string setting
-SWFUpload.prototype.setUseQueryString = function (useQueryString) {
-	this.settings.use_query_string = useQueryString;
-	this.callFlash("SetUseQueryString", [useQueryString]);
-};
-
-// Public: setRequeueOnError changes the requeue_on_error setting
-SWFUpload.prototype.setRequeueOnError = function (requeueOnError) {
-	this.settings.requeue_on_error = requeueOnError;
-	this.callFlash("SetRequeueOnError", [requeueOnError]);
-};
-
-// Public: setHTTPSuccess changes the http_success setting
-SWFUpload.prototype.setHTTPSuccess = function (http_status_codes) {
-	if (typeof http_status_codes === "string") {
-		http_status_codes = http_status_codes.replace(" ", "").split(",");
-	}
-	
-	this.settings.http_success = http_status_codes;
-	this.callFlash("SetHTTPSuccess", [http_status_codes]);
-};
-
-// Public: setHTTPSuccess changes the http_success setting
-SWFUpload.prototype.setAssumeSuccessTimeout = function (timeout_seconds) {
-	this.settings.assume_success_timeout = timeout_seconds;
-	this.callFlash("SetAssumeSuccessTimeout", [timeout_seconds]);
-};
-
-// Public: setDebugEnabled changes the debug_enabled setting
-SWFUpload.prototype.setDebugEnabled = function (debugEnabled) {
-	this.settings.debug_enabled = debugEnabled;
-	this.callFlash("SetDebugEnabled", [debugEnabled]);
-};
-
-// Public: setButtonImageURL loads a button image sprite
-SWFUpload.prototype.setButtonImageURL = function (buttonImageURL) {
-	if (buttonImageURL == undefined) {
-		buttonImageURL = "";
-	}
-	
-	this.settings.button_image_url = buttonImageURL;
-	this.callFlash("SetButtonImageURL", [buttonImageURL]);
-};
-
-// Public: setButtonDimensions resizes the Flash Movie and button
-SWFUpload.prototype.setButtonDimensions = function (width, height) {
-	this.settings.button_width = width;
-	this.settings.button_height = height;
-	
-	var movie = this.getMovieElement();
-	if (movie != undefined) {
-		movie.style.width = width + "px";
-		movie.style.height = height + "px";
-	}
-	
-	this.callFlash("SetButtonDimensions", [width, height]);
-};
-// Public: setButtonText Changes the text overlaid on the button
-SWFUpload.prototype.setButtonText = function (html) {
-	this.settings.button_text = html;
-	this.callFlash("SetButtonText", [html]);
-};
-// Public: setButtonTextPadding changes the top and left padding of the text overlay
-SWFUpload.prototype.setButtonTextPadding = function (left, top) {
-	this.settings.button_text_top_padding = top;
-	this.settings.button_text_left_padding = left;
-	this.callFlash("SetButtonTextPadding", [left, top]);
-};
-
-// Public: setButtonTextStyle changes the CSS used to style the HTML/Text overlaid on the button
-SWFUpload.prototype.setButtonTextStyle = function (css) {
-	this.settings.button_text_style = css;
-	this.callFlash("SetButtonTextStyle", [css]);
-};
-// Public: setButtonDisabled disables/enables the button
-SWFUpload.prototype.setButtonDisabled = function (isDisabled) {
-	this.settings.button_disabled = isDisabled;
-	this.callFlash("SetButtonDisabled", [isDisabled]);
-};
-// Public: setButtonAction sets the action that occurs when the button is clicked
-SWFUpload.prototype.setButtonAction = function (buttonAction) {
-	this.settings.button_action = buttonAction;
-	this.callFlash("SetButtonAction", [buttonAction]);
-};
-
-// Public: setButtonCursor changes the mouse cursor displayed when hovering over the button
-SWFUpload.prototype.setButtonCursor = function (cursor) {
-	this.settings.button_cursor = cursor;
-	this.callFlash("SetButtonCursor", [cursor]);
-};
-
-/* *******************************
-	Flash Event Interfaces
-	These functions are used by Flash to trigger the various
-	events.
-	
-	All these functions a Private.
-	
-	Because the ExternalInterface library is buggy the event calls
-	are added to a queue and the queue then executed by a setTimeout.
-	This ensures that events are executed in a determinate order and that
-	the ExternalInterface bugs are avoided.
-******************************* */
-
-SWFUpload.prototype.queueEvent = function (handlerName, argumentArray) {
-	// Warning: Don't call this.debug inside here or you'll create an infinite loop
-	
-	if (argumentArray == undefined) {
-		argumentArray = [];
-	} else if (!(argumentArray instanceof Array)) {
-		argumentArray = [argumentArray];
-	}
-	
-	var self = this;
-	if (typeof this.settings[handlerName] === "function") {
-		// Queue the event
-		this.eventQueue.push(function () {
-			this.settings[handlerName].apply(this, argumentArray);
-		});
-		
-		// Execute the next queued event
-		setTimeout(function () {
-			self.executeNextEvent();
-		}, 0);
-		
-	} else if (this.settings[handlerName] !== null) {
-		throw "Event handler " + handlerName + " is unknown or is not a function";
-	}
-};
-
-// Private: Causes the next event in the queue to be executed.  Since events are queued using a setTimeout
-// we must queue them in order to garentee that they are executed in order.
-SWFUpload.prototype.executeNextEvent = function () {
-	// Warning: Don't call this.debug inside here or you'll create an infinite loop
-
-	var  f = this.eventQueue ? this.eventQueue.shift() : null;
-	if (typeof(f) === "function") {
-		f.apply(this);
-	}
-};
-
-// Private: unescapeFileParams is part of a workaround for a flash bug where objects passed through ExternalInterface cannot have
-// properties that contain characters that are not valid for JavaScript identifiers. To work around this
-// the Flash Component escapes the parameter names and we must unescape again before passing them along.
-SWFUpload.prototype.unescapeFilePostParams = function (file) {
-	var reg = /[$]([0-9a-f]{4})/i;
-	var unescapedPost = {};
-	var uk;
-
-	if (file != undefined) {
-		for (var k in file.post) {
-			if (file.post.hasOwnProperty(k)) {
-				uk = k;
-				var match;
-				while ((match = reg.exec(uk)) !== null) {
-					uk = uk.replace(match[0], String.fromCharCode(parseInt("0x" + match[1], 16)));
-				}
-				unescapedPost[uk] = file.post[k];
-			}
-		}
-
-		file.post = unescapedPost;
-	}
-
-	return file;
-};
-
-// Private: Called by Flash to see if JS can call in to Flash (test if External Interface is working)
-SWFUpload.prototype.testExternalInterface = function () {
-	try {
-		return this.callFlash("TestExternalInterface");
-	} catch (ex) {
-		return false;
-	}
-};
-
-// Private: This event is called by Flash when it has finished loading. Don't modify this.
-// Use the swfupload_loaded_handler event setting to execute custom code when SWFUpload has loaded.
-SWFUpload.prototype.flashReady = function () {
-	// Check that the movie element is loaded correctly with its ExternalInterface methods defined
-	var movieElement = this.getMovieElement();
-
-	if (!movieElement) {
-		this.debug("Flash called back ready but the flash movie can't be found.");
-		return;
-	}
-
-	this.cleanUp(movieElement);
-	
-	this.queueEvent("swfupload_loaded_handler");
-};
-
-// Private: removes Flash added fuctions to the DOM node to prevent memory leaks in IE.
-// This function is called by Flash each time the ExternalInterface functions are created.
-SWFUpload.prototype.cleanUp = function (movieElement) {
-	// Pro-actively unhook all the Flash functions
-	try {
-		if (this.movieElement && typeof(movieElement.CallFunction) === "unknown") { // We only want to do this in IE
-			this.debug("Removing Flash functions hooks (this should only run in IE and should prevent memory leaks)");
-			for (var key in movieElement) {
-				try {
-					if (typeof(movieElement[key]) === "function") {
-						movieElement[key] = null;
-					}
-				} catch (ex) {
-				}
-			}
-		}
-	} catch (ex1) {
-	
-	}
-
-	// Fix Flashes own cleanup code so if the SWFMovie was removed from the page
-	// it doesn't display errors.
-	window["__flash__removeCallback"] = function (instance, name) {
-		try {
-			if (instance) {
-				instance[name] = null;
-			}
-		} catch (flashEx) {
-		
-		}
-	};
-
-};
-
-
-/* This is a chance to do something before the browse window opens */
-SWFUpload.prototype.fileDialogStart = function () {
-	this.queueEvent("file_dialog_start_handler");
-};
-
-
-/* Called when a file is successfully added to the queue. */
-SWFUpload.prototype.fileQueued = function (file) {
-	file = this.unescapeFilePostParams(file);
-	this.queueEvent("file_queued_handler", file);
-};
-
-
-/* Handle errors that occur when an attempt to queue a file fails. */
-SWFUpload.prototype.fileQueueError = function (file, errorCode, message) {
-	file = this.unescapeFilePostParams(file);
-	this.queueEvent("file_queue_error_handler", [file, errorCode, message]);
-};
-
-/* Called after the file dialog has closed and the selected files have been queued.
-	You could call startUpload here if you want the queued files to begin uploading immediately. */
-SWFUpload.prototype.fileDialogComplete = function (numFilesSelected, numFilesQueued, numFilesInQueue) {
-	this.queueEvent("file_dialog_complete_handler", [numFilesSelected, numFilesQueued, numFilesInQueue]);
-};
-
-SWFUpload.prototype.uploadStart = function (file) {
-	file = this.unescapeFilePostParams(file);
-	this.queueEvent("return_upload_start_handler", file);
-};
-
-SWFUpload.prototype.returnUploadStart = function (file) {
-	var returnValue;
-	if (typeof this.settings.upload_start_handler === "function") {
-		file = this.unescapeFilePostParams(file);
-		returnValue = this.settings.upload_start_handler.call(this, file);
-	} else if (this.settings.upload_start_handler != undefined) {
-		throw "upload_start_handler must be a function";
-	}
-
-	// Convert undefined to true so if nothing is returned from the upload_start_handler it is
-	// interpretted as 'true'.
-	if (returnValue === undefined) {
-		returnValue = true;
-	}
-	
-	returnValue = !!returnValue;
-	
-	this.callFlash("ReturnUploadStart", [returnValue]);
-};
-
-
-
-SWFUpload.prototype.uploadProgress = function (file, bytesComplete, bytesTotal) {
-	file = this.unescapeFilePostParams(file);
-	this.queueEvent("upload_progress_handler", [file, bytesComplete, bytesTotal]);
-};
-
-SWFUpload.prototype.uploadError = function (file, errorCode, message) {
-	file = this.unescapeFilePostParams(file);
-	this.queueEvent("upload_error_handler", [file, errorCode, message]);
-};
-
-SWFUpload.prototype.uploadSuccess = function (file, serverData, responseReceived) {
-	file = this.unescapeFilePostParams(file);
-	this.queueEvent("upload_success_handler", [file, serverData, responseReceived]);
-};
-
-SWFUpload.prototype.uploadComplete = function (file) {
-	file = this.unescapeFilePostParams(file);
-	this.queueEvent("upload_complete_handler", file);
-};
-
-/* Called by SWFUpload JavaScript and Flash functions when debug is enabled. By default it writes messages to the
-   internal debug console.  You can override this event and have messages written where you want. */
-SWFUpload.prototype.debug = function (message) {
-	this.queueEvent("debug_handler", message);
-};
-
-
-/* **********************************
-	Debug Console
-	The debug console is a self contained, in page location
-	for debug message to be sent.  The Debug Console adds
-	itself to the body if necessary.
-
-	The console is automatically scrolled as messages appear.
-	
-	If you are using your own debug handler or when you deploy to production and
-	have debug disabled you can remove these functions to reduce the file size
-	and complexity.
-********************************** */
-   
-// Private: debugMessage is the default debug_handler.  If you want to print debug messages
-// call the debug() function.  When overriding the function your own function should
-// check to see if the debug setting is true before outputting debug information.
-SWFUpload.prototype.debugMessage = function (message) {
-	if (this.settings.debug) {
-		var exceptionMessage, exceptionValues = [];
-
-		// Check for an exception object and print it nicely
-		if (typeof message === "object" && typeof message.name === "string" && typeof message.message === "string") {
-			for (var key in message) {
-				if (message.hasOwnProperty(key)) {
-					exceptionValues.push(key + ": " + message[key]);
-				}
-			}
-			exceptionMessage = exceptionValues.join("\n") || "";
-			exceptionValues = exceptionMessage.split("\n");
-			exceptionMessage = "EXCEPTION: " + exceptionValues.join("\nEXCEPTION: ");
-			SWFUpload.Console.writeLine(exceptionMessage);
-		} else {
-			SWFUpload.Console.writeLine(message);
-		}
-	}
-};
-
-SWFUpload.Console = {};
-SWFUpload.Console.writeLine = function (message) {
-	var console, documentForm;
-
-	try {
-		console = document.getElementById("SWFUpload_Console");
-
-		if (!console) {
-			documentForm = document.createElement("form");
-			document.getElementsByTagName("body")[0].appendChild(documentForm);
-
-			console = document.createElement("textarea");
-			console.id = "SWFUpload_Console";
-			console.style.fontFamily = "monospace";
-			console.setAttribute("wrap", "off");
-			console.wrap = "off";
-			console.style.overflow = "auto";
-			console.style.width = "700px";
-			console.style.height = "350px";
-			console.style.margin = "5px";
-			documentForm.appendChild(console);
-		}
-
-		console.value += message + "\n";
-
-		console.scrollTop = console.scrollHeight - console.clientHeight;
-	} catch (ex) {
-		alert("Exception: " + ex.name + " Message: " + ex.message);
-	}
-};
diff --git a/library/swfupload.swf b/library/swfupload.swf
deleted file mode 100755
index e3f767031ca8243a5f0b89bc0f154cc5962e01e9..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 12787
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
FQw=c6g4F;3

diff --git a/swfupload.info b/swfupload.info
index 6c88f22..f24ae4d 100644
--- a/swfupload.info
+++ b/swfupload.info
@@ -3,4 +3,5 @@ description = A widget for File fields which enables multiple file uploads using
 package = CCK
 version = VERSION
 dependencies[] = file
+dependencies[] = libraries
 core = 7.x
diff --git a/swfupload.module b/swfupload.module
index 6dc4720..3e79041 100644
--- a/swfupload.module
+++ b/swfupload.module
@@ -148,32 +148,20 @@ function swfupload_element_info() {
 }
 
 /**
- * Implements hook_library()
- */
-function swfupload_library() {
-  $libraries['swfupload'] = array(
-    'title' => 'SWFUpload',
-    'website' => 'http://swfupload.org/',
-    'version' => '2.2.0.1',
-    'js' => array(
-      drupal_get_path('module', 'swfupload') .'/library/swfupload.js' => array(),
-    ),
-  );
-
-  return $libraries;
-}
-
-/**
  * This function is called after the FAPI element is processed.
  * Here we can safely attach our javascript
  */
 function swfupload_add_js($element, $form_state) {
   // Get the path to the swfupload module.
-  $path = drupal_get_path('module', 'swfupload');
+  $module_path = drupal_get_path('module', 'swfupload');
 
   $field = $form_state['field'][$element['#field_name']][$element['#language']]['field'];
   $instance = $form_state['field'][$element['#field_name']][$element['#language']]['instance'];
-  if (drupal_add_library('swfupload', 'swfupload') !== FALSE) {
+
+  $library_path = libraries_get_path('swfupload');
+  if (file_exists($library_path . '/swfupload.js') !== FALSE) {
+    drupal_add_js($library_path .'/swfupload.js');
+
     // Put the values of the list field and description field in the widget array
     // so we can pass it to our hook_swfupload implementation.
     $field['widget']['display_field'] = isset($field['settings']['display_field']) ? $field['settings']['display_field'] : 0;
@@ -187,10 +175,10 @@ function swfupload_add_js($element, $form_state) {
 
     $limit = ($field['cardinality'] == -1) ? 0 : $field['cardinality'];
 
-    $flash_url = '/'. drupal_get_path('module', 'swfupload') .'/library/swfupload.swf';
+    $flash_url = '/'. $library_path .'/swfupload.swf';
 
     $settings['swfupload_settings'][$element['#id']] = array(
-      'module_path' => $path,
+      'module_path' => $module_path,
       'flash_url' => $flash_url,
       'upload_url' => url('swfupload'), // Relative to the SWF file
       'upload_button_id' => $element['#id'],
@@ -213,7 +201,7 @@ function swfupload_add_js($element, $form_state) {
       ),
     );
     drupal_add_js('misc/tabledrag.js', array('type' => 'file', 'weight' => JS_LIBRARY));
-    drupal_add_js("$path/js/swfupload_widget.js");
+    drupal_add_js("$module_path/js/swfupload_widget.js");
     drupal_add_js($settings, array('type' => 'setting', 'scope' => JS_DEFAULT));
   }
 
-- 
1.7.7


From 0c9301771ac50edefdb60e68b3888bd18f457d31 Mon Sep 17 00:00:00 2001
From: Jonathan Jordan <jonathan@metaltoad.com>
Date: Thu, 29 Dec 2011 14:21:13 -0800
Subject: [PATCH 28/30] Fixed a bug in the stack building that was causing
 filename to be overwritten.

---
 js/swfupload_widget.js |   11 ++++++++---
 1 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/js/swfupload_widget.js b/js/swfupload_widget.js
index 57790b2..d34df38 100755
--- a/js/swfupload_widget.js
+++ b/js/swfupload_widget.js
@@ -58,7 +58,7 @@ jQuery.fn.disableTextSelect = function() {
     ref.init = function() {
       ref.settings = settings;
       ref.upload_button_obj = $('#' + ref.settings.upload_button_id);
-      ref.instance = {name:settings.file_post_name};
+      ref.instance = {name:settings.file_post_name, language:$.parseJSON(settings.post_params.instance).language};
       ref.ajax_settings = {
         type:"post",
         url:ref.settings.upload_url,
@@ -104,7 +104,7 @@ jQuery.fn.disableTextSelect = function() {
     ref.createStackObj = function() {
       var upload_stack_value = settings.custom_settings.upload_stack_value;
       ref.max_queue_size = settings.custom_settings.max_queue_size;
-      ref.upload_stack_obj = $('<input type="hidden" />').attr('name', ref.instance.name).val(upload_stack_value).prependTo(ref.upload_button_obj);
+      ref.upload_stack_obj = $('<input type="hidden" />').attr('name', ref.instance.name + '[' + ref.instance.language + '][0][raw_value]').val(upload_stack_value).prependTo(ref.upload_button_obj);
       ref.upload_stack = jQuery.parseJSON(upload_stack_value);
       ref.upload_stack_length = ref.objectLength(ref.upload_stack);
     };
@@ -770,7 +770,12 @@ jQuery.fn.disableTextSelect = function() {
           ref.upload_stack[fid] = old_upload_stack[fid];
         }
         else {
-          ref.upload_stack[fid] = {filename:file.filename || file.name, fid:fid};
+          // Don't overwrite other rows with the current filename.
+          if (fid == file.fid) {
+            ref.upload_stack[fid] = {filename:file.filename || file.name, fid:fid};
+          } else {
+            ref.upload_stack[fid] = old_upload_stack[fid];
+          }
           total_size += parseInt(file.size);
           for (var name in ref.instance.elements) {
             input_field = $('#edit-' + name + '_' + fid);
-- 
1.7.7


From 6136f095f00e2b9437168cbcebdbb75a711d7905 Mon Sep 17 00:00:00 2001
From: Jonathan Jordan <jonathan@metaltoad.com>
Date: Thu, 29 Dec 2011 14:30:13 -0800
Subject: [PATCH 29/30] Since the value_callback is not called until after
 drupal_array_set_nested_value() in D7, our json
 string does not work unless we have an array, instead
 we use the element_validate callback to convert our
 json string to a valid file array.

---
 swfupload.module     |    8 ++++----
 swfupload_widget.inc |   29 ++++++++++++-----------------
 2 files changed, 16 insertions(+), 21 deletions(-)

diff --git a/swfupload.module b/swfupload.module
index 3e79041..da77304 100644
--- a/swfupload.module
+++ b/swfupload.module
@@ -115,6 +115,9 @@ function swfupload_field_widget_form(&$form, &$form_state, $field, $instance, $l
   $element['#default_value'] = $items;
   $element['#theme'] = 'swfupload_widget';
   $element['#after_build'] = array('swfupload_add_js');
+  $element['#element_validate'] = array('swfupload_widget_validate');
+  //$element['#process'] = array('swfupload_widget_process');
+  $element['#value_callback'] = 'swfupload_widget_value';
 
   return $element;
 }
@@ -188,7 +191,7 @@ function swfupload_add_js($element, $form_state) {
         'sid' => _post_key(),
         'file_path' => $field['settings']['uri_scheme'] . '://' . $instance['settings']['file_directory'],
         'op' => 'move_uploaded_file',
-        'instance' => swfupload_to_js(array('name' => $element['#field_name'])),
+        'instance' => swfupload_to_js(array('name' => $element['#field_name'], 'language' => $element['#language'])),
         'widget' => swfupload_to_js($field['widget']),
       ),
       'file_size_limit' => ($instance['settings']['max_filesize'] ? (parse_size($instance['settings']['max_filesize']) / 1048576) . 'MB' : 0),
@@ -234,7 +237,6 @@ function hex2bin($h) {
  * Implements hook_swfupload().
  */
 function swfupload_swfupload(&$file, $op, &$instance, $widget) {
-  watchdog('swfupload', 'File (@type): @file; @op; @instance; @widget', array('@type' => gettype($file), '@file' => print_r($file, 1), '@op' => $op, '@instance' => print_r($instance, 1), '@widget' => print_r($widget, 1)));
   switch ($op) {
     case 'init':
       $columns = 0;
@@ -293,8 +295,6 @@ function swfupload_swfupload(&$file, $op, &$instance, $widget) {
         return;
       }
 
-      watchdog('swfupload', 'File array: @filearr', array('@filearr' => print_r($_FILES, 1)));
-
       $upload_name = $instance->name;
       $_FILES['files']['name'][$upload_name] = $_FILES[$instance->name]['name'];
       $_FILES['files']['type'][$upload_name] = $_FILES[$instance->name]['type'];
diff --git a/swfupload_widget.inc b/swfupload_widget.inc
index 68f1455..b4463c7 100755
--- a/swfupload_widget.inc
+++ b/swfupload_widget.inc
@@ -29,24 +29,19 @@ function swfupload_field_widget_info() {
  * An #element_validate callback for the file_field_widget field.
  */
 function swfupload_widget_validate(&$element, &$form_state) {
-  $element_value = $element['#value'];
-  if (!empty($element_value)) {
-    foreach (array_values($element_value) as $key => $file) {
-      $form_state['values'][$element['#field_name']][$key] = array_merge(
-        field_file_load($file['fid']), // Load all fields, such as 'filepath'.
-        array(
-        'list' => $file['list'],
-        'data' => array(
-          'description' => $file['description'],
-          'alt' => $file['alt'],
-          'title' => $file['title'],
-        ),
-      )
-      );
-      unset($form_state['values'][$element['#field_name']][$file['fid']]);
-    }
-    unset($form_state['values'][$element['#field_name']]['data']);
+  $raw_value = $form_state['input'][$element['#field_name']][$element['#language']][0]['raw_value'];
+  $files = json_decode($raw_value);
+
+  $values = array();
+  foreach ($files as $file) {
+    $values[] = array(
+      'fid' => $file->fid,
+      'filename' => $file->filename,
+    );
   }
+
+  $form_state['input'][$element['#field_name']][$element['#language']] = $values;
+  $form_state['values'][$element['#field_name']][$element['#language']] = $values;
 }
 
 /**
-- 
1.7.7


From 4e2f67b578a0b0580dfba0668962b55ce339c3e4 Mon Sep 17 00:00:00 2001
From: Jonathan Jordan <jonathan@metaltoad.com>
Date: Thu, 29 Dec 2011 17:01:57 -0800
Subject: [PATCH 30/30] Fixed file fields issue with required display column
 being empty.

---
 swfupload.admin.inc  |    4 ++--
 swfupload.module     |   25 ++++++++++++++++++++-----
 swfupload_widget.inc |    9 +++++----
 3 files changed, 27 insertions(+), 11 deletions(-)

diff --git a/swfupload.admin.inc b/swfupload.admin.inc
index 4012c41..3e3c917 100755
--- a/swfupload.admin.inc
+++ b/swfupload.admin.inc
@@ -147,8 +147,8 @@ function _class_to_classname(&$element) {
  */
 function swfupload_thumb($file, $destination) {
   $size = explode('x', variable_get('swfupload_thumb_size', '32x32'));
-
-  $image = image_load($file->destination);
+  $image_path = !empty($file->destination) ? $file->destination : $file->uri;
+  $image = image_load($image_path);
   if (file_prepare_directory(dirname($destination), FILE_CREATE_DIRECTORY) && @image_scale($image, $size[0], $size[1])) {
     image_save($image, $destination);
   }
diff --git a/swfupload.module b/swfupload.module
index da77304..117e21c 100644
--- a/swfupload.module
+++ b/swfupload.module
@@ -111,13 +111,27 @@ function swfupload_field_widget_form(&$form, &$form_state, $field, $instance, $l
     $element += file_field_widget_form($form, $form_state, $field, $instance, $langcode, $items, $delta, $element);
   }
 
-  //$element['#type'] = 'swfupload_widget';
-  $element['#default_value'] = $items;
+  if (!empty($items)) {
+    $default_values = array();
+    foreach ($items as $key => $file) {
+      $default_values[$file['fid']] = $file + array(
+        'thumb' => '/'. swfupload_thumb_path($file),
+      );
+      unset($element[$key]);
+    }
+
+    $element['#value'] = $default_values;
+    unset($element[$key + 1]);
+  } else {
+    // Remove child elements because we don't want their callbacks to fire
+    unset($element[0]);
+  }
+
   $element['#theme'] = 'swfupload_widget';
   $element['#after_build'] = array('swfupload_add_js');
   $element['#element_validate'] = array('swfupload_widget_validate');
   //$element['#process'] = array('swfupload_widget_process');
-  $element['#value_callback'] = 'swfupload_widget_value';
+  //$element['#value_callback'] = 'swfupload_widget_value';
 
   return $element;
 }
@@ -247,7 +261,7 @@ function swfupload_swfupload(&$file, $op, &$instance, $widget) {
         unset($instance->elements['filename']);
       }
       if ($widget->display_field) {
-        $instance->elements['list'] = array(
+        $instance->elements['display'] = array(
           'title' => t('List'),
           'type' => 'checkbox',
           'default_value' => $widget->display_default,
@@ -339,7 +353,8 @@ function swfupload_filefield_paths_process_file($new, $file, $settings, $node, $
  */
 function swfupload_thumb_path($file, $create_thumb = FALSE) {
   $file = (object) $file;
-  $short_path = substr($file->destination, strpos($file->destination, '://')+3);
+  $destination = !empty($file->destination) ? $file->destination : $file->uri;
+  $short_path = substr($destination, strpos($destination, '://')+3);
   $filepath = file_directory_path() .'/imagefield_thumbs/' . $short_path;
 
   if ($create_thumb) {
diff --git a/swfupload_widget.inc b/swfupload_widget.inc
index b4463c7..03962fb 100755
--- a/swfupload_widget.inc
+++ b/swfupload_widget.inc
@@ -31,12 +31,13 @@ function swfupload_field_widget_info() {
 function swfupload_widget_validate(&$element, &$form_state) {
   $raw_value = $form_state['input'][$element['#field_name']][$element['#language']][0]['raw_value'];
   $files = json_decode($raw_value);
-
   $values = array();
   foreach ($files as $file) {
     $values[] = array(
       'fid' => $file->fid,
       'filename' => $file->filename,
+      'display' => (empty($file->display)) ? 0 : 1,
+      'description' => '',
     );
   }
 
@@ -48,8 +49,8 @@ function swfupload_widget_validate(&$element, &$form_state) {
  * The #value_callback for the swfupload_widget type element.
  */
 function swfupload_widget_value($element, $input = FALSE, $form_state) {
-  if (is_string($input)) {
-    $input = json_decode($input, TRUE);
+  if (!empty($input) && is_string($input['raw_value'])) {
+    $input = json_decode($input['raw_value'], TRUE);
   }
 
   if ($input === FALSE) {
@@ -65,7 +66,7 @@ function swfupload_widget_value($element, $input = FALSE, $form_state) {
             'description' => $tmp_file['data']['description'] ? $tmp_file['data']['description'] : '',
             'alt' => $tmp_file['data']['alt'],
             'title' => $tmp_file['data']['title'],
-            'list' => $tmp_file['list'],
+            'display' => $tmp_file['display'],
           );
 
           // If we're dealing with an image, create a thumbpath
-- 
1.7.7

