/**
 * @file
 *
 * Dialog API inspired by HTML5 dialog element:
 * http://www.whatwg.org/specs/web-apps/current-work/multipage/commands.html#the-dialog-element
 */
(function ($) {

"use strict";

Backdrop.settings.dialog = {
  // This option will turn off resizable and draggable.
  autoResize: true,
  // jQuery UI does not support percentage heights, but we convert this property
  // in the resetPosition() function.
  maxHeight: '95%',
  // jQuery UI defaults to 300px, use 100% width to allow for responsive
  // dialogs. CSS can override by specifying a max-width.
  width: '100%',
  position: { my: "center", at: "center", of: window },
  close: function (e) {
    Backdrop.detachBehaviors(e.target, null, 'unload');
  }
};

Backdrop.dialog = function (element, options) {

  function openDialog (settings) {
    settings = $.extend({}, Backdrop.settings.dialog, options, settings);
    settings.beforeClose = beforeClose;

    // Add class to the page to modify overall page display.
    $('html').addClass('dialog-open');

    // Trigger a global event to allow scripts to bind events to the dialog.
    $(window).trigger('dialog:beforecreate', [dialog, $element, settings]);
    $element.dialog(settings);

    if (settings.autoResize === true || settings.autoResize === 'true') {
      // Add a class specifically to help to lock scrolling.
      $('html').addClass('dialog-auto-resize');

      // Callback function for positioning the dialog on resize/scroll.
      var resetPosition = function() {
        var positionOptions = ['width', 'height', 'minWidth', 'minHeight', 'maxHeight', 'maxWidth', 'position'];
        var windowHeight = $(window).height();
        var adjustedOptions = {};
        var option, optionValue, adjustedValue;
        for (var n = 0; n < positionOptions.length; n++) {
          option = positionOptions[n];
          optionValue = settings[option];
          if (optionValue) {
            // jQuery UI does not support percentages on heights, convert to pixels.
            if (typeof optionValue === 'string' && /%$/.test(optionValue) && /height/i.test(option)) {
              adjustedValue = parseInt(0.01 * parseInt(optionValue, 10) * windowHeight, 10);
              // Don't force the dialog to be bigger vertically than needed.
              if (option === 'height' && $element.parent().outerHeight() < adjustedValue) {
                adjustedValue = 'auto';
              }
              adjustedOptions[option] = adjustedValue;
            }
            else {
              adjustedOptions[option] = optionValue;
            }
          }
        }
        $element.dialog('option', adjustedOptions);
      };

      // If auto-resized, it can't be manually resized or moved.
      $element
        .dialog('option', {
            resizable: false,
            draggable: false
        })
        .dialog('widget').css('position', 'fixed');
      Backdrop.optimizedResize.add(resetPosition, 'dialogResize.' + dialogId);
      resetPosition();
    }
    dialog.open = true;
    $(window).trigger('dialog:aftercreate', [dialog, $element, settings]);
  }

  function closeDialog (value) {
    $(window).trigger('dialog:beforeclose', [dialog, $element]);
    $element.dialog('close');
    dialog.returnValue = value;
    dialog.open = false;
    $(window).trigger('dialog:afterclose', [dialog, $element]);
  }

  /**
   * jQuery UI callback fired just before closing the dialog.
   *
   * This callback fires in all situations where the modal is closed, rather
   * than only through the Backdrop dialog API. For example hitting the escape
   * key or using the close button, which are triggered by jQuery UI directly.
   */
  function beforeClose (event, ui) {
    $('html').removeClass('dialog-open dialog-auto-resize');
    Backdrop.optimizedResize.remove('dialogResize.' + dialogId);
  }

  var undef;
  var $element = $(element);

  // Generate a dialog ID based on the microsecond the dialog was created.
  // When binding and unbinding window resize events, we use this ID to track
  // each individual dialog.
  var dialogId = Date.now().toString();

  var dialog = {
    open: false,
    returnValue: undef,
    show: function () {
      openDialog({modal: false});
    },
    showModal: function () {
      openDialog({modal: true});
    },
    close: closeDialog
  };

  return dialog;
};

})(jQuery);
