/**
 * @file
 * A Backbone Model for the state of a contextual link's trigger, list & region.
 */

(function (Drupal, Backbone) {

  'use strict';

  /**
   * Models the state of a contextual link's trigger, list & region.
   *
   * @constructor
   *
   * @augments Backbone.Model
   */
  Drupal.contextual.StateModel = Backbone.Model.extend(/** @lends Drupal.contextual.StateModel# */{

    /**
     * @type {object}
     *
     * @prop {string} title
     * @prop {bool} regionIsHovered
     * @prop {bool} hasFocus
     * @prop {bool} isOpen
     * @prop {bool} isLocked
     */
    defaults: /** @lends Drupal.contextual.StateModel# */{

      /**
       * The title of the entity to which these contextual links apply.
       *
       * @type {string}
       */
      title: '',

      /**
       * Represents if the contextual region is being hovered.
       *
       * @type {bool}
       */
      regionIsHovered: false,

      /**
       * Represents if the contextual trigger or options have focus.
       *
       * @type {bool}
       */
      hasFocus: false,

      /**
       * Represents if the contextual options for an entity are available to
       * be selected (i.e. whether the list of options is visible).
       *
       * @type {bool}
       */
      isOpen: false,

      /**
       * When the model is locked, the trigger remains active.
       *
       * @type {bool}
       */
      isLocked: false
    },

    /**
     * Opens or closes the contextual link.
     *
     * If it is opened, then also give focus.
     *
     * @return {Drupal.contextual.StateModel}
     *   The current contextual state model.
     */
    toggleOpen: function () {
      var newIsOpen = !this.get('isOpen');
      this.set('isOpen', newIsOpen);
      if (newIsOpen) {
        this.focus();
      }
      return this;
    },

    /**
     * Closes this contextual link.
     *
     * Does not call blur() because we want to allow a contextual link to have
     * focus, yet be closed for example when hovering.
     *
     * @return {Drupal.contextual.StateModel}
     *   The current contextual state model.
     */
    close: function () {
      this.set('isOpen', false);
      return this;
    },

    /**
     * Gives focus to this contextual link.
     *
     * Also closes + removes focus from every other contextual link.
     *
     * @return {Drupal.contextual.StateModel}
     *   The current contextual state model.
     */
    focus: function () {
      this.set('hasFocus', true);
      var cid = this.cid;
      this.collection.each(function (model) {
        if (model.cid !== cid) {
          model.close().blur();
        }
      });
      return this;
    },

    /**
     * Removes focus from this contextual link, unless it is open.
     *
     * @return {Drupal.contextual.StateModel}
     *   The current contextual state model.
     */
    blur: function () {
      if (!this.get('isOpen')) {
        this.set('hasFocus', false);
      }
      return this;
    }

  });

})(Drupal, Backbone);
