Index: includes/ooyala.pages.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/ooyala/includes/ooyala.pages.inc,v
retrieving revision 1.7
diff -u -r1.7 ooyala.pages.inc
--- includes/ooyala.pages.inc	19 Jan 2010 17:59:08 -0000	1.7
+++ includes/ooyala.pages.inc	19 Jan 2010 23:40:13 -0000
@@ -224,6 +224,46 @@
 }
 
 /**
+ * Menu callback; Retrieve a new thumbnail from the Ooyala servers.
+ */
+function ooyala_refresh_thumbnail() {
+  $token = drupal_get_token();
+  $data = array();
+  if (isset($_GET['token']) && $_GET['token'] == $token) {
+    if (isset($_GET['embedcode']) && $_GET['embedcode']) {
+      $embedcode = $_GET['embedcode'];
+
+      // Try to retrieve a new thumbnail.
+      if ($thumb_path = ooyala_api_fetch_image($embedcode)) {
+        $data['content'] = theme('ooyala_upload_preview', $embedcode);
+        $data['message'] = '';
+        $data['error'] = 0;
+
+        // Flush out all existing ImageCache images.
+        if (function_exists('imagecache_image_flush')) {
+          imagecache_image_flush($thumb_path);
+        }
+      }
+      else {
+        $data['content'] = theme('ooyala_upload_preview');
+        $data['message'] = t('A thumbnail was not able to be retrieved. Check that the video code correct and that the video has finished processing.');
+        $data['error'] = 0;
+      }
+    }
+    else {
+      $data['message'] = t('A video code must be provided before it can be previewed.');
+      $data['error'] = 1;
+    }
+  }
+  else {
+    $data['message'] = t('Invalid token.');
+    $data['error'] = 1;
+  }
+
+  drupal_json($data);
+}
+
+/**
  * Menu callback; Respond to Ooyala pings when a video has finished processing.
  *
  * This callback responds to the URL "ooyala/ping" within the Drupal site.
Index: ooyala_upload.js
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/ooyala/ooyala_upload.js,v
retrieving revision 1.4
diff -u -r1.4 ooyala_upload.js
--- ooyala_upload.js	6 Dec 2009 01:54:34 -0000	1.4
+++ ooyala_upload.js	19 Jan 2010 23:40:13 -0000
@@ -7,10 +7,6 @@
 
 Drupal.ooyala = Drupal.ooyala || {};
 
-Drupal.ooyala.triggerEvent = function() {
-  console.log(args);
-}
-
 Drupal.ooyala.onFileSelected = function(file) {
   $('.ooyala-button-container').removeClass('ooyala-finished');
   $('#ooyala-message').empty().append(Drupal.t('File selected: !filename. Click "Upload" to transfer to the video provider.', { '!filename': '<span class="ooyala-filename">' + Drupal.checkPlain(file.name) + '</span>' }));
@@ -64,6 +60,48 @@
 }
 
 /**
+ * AJAX success handler.
+ */
+Drupal.ooyala.refreshThumbanil = function(data) {
+  $('.ooyala-preview').removeClass('ooyala-progress').find('.throbber').remove();
+
+  if (!data['error']) {
+    var preview = $('.ooyala-preview').removeClass('ooyala-preview-hidden').get(0);
+    $(preview).html(data['content']);
+
+    var image = $('.ooyala-preview').find('img').get(0);
+    if (image) {
+      var src = $(image).attr('src');
+      var timestamp = new Date().getTime();
+      $(image).attr('src', src + '?' + timestamp);
+    }
+  }
+
+  if (data['message']) {
+    alert(data['message']);
+  }
+}
+
+/**
+ * Add AJAX functionality to the thumbnail refresh link.
+ */
+Drupal.behaviors.ooyalaRefreshThumbnail = function(context) {
+  $('a.ooyala-refresh', context).click(function() {
+    var embedcode = $(this).parents('.ooyala-button-container').find('.ooyala-embed-code-input').val();
+    $(this).parents('.ooyala-field').find('.ooyala-preview')
+      .addClass('ooyala-progress')
+      .append('<span class="throbber">&nbsp;</span>');
+    $.ajax({
+      url: Drupal.settings.ooyalaRefreshUrl,
+      success: Drupal.ooyala.refreshThumbanil,
+      dataType: 'json',
+      data: { embedcode: embedcode }
+    });
+    return false;
+  });
+}
+
+/**
  * This function is called by naming convention when the uploader finishes.
  */
 function onOoyalaUploaderReady() {
Index: ooyala.css
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/ooyala/ooyala.css,v
retrieving revision 1.1
diff -u -r1.1 ooyala.css
--- ooyala.css	24 Nov 2009 18:59:12 -0000	1.1
+++ ooyala.css	19 Jan 2010 23:40:12 -0000
@@ -1,10 +1,49 @@
 /* $Id: ooyala.css,v 1.1 2009/11/24 18:59:12 quicksketch Exp $ */
 
+div.ooyala-preview {
+  float: left;
+  text-align: center;
+  position: relative;
+  width: 150px;
+  min-height: 100px;
+  padding: 10px;
+}
+
+div.ooyala-preview-hidden {
+  display: none;
+}
+
+div.ooyala-preview-placeholder {
+  width: 130px;
+  border: 1px solid #CCC;
+  text-align: center;
+  text-transform: uppercase;
+  color: #999;
+  padding: 30px 10px;
+}
+
 div.ooyala-button-container input.form-text {
   display: inline;
   width: auto;
 }
 
+div.ooyala-progress div {
+  opacity: 0.25;
+  filter: alpha(opacity=25);
+}
+
+div.ooyala-progress span.throbber {
+  display: block;
+  width: 150px;
+  height: 24px;
+  top: 40px;
+  left: 0;
+  position: absolute;
+  z-index: 20;
+  padding: 10px;
+  background: url(throbber.gif) no-repeat center center;
+}
+
 #ooyala-message span.percentage {
   font-weight: bold;
 }
Index: ooyala.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/ooyala/ooyala.module,v
retrieving revision 1.14
diff -u -r1.14 ooyala.module
--- ooyala.module	19 Jan 2010 23:33:00 -0000	1.14
+++ ooyala.module	19 Jan 2010 23:40:13 -0000
@@ -35,6 +35,12 @@
     'file' => 'includes/ooyala.pages.inc',
     'type' => MENU_CALLBACK,
   );
+  $items['ooyala/thumbnail'] = array(
+    'page callback' => 'ooyala_refresh_thumbnail',
+    'access arguments' => array('upload ooyala videos'),
+    'file' => 'includes/ooyala.pages.inc',
+    'type' => MENU_CALLBACK,
+  );
   $items['ooyala/ping'] = array(
     'page callback' => 'ooyala_ping',
     'access arguments' => array('access content'),
@@ -121,13 +127,18 @@
     'ooyala_upload' => array(
       'arguments' => array('element' => NULL),
     ),
+    'ooyala_upload_preview' => array(
+      'arguments' => array('embedcode' => NULL),
+    ),
     'ooyala_thumbnail' => array(
       'arguments' => array(
-        'thumbpath' => NULL,
-        'link_to_node' => NULL,
-        'link_attributes' => NULL
+        'src' => NULL,
+        'preset' => NULL,
+        'link_href' => NULL,
+        'link_attributes' => array(),
+        'image_attributes' => array(),
+        'get_size' => FALSE,
       ),
-      'template' => 'templates/ooyala-thumbnail',
     ),
   );
 
@@ -393,6 +404,9 @@
 
   $element['#theme'] = 'ooyala_upload';
   $element['#field'] = $field;
+  $element['#ooyala_api_available'] = ooyala_api_available();
+  $element['#ooyala_video'] = isset($element['#value'][0]['value']) ? ooyala_api_video_load($element['#value'][0]['value']) : array();
+
   $element['value'] = array(
     '#type' => 'textfield',
     '#title' => $element['#title'],
@@ -459,6 +479,18 @@
 }
 
 /**
+ * Check if Ooyala APIs are available.
+ */
+function ooyala_api_available() {
+  static $online;
+  if (!isset($online)) {
+    $response = drupal_http_request("http://api.ooyala.com/partner/query");
+    $online = $response->code == 200;
+  }
+  return $online;
+}
+
+/**
  * Load an individual video from Ooyala.
  */
 function ooyala_api_video_load($embedcode) {
@@ -547,7 +579,7 @@
   if ($response->data && $xmldoc = @simplexml_load_string($response->data)) {
     $thumb_url = (string) $xmldoc->promoThumbnail[0] ; // we just want the big thumbnail. 
     $thumb_file = drupal_http_request($thumb_url);
-    $thumb_path = _ooyala_get_thumbnail_url($embedcode, NULL, TRUE);
+    $thumb_path = ooyala_get_thumbnail_url($embedcode, NULL, TRUE);
     if ($fp = @fopen($thumb_path, 'w+')) {
       fwrite($fp, $thumb_file->data);
       fclose($fp);
@@ -578,7 +610,7 @@
     ooyala_message('The thumbnail for the video "@embedcode" could not be retrieved from Ooyala because the service returned an HTTP error @code.', array('@embedcode' => $embedcode, '@code' => $response->code), 'error');
   }
 
-   return $thumb_path;
+  return $thumb_path;
 }
 
 /**
@@ -624,24 +656,56 @@
   if (!isset($js_added)) {
     drupal_add_css(drupal_get_path('module', 'ooyala') . '/ooyala.css');
     drupal_add_js(drupal_get_path('module', 'ooyala') . '/ooyala_upload.js');
-    drupal_add_js(array('ooyalaUploadUrl' => url('ooyala/js/' . $element['#field']['field_name'])), 'setting');
+    drupal_add_js(array(
+      'ooyalaUploadUrl' => url('ooyala/js/' . $element['#field']['field_name']),
+      'ooyalaRefreshUrl' => url('ooyala/thumbnail', array('query' => 'token=' . drupal_get_token())),
+    ), 'setting');
     $js_added = TRUE;
   }
 
   $node_type = node_get_types('type', $element['#field']['type_name']);
-  $initial_message = t('Note that you must enter a @title value for this content before selecting a file.', array('@title' => $node_type->title_label));
+  $status = empty($element['#ooyala_video']) ? 'unknown' : $element['#ooyala_video']['status'];
+  $online = $element['#ooyala_api_available'];
+
+  if ($online) {
+    $upload_button = '<script src="http://www.ooyala.com/partner/uploadButton?width=100&height=20&label=' . t('Browse') . '""></script>';
+    $submit_button = '<input type="button" class="form-submit" value="' . t('Upload') .'" id="ooyala-upload-button" disabled="disabled" />';
+    $initial_message = t('Note that you must enter a @title value for this content before selecting a file.', array('@title' => $node_type->title_label));
+    $element['value']['#field_suffix'] = $upload_button . $submit_button;
 
-  $upload_button = '<script src="http://www.ooyala.com/partner/uploadButton?width=100&height=20&label=' . t('Browse') . '""></script>';
-  $submit_button = '<input type="button" class="form-submit" value="' . t('Upload') .'" id="ooyala-upload-button" disabled="disabled" />';
+    $refresh_link = '<div class="ooyala-refresh"><a href="#" class="ooyala-refresh">' . t('Preview/refresh thumbnail') . '</a></div>';
+  }
+  else {
+    $initial_message = '<em>' . t('Uploading is currently not available because the Ooyala service could not be reached.') . '</em>';
+    $refresh_link = '';
+  }
   $element['value']['#size'] = '40';
-  $element['value']['#description'] = $element['value']['#description'] . '<div id="ooyala-message">' . $initial_message . '</div>';
-  $element['value']['#field_suffix'] = $upload_button . $submit_button;
+  $element['value']['#description'] = $element['value']['#description'] . '<div id="ooyala-message">' . $initial_message . '</div>' . $refresh_link;
   $element['value']['#attributes']['class'] = 'ooyala-embed-code-input';
 
   $output = '';
+  $output .= '<div class="ooyala-field">';
+  $output .= '<div class="ooyala-preview' . ($element['value']['#value'] ? '' : ' ooyala-preview-hidden') . '">';
+  $output .= theme('ooyala_upload_preview', $element['value']['#value']);
+  $output .= '</div>';
   $output .= '<div class="ooyala-button-container">';
   $output .= drupal_render($element['value']);
   $output .= '</div>';
+  $output .= '</div>';
+  return $output;
+}
+
+/**
+ * Theme the preview thumbnail on the node form.
+ */
+function theme_ooyala_upload_preview($embedcode = NULL) {
+  if (isset($embedcode)) {
+    $output = theme('ooyala_thumbnail', $embedcode, NULL, NULL, NULL, array('width' => 150), FALSE);
+  }
+  else {
+    $output = '<div class="ooyala-preview-placeholder">' . t('No Preview Available') . '</div>';
+  }
+
   return $output;
 }
 
@@ -657,10 +721,10 @@
 
   switch ($formatter[1]) {
     case 'ooyala_imagecache':
-      $return = theme('ooyala_thumbnail', _ooyala_get_thumbnail_url($element['#item']['value'], $preset), FALSE);
+      $return = theme('ooyala_thumbnail', $element['#item']['value'], $preset);
       break;
     case 'ooyala_linked_imagecache':
-      $return = theme('ooyala_thumbnail', _ooyala_get_thumbnail_url($element['#item']['value'], $preset), url('node/' . $element['#node']->nid));
+      $return = theme('ooyala_thumbnail', $element['#item']['value'], $preset, 'node/' . $element['#node']->nid);
       break;
     case 'ooyala_thickbox':
       $return = theme('ooyala_formatter_ooyala_thickbox', $element, $preset);
@@ -687,7 +751,7 @@
     $values[] = ($allowed = _text_allowed_values($item)) ? $allowed : $item['#item']['safe'];
   }
 
-  // TODO: Make this formatter work on mulitple values.
+  // TODO: Make this formatter work on multiple values.
   return theme('ooyala_player', implode($values));
 }
 
@@ -695,27 +759,21 @@
  * Theme function to output the "ooyala_thumbnail" formatter.
  */
 function theme_ooyala_formatter_ooyala_thumbnail($element) {
-  $values = array();
+  $output = '';
   foreach (element_children($element) as $key) {
     $item = $element[$key];
     if ($item['#item']['value']) {
-      $values[] = _ooyala_get_thumbnail_url($item['#item']['value'], NULL);
+      $output .= theme('ooyala_thumbnail', $item['#item']['value']);
     }
   }
 
-  foreach ($values as $value) {
-    $return .= theme('ooyala_thumbnail', $value, NULL );
-  }
-  return $return;
+  return $output;
 }
 
 /**
  * Theme function to output the "ooyala_thickbox" formatter.
  */
 function theme_ooyala_formatter_ooyala_thickbox($element, $preset = NULL) {
-  $embededcode = $element['#item']['value'];
-
-  $image_url = _ooyala_get_thumbnail_url($embededcode, $preset);
   $link_url = url('ooyalavideo', array('query' => array(
     'KeepThis' => 'true',
     'TB_iframe' => 'true',
@@ -723,17 +781,41 @@
     'height' => variable_get('ooyala_thickbox_height', 400),
   )));
 
-  $return = theme('ooyala_thumbnail', $image_url, $link_url, array('class' => 'thickbox'));
+  $return = theme('ooyala_thumbnail', $element['#item']['value'], $preset, $link_url, array('class' => 'thickbox'));
 
   return $return;
 }
 
 /**
- * Preprocess function for ooyala-thumbnail.tpl.php.
+ * Themed output for an Ooyala thumbnail.
  */
-function template_preprocess_ooyala_thumbnail(&$variables) {
-  $image_code = sprintf('<img src=%s />', $variables['thumbpath']);
-  $variables['thumbnail_code'] = ($variables['link_to_node'])? sprintf('<a href=%s %s>%s</a>', $variables['link_to_node'], drupal_attributes($variables['link_attributes']), $image_code) : $image_code;
+function theme_ooyala_thumbnail($embedcode, $preset = NULL, $link_href = NULL, $link_attributes = array(), $image_attributes = array(), $get_size = TRUE) {
+  $src = ooyala_get_thumbnail_url($embedcode, NULL, TRUE);
+
+  // Retrieve the alt and title variables to be passed to other theme functions.
+  $image_attributes += array('alt' => '', 'title' => '');
+  $alt = $image_attributes['alt'];
+  $title = $image_attributes['title'];
+  unset($image_attributes['alt'], $image_attributes['title']);
+
+  // Generate the img tag.
+  if (isset($preset)) {
+    $output = theme('imagecache', $preset, $src, $alt, $title, $image_attributes, $get_size);
+  }
+  else {
+    $output = theme('image', $src, $alt, $title, $image_attributes, $get_size);
+  }
+
+  // Wrap if needed in our link.
+  if ($link_href) {
+    $options = array(
+      'html' => TRUE,
+      'attributes' => $link_attributes,
+    );
+    $output = l($output, $link_href, $options);
+  }
+
+  return '<div class="ooyala-thumbnail">' . $output .'</div>';
 }
 
 /**
@@ -767,10 +849,10 @@
 /**
  * Helper function to generate a thumbnail URL from an Ooyala video code.
  */
-function _ooyala_get_thumbnail_url($embededcode, $preset = NULL, $return_path = FALSE) {
+function ooyala_get_thumbnail_url($embedcode, $preset = NULL, $return_path = FALSE) {
   $directory = file_create_path(variable_get('ooyala_thumbnail_path', 'ooyalathumbs'));
   _ooyala_check_directory($directory);
-  $path = $directory . '/' . $embededcode . '.jpg';
+  $path = $directory . '/' . $embedcode . '.jpg';
 
   if ($return_path) {
     return $path;
@@ -788,8 +870,8 @@
     // Save this embeded code to download the thumbnail on next cron run.
     $thumbnails_to_get = variable_get('ooyala_pending_thumbnails', array());
 
-    if ($embededcode && !isset($thumbnails_to_get[$embededcode])) {
-      $thumbnails_to_get[$embededcode] = $embededcode;
+    if ($embedcode && !isset($thumbnails_to_get[$embedcode])) {
+      $thumbnails_to_get[$embedcode] = $embedcode;
       variable_set('ooyala_pending_thumbnails', $thumbnails_to_get);
       drupal_set_message(t('The thumbnail will be downloaded from Ooyala in the next Cron run'), 'status');
     }
Index: templates/ooyala-thumbnail.tpl.php
===================================================================
RCS file: templates/ooyala-thumbnail.tpl.php
diff -N templates/ooyala-thumbnail.tpl.php
--- templates/ooyala-thumbnail.tpl.php	11 Nov 2009 00:33:47 -0000	1.1
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,3 +0,0 @@
-<div class='ooyala_thumbnail'>
-	<?php print $thumbnail_code ?>
-</div>
\ No newline at end of file
