/**
 * @file
 * Extends the Backdrop AJAX functionality to integrate the dialog API.
 */

(function ($) {

"use strict";

Backdrop.behaviors.dialog = {
  attach: function (context) {
    // Provide a known 'backdrop-modal' DOM element for Backdrop-based modal
    // dialogs. Non-modal dialogs are responsible for creating their own
    // elements, since there can be multiple non-modal dialogs at a time.
    if (!$('#backdrop-modal').length) {
      $('<div id="backdrop-modal" />').hide().appendTo('body');
    }

    // Special behaviors specific when attaching content within a dialog.
    // These behaviors usually fire after a validation error inside a dialog.
    var $dialog = $(context).closest('.ui-dialog-content');
    if ($dialog.length) {
      // Remove and replace the dialog buttons with those from the new form.
      if ($dialog.dialog('option', 'backdropAutoButtons')) {
        // Trigger an event to detect/sync changes to buttons.
        $dialog.trigger('dialogButtonsChange');
      }

      // Force focus on the modal when the behavior is run.
      $dialog.dialog('widget').trigger('focus');
    }
  },

  /**
   * Scan a dialog for any primary buttons and move them to the button area.
   *
   * @param $dialog
   *   An jQuery object containing the element that is the dialog target.
   * @return
   *   An array of buttons that need to be added to the button area.
   */
  prepareDialogButtons: function ($dialog) {
    var buttons = [];
    var $buttons = $dialog.find('.form-actions input[type=submit], .form-actions a.button');
    $buttons.each(function () {
      // Hidden form buttons need special attention. For browser consistency,
      // the button needs to be "visible" in order to have the enter key fire
      // the form submit event. So instead of a simple "hide" or
      // "display: none", we set its dimensions to zero.
      // See http://mattsnider.com/how-forms-submit-when-pressing-enter/
      var $originalButton = $(this).css({
        width: 0,
        height: 0,
        padding: 0,
        border: 0,
        overflow: 'hidden'
      });
      buttons.push({
        'text': $originalButton.html() || $originalButton.attr('value'),
        'class': $originalButton.attr('class'),
        'click': function (e) {
          $originalButton.trigger('mousedown').trigger('click').trigger('mouseup');
          e.preventDefault();
        }
      });
    });
    return buttons;
  }
};

/**
 * Command to open a dialog.
 */
Backdrop.ajax.prototype.commands.openDialog = function (ajax, response, status) {
  if (!response.selector) {
    return false;
  }
  var $dialog = $(response.selector);
  if (!$dialog.length) {
    // Create the element if needed.
    $dialog = $('<div id="' + response.selector.replace(/^#/, '') + '"/>').appendTo('body');
  }
  // Set up the wrapper, if there isn't one.
  if (!ajax.wrapper) {
    ajax.wrapper = $dialog.attr('id');
  }

  // Use the ajax.js insert command to populate the dialog contents.
  response.command = 'insert';
  response.method = 'html';
  ajax.commands.insert(ajax, response, status);

  // Move the buttons to the jQuery UI dialog buttons area.
  if (!response.dialogOptions.buttons) {
    response.dialogOptions.backdropAutoButtons = true;
    response.dialogOptions.buttons = Backdrop.behaviors.dialog.prepareDialogButtons($dialog);
  }

  // Bind dialogButtonsChange
  $dialog.on('dialogButtonsChange', function () {
    var buttons = Backdrop.behaviors.dialog.prepareDialogButtons($dialog);
    $dialog.dialog('option', 'buttons', buttons);
  });

  // Open the dialog itself.
  response.dialogOptions = response.dialogOptions || {};
  var dialog = Backdrop.dialog($dialog, response.dialogOptions);
  if (response.dialogOptions.modal) {
    dialog.showModal();
  }
  else {
    dialog.show();
  }

  // Add the standard Backdrop class for buttons for style consistency.
  $dialog.parent().find('.ui-dialog-buttonset').addClass('form-actions');
};

/**
 * Command to close a dialog.
 *
 * If no selector is given, it defaults to trying to close the modal.
 */
Backdrop.ajax.prototype.commands.closeDialog = function (ajax, response, status) {
  var $dialog = $(response.selector);
  if ($dialog.length) {
    Backdrop.dialog($dialog).close();
  }

  // Unbind dialogButtonsChange
  $dialog.off('dialogButtonsChange');
};

/**
 * Command to set a dialog property.
 *
 * jQuery UI specific way of setting dialog options.
 */
Backdrop.ajax.prototype.commands.setDialogOption = function (ajax, response, status) {
  var $dialog = $(response.selector);
  if ($dialog.length) {
    $dialog.dialog('option', response.optionName, response.optionValue);
  }
};

/**
 * Binds a listener on dialog creation to handle the cancel link.
 */
$(window).on('dialog:aftercreate', function (e, dialog, $element, settings) {
  $element.on('click.dialog', '.dialog-cancel', function (e) {
    dialog.close('cancel');
    e.preventDefault();
    e.stopPropagation();
  });
});

/**
 * Removes all 'dialog' listeners.
 */
$(window).on('dialog:beforeclose', function (e, dialog, $element) {
  $element.off('.dialog');
});

})(jQuery);