diff --git a/audio/audio.module b/audio/audio.module
old mode 100755
new mode 100644
index df0bfe7..f5d12aa
--- a/audio/audio.module
+++ b/audio/audio.module
@@ -1,5 +1,5 @@
 <?php
-// $Id: audio.module,v 1.159 2009/11/29 19:45:22 drewish Exp $
+// $Id: audio.module,v 1.158 2009/11/25 19:30:45 drewish Exp $
 
 /**
  * Implementation of hook_help().
@@ -126,11 +126,127 @@ function audio_menu() {
     'access arguments' => array(2),
     'type' => MENU_CALLBACK,
   );
+  $items['audio/progress'] = array(
+    'page callback' => 'audio_progress',
+    'page arguments' => array(2),
+    'access arguments' => array('access content'),
+    'type' => MENU_CALLBACK,
+  );
+  $items['audio/ahah'] = array(
+    'page callback' => 'audio_ahah',
+    'access arguments' => array('access content'),
+    'type' => MENU_CALLBACK,
+  );
+
 
   return $items;
 }
 
 /**
+ * Implementation of audio_ahah callback
+ */
+function audio_ahah() {
+  $cached_form_state = array();
+  if (!($cached_form = form_get_cache($_POST['form_build_id'], $cached_form_state))) {
+    $output = theme('status_messages');
+    print drupal_to_js(array('status' => TRUE, 'data' => $output));
+  }
+
+  $form_state = array('values' => $_POST);
+  $form_build_id = $_POST['form_build_id'];
+ 
+  $validators = array(
+    'file_validate_extensions' => array(variable_get('audio_allowed_extensions', 'mp3 wav ogg')),
+  );
+  if ($file = file_save_upload('audio_upload', $validators)) {
+    //we need to add the the audio file to the form.
+    $form_state['values']['audio']['file'] = $file;
+    $node = (object) $form_state['values'];
+
+    $cached_form['audio']['file'] = array(
+      '#type' => 'value',
+      '#value' => $file,
+    );
+    $cached_form['audio']['display_filepath']['#value'] = $file->filepath;
+    unset($cached_form['audio']['audio_upload']);
+    unset($cached_form['audio']['attach']);
+    $form_state['storage']['node'] = $node;
+
+    $cached_form['audio']['message'] = array(
+      '#type' => 'markup',
+      '#value' => '<div class="messages warning">' . t('File was successfully attached.') . '</div>',
+      );
+    $cached_form['#submit'] = array('audio_node_form_submit');
+    $form_state['rebuild'] = FALSE;
+  }
+
+  // Unfortunately we HAVE to use the old way because the new way
+  // plain, simply doesn't work. And the old way doesn't work, and
+  // doesn't save form_state or form to the cache so that the validate
+  // submit and node validate functions will recognize the new values.
+  //drupal_process_form('audio_node_form', $cached_form, $form_state);
+  //$form = drupal_rebuild_form('audio_node_form', $form_state, $node, $form_build_id);
+  form_set_cache($form_build_id, $cached_form, $form_state);
+  drupal_alter('form', $cached_form, array(), 'audio_ahah');
+  $form = form_builder('audio_node_form', $cached_form, $form_state);
+
+  print drupal_to_js(array('status' => TRUE, 'data' => $message . drupal_render($form['audio'])));
+  exit();
+}
+
+/**
+ * Implementation audio_progress callback
+ */
+function audio_progress($key) {
+  $progress = array(
+    'message' => t('Starting upload...'),
+    'percentage' => -1,
+  );
+
+  $implementation = audio_progress_implementation();
+  if ($implementation == 'uploadprogress') {
+  	$template = ini_get("uploadprogress.file.filename_template");
+  	$filename = preg_replace("/%s/", $key, $template);
+  	$status = uploadprogress_get_info($key);
+  	if (isset($status['bytes_uploaded']) && !empty($status['bytes_total'])) {
+    	$progress['message'] = t('Uploading... (@current of @total)', array('@current' => format_size($status['bytes_uploaded']), '@total' => format_size($status['bytes_total'])));
+		$progress['percentage'] = round(100 * $status['bytes_uploaded'] / $status['bytes_total']);
+	}
+  }
+  elseif ($implementation == 'apc') {
+	//TODO: 
+	//apc implementation untested. We don't have a working APC-enabled PHP installation to test with
+    $status = apc_fetch('upload_' . $key);
+    if (isset($status['current']) && !empty($status['total'])) {
+      $progress['message'] = t('Uploading... (@current of @total)', array('@current' => format_size($status['current']), '@total' => format_size($status['total'])));
+      $progress['percentage'] = round(100 * $status['current'] / $status['total']);
+    }
+  }
+  drupal_json($progress);
+}
+
+/**
+ * Determine which upload progress implementation to use, if any available.
+ * 	Code borrowed from the filefield module.
+ */
+function audio_progress_implementation() {
+  static $implementation;
+  if (!isset($implementation)) {
+    $implementation = FALSE;
+
+    // We prefer the PECL extension uploadprogress because it supports multiple
+    // simultaneous uploads. APC only supports one at a time.
+    if (extension_loaded('uploadprogress')) {
+      $implementation = 'uploadprogress';
+    }
+    elseif (extension_loaded('apc') && ini_get('apc.rfc1867')) {
+      $implementation = 'apc';
+    }
+  }
+  return $implementation;
+}
+
+/**
  * Implementation of hook_theme
  */
 function audio_theme() {
@@ -441,7 +557,7 @@ function audio_view(&$node, $teaser = FALSE, $page = FALSE) {
  */
 function audio_validate(&$node, &$form) {
   if (!isset($node->audio['file']->filepath)) {
-    form_set_error('audio_upload', t("A file must be provided. If you tried uploading a file, make sure it's less than the upload size limit."));
+      form_set_error('audio_upload', t("A file must be provided. If you tried uploading a file, make sure it's less than the upload size limit."));
   }
 
   if (empty($form_state['values']['title_format'])) {
@@ -506,6 +622,8 @@ function audio_load($node) {
 function audio_insert(&$node) {
   file_move($node->audio['file']->filepath, audio_get_directory(), FILE_EXISTS_RENAME);
   _audio_save($node);
+  //@todo for some reason form_state['redirect'] isn't working
+  drupal_goto('node/' . $node->nid);
 }
 
 /**
@@ -529,6 +647,8 @@ function audio_update(&$node) {
   }
 
   _audio_save($node);
+  //@todo for some reason form_state['redirect'] isn't working
+  drupal_goto('node/' . $node->nid);
 }
 
 /**
@@ -555,10 +675,12 @@ function _audio_save(&$node) {
 
   // Save the new tags.
   $allowed_tags = audio_get_tags_allowed();
-  foreach ($node->audio_tags as $tag => $value) {
-    if (in_array($tag, $allowed_tags) && $value) {
-      $metadata = array('vid' => $node->vid, 'tag' => $tag, 'value' => $value, 'clean' => audio_clean_tag($value));
-      drupal_write_record('audio_metadata', $metadata);
+  if (!empty($node->audio_tags)) {
+    foreach ($node->audio_tags as $tag => $value) {
+      if (in_array($tag, $allowed_tags) && $value) {
+        $metadata = array('vid' => $node->vid, 'tag' => $tag, 'value' => $value, 'clean' => audio_clean_tag($value));
+        drupal_write_record('audio_metadata', $metadata);
+      }
     }
   }
 }
@@ -642,6 +764,8 @@ function audio_form(&$node, &$form_state) {
   $form['audio'] = array(
     '#type' => 'fieldset',
     '#title' => t('Audio File Info'),
+    '#prefix' => '<div id="audio-file-info-wrapper">',
+    '#suffix' => '</div>',
     '#collapsible' => TRUE,
     '#weight' => -1,
     '#tree' => TRUE,
@@ -730,14 +854,52 @@ function audio_form(&$node, &$form_state) {
   }
 
   $extensions = implode(', ', array_filter(explode(' ', variable_get('audio_allowed_extensions', 'mp3 wav ogg'))));
+
+  $key = md5(mt_rand());
+
+  $form['upload']['UPLOAD_IDENTIFIER'] = array(
+    '#type' =>'hidden',
+    '#value' => $key,
+  );
+
   $form['audio']['audio_upload'] = array(
     '#tree' => FALSE,
     '#type' => 'file',
     '#title' => empty($node->audio['file']->filename) ? t('Add a new audio file') : t('Replace this with a new file'),
-    '#attributes' => array('audio_accept' => $extensions),
+    '#attributes' => array('audio_accept' => $extensions, 'size' => '40'),
     '#description' => t('Click "Browse..." to select an audio file to upload. Only files with the following extensions are allowed: %allowed-extensions.', array('%allowed-extensions' => $extensions)) .'<br />'
       . t('<strong>NOTE:</strong> the current PHP configuration limits uploads to %maxsize.', array('%maxsize' => format_size(file_upload_max_size()))),
   );
+
+  //kill Kenny
+  $progress_implementation = audio_progress_implementation();
+  if ($progress_implementation) {
+	$progress_type = 'bar';
+  }
+  else {
+	$progress_type = 'throbber';	
+  }
+
+  //kill radcliffe 
+  $form['audio']['attach'] = array(
+    '#type' => 'submit',
+    '#value' => t('Upload'),
+    '#name' => 'attach',
+    '#prefix' => '<div id="edit-audio-attach-wrapper">',
+    '#suffix' => '</div>',
+    '#ahah' => array(
+      'path' => 'audio/ahah',
+      'wrapper' => 'audio-file-info-wrapper',
+      'method' => 'replace',
+      'progress' => array(
+        'path' => 'audio/progress/' . $key,
+        'type' => $progress_type,
+        'message' => t('Please wait...'),
+        'interval' => 300,
+      ),
+    ),
+  );
+
   $form['audio']['downloadable'] = array(
     '#type' => 'checkbox',
     '#title' => t('Allow file downloads.'),
@@ -747,6 +909,8 @@ function audio_form(&$node, &$form_state) {
   );
 
 
+
+
   // If we've got a file, add the fields for editing meta data.
   if (!empty($node->audio['file']->filepath)) {
     $form['audio_tags'] = array(
@@ -764,6 +928,7 @@ function audio_form(&$node, &$form_state) {
 
   $form['#validate'][] = 'audio_node_form_validate';
   $form['#submit'][] = 'audio_node_form_submit';
+
   $form['#attributes'] = array('enctype' => 'multipart/form-data');
 
   return $form;
@@ -774,8 +939,8 @@ function audio_form(&$node, &$form_state) {
  * the watchdog module.
  */
 function theme_audio_file_form($form) {
-  // List of elements to leave out of the table.
-  $skip_list = array('audio_upload' => 1, 'downloadable' => 1);
+	// List of elements to leave out of the table.
+	$skip_list = array('audio_upload' => 1, 'downloadable' => 1, 'attach' => 1, 'message' => 1);
 
   $rows = array();
   foreach (element_children($form) as $key) {
@@ -799,18 +964,20 @@ function theme_audio_file_form($form) {
  * Node submit handler
  */
 function audio_node_form_validate($form, &$form_state) {
-  // Check for an upload.
-  $validators = array(
-    'file_validate_extensions' => array(variable_get('audio_allowed_extensions', 'mp3 wav ogg')),
-  );
-  if ($file = file_save_upload('audio_upload', $validators)) {
-    $node = (object) $form_state['values'];
-    $node->audio = array(
-      'play_count' => 0,
-      'download_count' => 0,
-      'downloadable' => (bool) $form_state['values']['audio']['downloadable'],
-      'file' => $file,
+  if (!isset($form_state['values']['audio']['file']->filename)) {
+    // Check for an upload.
+    $validators = array(
+      'file_validate_extensions' => array(variable_get('audio_allowed_extensions', 'mp3 wav ogg')),
     );
+    if ($file = file_save_upload('audio_upload', $validators)) {
+      $node = (object) $form_state['values'];
+      $node->audio = array(
+        'play_count' => 0,
+        'download_count' => 0,
+        'downloadable' => (bool) $form_state['values']['audio']['downloadable'],
+        'file' => $file,
+      );
+    }
 
     // Allow other modules to modify the node.
     audio_invoke_audioapi('upload', $node);
@@ -822,7 +989,17 @@ function audio_node_form_validate($form, &$form_state) {
     $form_state['values']['audio'] = $node->audio;
     $form_state['values']['audio_tags'] = $node->audio_tags;
     $form_state['values']['audio_images'] = $node->audio_images;
-  }
+    }
+    else {
+      $node = $form_state['storage']['node'];
+
+      // Allow other modules to modify the node.
+      audio_invoke_audioapi('upload', $node);
+
+      $form_state['values']['audio'] = $node->audio;
+      $form_state['values']['audio_tags'] = $node->audio_tags;
+      $form_state['values']['audio_images'] = $node->audio_images;
+    }
 }
 
 /**
@@ -967,7 +1144,7 @@ function audio_get_tag_settings() {
   $defaults = array(
     'artist' => array('autocomplete' => 1, 'required' => 1, 'hidden' => 0,
       'writetofile' => 1, 'browsable' => 1, 'weight' => -2),
-    'title'  => array('autocomplete' => 0, 'required' => 1, 'hidden' => 0,
+    'title'  => array('autocomplete' => 1, 'required' => 1, 'hidden' => 0,
        'writetofile' => 1, 'browsable' => 1, 'weight' => -2),
     'album'  => array('autocomplete' => 1, 'required' => 0, 'hidden' => 0,
        'writetofile' => 1, 'browsable' => 1, 'weight' => -1),
@@ -1043,7 +1220,7 @@ function _audio_player_build_list() {
       if (isset($result) && is_array($result)) {
         foreach (array_keys($result) as $player) {
           // Keep track of the file where this player was found.
-          $result[$player]['file'] = $file->basename;
+          $result[$player]['file'] = $file->basename; 
         }
         $players_name = array_merge($players_name, $result);
       }
