/**
 * @file
 * Provides JavaScript additions to the media field widget.
 *
 * This file provides support for launching the media browser to select existing
 * files and disabling of other media fields during Ajax uploads (which prevents
 * separate media fields from accidentally attaching files).
 */

(function ($) {

/**
 * Attach behaviors to media element upload fields.
 */
Drupal.behaviors.mediaElement = {
  attach: function (context, settings) {
    var $context = $(context);
    var elements;

    function initMediaBrowser(selector) {
      var widget=$context.find(selector).once('media-browser-launch');
      var browse=widget.siblings('.browse').add(widget.find('.browse'));
      var upload=browse.siblings('.upload').add(widget.find('.upload'));
      var attach=upload.siblings('.attach').add(widget.find('.attach'));
      browse.show();
      upload.hide();
      attach.hide();
      browse.bind('click', {configuration: settings.media.elements[selector]}, Drupal.media.openBrowser);
    }

    if (settings.media && settings.media.elements) {
      elements = settings.media.elements;
      Object.keys(elements).forEach(initMediaBrowser);
    }
  },
  detach: function (context, settings, trigger) {
    var $context = $(context);
    var elements;

    function removeMediaBrowser(selector) {
      $context.find(selector)
        .removeOnce('media-browser-launch')
        .siblings('.browse').hide()
        .siblings('.upload').show()
        .siblings('.attach').show()
        .siblings('.browse').unbind('click', Drupal.media.openBrowser);
    }

    if (trigger === 'unload' && settings.media && settings.media.elements) {
      elements = settings.media.elements;
      Object.keys(elements).forEach(removeMediaBrowser);
    }
  }
};

/**
 * Attach behaviors to the media attach and remove buttons.
 */
Drupal.behaviors.mediaButtons = {
  attach: function (context) {
    $('input.form-submit', context).bind('mousedown', Drupal.media.disableFields);
  },
  detach: function (context) {
    $('input.form-submit', context).unbind('mousedown', Drupal.media.disableFields);
  }
};

/**
 * Media attach utility functions.
 */
Drupal.media = Drupal.media || {};

/**
 * Opens the media browser with the element's configuration settings.
 */
Drupal.media.openBrowser = function (event) {
  var clickedButton = this;
  var configuration = event.data.configuration.global;

  // Find the file ID, preview and upload fields.
  var fidField = $(this).siblings('.fid');
  var previewField = $(this).siblings('.preview');
  var uploadField = $(this).siblings('.upload');

  // Find the edit and remove buttons.
  var editButton = $(this).siblings('.edit');
  var removeButton = $(this).siblings('.remove');

  // Launch the media browser.
  Drupal.media.popups.mediaBrowser(function (mediaFiles) {
    // Ensure that there was at least one media file selected.
    if (mediaFiles.length < 0) {
      return;
    }

    var mediaFileValue;
    // Process the value based on multiselect.
    if (mediaFiles.length > 1) {
      // Concatenate the array into a comma separated string.
      mediaFileValue = mediaFiles.map(function(file) {
        return file.fid;
      }).join(',');
    }
    else {
      // Grab the first of the selected media files.
      mediaFileValue = mediaFiles[0].fid;

      // Display a preview of the file using the selected media file's display.
      previewField.html(mediaFileValue.preview);
    }

    // Set the value of the hidden file ID field and trigger a change.
    uploadField.val(mediaFileValue);
    uploadField.trigger('change');

    // Find the attach button and automatically trigger it.
    var attachButton = uploadField.siblings('.attach');
    attachButton.trigger('mousedown');
  }, configuration);

  return false;
};

/**
 * Prevent media browsing when using buttons not intended to browse.
 */
Drupal.media.disableFields = function (event) {
  var clickedButton = this;

  // Only disable browse fields for Ajax buttons.
  if (!$(clickedButton).hasClass('ajax-processed')) {
    return;
  }

  // Check if we're working with an "Attach" button.
  var $enabledFields = [];
  if ($(this).closest('div.media-widget').length > 0) {
    $enabledFields = $(this).closest('div.media-widget').find('input.attach');
  }

  // Temporarily disable attach fields other than the one we're currently
  // working with. Filter out fields that are already disabled so that they
  // do not get enabled when we re-enable these fields at the end of behavior
  // processing. Re-enable in a setTimeout set to a relatively short amount
  // of time (1 second). All the other mousedown handlers (like Drupal's Ajax
  // behaviors) are excuted before any timeout functions are called, so we
  // don't have to worry about the fields being re-enabled too soon.
  // @todo If the previous sentence is true, why not set the timeout to 0?
  var $fieldsToTemporarilyDisable = $('div.media-widget input.attach').not($enabledFields).not(':disabled');
  $fieldsToTemporarilyDisable.attr('disabled', 'disabled');
  setTimeout(function (){
    $fieldsToTemporarilyDisable.attr('disabled', false);
  }, 1000);
};

})(jQuery);
