/**
 * @file
 * Defines the behaviors needed for cropper integration.
 */

(function ($, Drupal, debounce) {
  'use strict';

  var $window = $(window);

  /**
   * @class Drupal.ImageWidgetCrop
   *
   * @param {HTMLElement|jQuery} element
   *   The wrapper element.
   */
  Drupal.ImageWidgetCrop = function (element) {

    /**
     * The wrapper element.
     *
     * @type {jQuery}
     */
    this.$wrapper = $(element);

    /**
     * The summary element.
     *
     * @type {jQuery}
     */
    this.$summary = this.$wrapper.find(this.selectors.summary).first();

    /**
     * Flag indicating whether the instance has been initialized.
     *
     * @type {Boolean}
     */
    this.initialized = false;

    /**
     * The current summary text.
     *
     * @type {String}
     */
    this.summary = Drupal.t('Crop image');

    /**
     * The individual ImageWidgetCropType instances.
     *
     * @type {Array.<Drupal.ImageWidgetCropType>}
     */
    this.types = [];

    // Initialize the instance.
    this.init();
  };

  /**
   * The selectors used to identify elements for this module.
   *
   * @type {Object.<String, String>}
   */
  Drupal.ImageWidgetCrop.prototype.selectors = {
    // Unfortunately, core does not provide a way to inject attributes into the
    // wrapper element's "summary" in a stable way. So, we can only target
    // the immediate children known to be the likely elements. Contrib can
    // extend this selector if needed.
    summary: '> summary, > legend',
    types: '[data-drupal-iwc=type]',
    wrapper: '[data-drupal-iwc=wrapper]'
  };

  /**
   * Destroys this instance.
   */
  Drupal.ImageWidgetCrop.prototype.destroy = function () {
    this.types.forEach(function (type) {
      type.destroy();
    });
  };

  /**
   * Initializes the instance.
   */
  Drupal.ImageWidgetCrop.prototype.init = function () {
    if (this.initialized) {
      return;
    }

    // Find all the types.
    var _this = this;
    this.$wrapper.find(this.selectors.types).each(function () {
      _this.types.push(new Drupal.ImageWidgetCropType(_this, this));
    });

    // Debounce resize event to prevent any issues.
    $window.on('resize.iwc', debounce(this.resize.bind(this), 250));

    // Update the summary when triggered from vertical tabs underneath it.
    this.$wrapper.on('summaryUpdated', this.updateSummary.bind(this));

    // Trigger the initial summaryUpdate event.
    this.$wrapper.trigger('summaryUpdated');
  };

  /**
   * The "resize" event callback.
   *
   * @see Drupal.ImageWidgetCropType.prototype.resize
   */
  Drupal.ImageWidgetCrop.prototype.resize = function () {
    var args = arguments;

    // Proxy the resize event to each ImageWidgetCropType instance.
    this.types.forEach(function (type) {
      type.resize.apply(type, args);
    });
  };

  /**
   * Updates the summary of the wrapper.
   */
  Drupal.ImageWidgetCrop.prototype.updateSummary = function () {
    var text = Drupal.t('Crop image');

    // Determine if any ImageWidgetCropType has been applied.
    for (var i = 0, l = this.types.length; i < l; i++) {
      var type = this.types[i];
      if (type.getValue('applied')) {
        text = Drupal.t('Crop image (cropping applied)');
        break;
      }
    }

    if (this.summary !== text) {
      this.$summary.text(this.summary = text);
    }
  };

}(jQuery, Drupal, Drupal.debounce));
