text: /**
   * Plugin which allows items to be dropped onto a toolbar and be turned into new Toolbar items.
   * To use the plugin, you just need to provide a createItem implementation that takes the drop
   * data as an argument and returns an object that can be placed onto the toolbar. Example:
   * <pre>
   * Ext.create('Ext.ux.ToolbarDroppable', {
   *   createItem: function(data) {
   *     return Ext.create('Ext.Button', {text: data.text});
   *   }
   * });
   * </pre>
   * The afterLayout function can also be overridden, and is called after a new item has been
   * created and inserted into the Toolbar. Use this for any logic that needs to be run after
   * the item has been created.
   */
   Ext.define('Ext.ux.ToolbarDroppable', {
  
      /**
       * Creates new ToolbarDroppable.
       * @param {Object} config Config options.
       */
      constructor: function(config) {
        Ext.apply(this, config);
      },
  
      /**
       * Initializes the plugin and saves a reference to the toolbar
       * @param {Ext.toolbar.Toolbar} toolbar The toolbar instance
       */
      init: function(toolbar) {
        /**
         * @property toolbar
         * @type Ext.toolbar.Toolbar
         * The toolbar instance that this plugin is tied to
         */
        this.toolbar = toolbar;
  
        this.toolbar.on({
            scope : this,
            render: this.createDropTarget
        });
      },
  
      /**
       * Creates a drop target on the toolbar
       */
      createDropTarget: function() {
          /**
           * @property dropTarget
           * @type Ext.dd.DropTarget
           * The drop target attached to the toolbar instance
           */
          this.dropTarget = Ext.create('Ext.dd.DropTarget', this.toolbar.getEl(), {
              notifyOver: Ext.Function.bind(this.notifyOver, this),
              notifyDrop: Ext.Function.bind(this.notifyDrop, this)
          });
      },
  
      /**
       * Adds the given DD Group to the drop target
       * @param {String} ddGroup The DD Group
       */
      addDDGroup: function(ddGroup) {
          this.dropTarget.addToGroup(ddGroup);
      },
  
      /**
       * Calculates the location on the toolbar to create the new sorter button based on the XY of the
       * drag event
       * @param {Ext.EventObject} e The event object
       * @return {Number} The index at which to insert the new button
       */    
      calculateEntryIndex: function(e) {
          var entryIndex = 0,
              toolbar = this.toolbar,
              items = toolbar.items.items,
              count = items.length,
              xHover = e.getXY()[0],
              index = 0,
              el, xTotal, width, midpoint;
   
          for (; index < count; index++) {
              el = items[index].getEl();
              xTotal = el.getXY()[0];
              width = el.getWidth();
              midpoint = xTotal + width / 2;
   
              if (xHover < midpoint) {
                  entryIndex = index; 
                  break;
              } else {
                  entryIndex = index + 1;
              }
         }
         return entryIndex;
      },
  
      /**
       * Returns true if the drop is allowed on the drop target. This function can be overridden
       * and defaults to simply return true
       * @param {Object} data Arbitrary data from the drag source
       * @return {Boolean} True if the drop is allowed
       */
      canDrop: function(data) {
          return true;
      },
  
      /**
       * Custom notifyOver method which will be used in the plugin's internal DropTarget
       * @return {String} The CSS class to add
       */
      notifyOver: function(dragSource, event, data) {
          return this.canDrop.apply(this, arguments) ? this.dropTarget.dropAllowed : this.dropTarget.dropNotAllowed;
      },
  
      /**
       * Called when the drop has been made. Creates the new toolbar item, places it at the correct location
       * and calls the afterLayout callback.
       */
      notifyDrop: function(dragSource, event, data) {
          var canAdd = this.canDrop(dragSource, event, data),
              tbar   = this.toolbar;
  
          if (canAdd) {
              var entryIndex = this.calculateEntryIndex(event);
  
              tbar.insert(entryIndex, this.createItem(data));
              tbar.doLayout();
  
              this.afterLayout();
          }
  
          return canAdd;
      },
  
      /**
       * Creates the new toolbar item based on drop data. This method must be implemented by the plugin instance
       * @param {Object} data Arbitrary data from the drop
       * @return {Mixed} An item that can be added to a toolbar
       */
      createItem: function(data) {
          //<debug>
          Ext.Error.raise("The createItem method must be implemented in the ToolbarDroppable plugin");
          //</debug>
      },
  
      /**
       * Called after a new button has been created and added to the toolbar. Add any required cleanup logic here
       */
      afterLayout: Ext.emptyFn
  });
  