define(['jquery', 'lodash', 'ui/component', 'handlebars', 'lib/handlebars/helpers'], function ($$1, _, component, Handlebars, Helpers0) { 'use strict';

    $$1 = $$1 && Object.prototype.hasOwnProperty.call($$1, 'default') ? $$1['default'] : $$1;
    _ = _ && Object.prototype.hasOwnProperty.call(_, 'default') ? _['default'] : _;
    component = component && Object.prototype.hasOwnProperty.call(component, 'default') ? component['default'] : component;
    Handlebars = Handlebars && Object.prototype.hasOwnProperty.call(Handlebars, 'default') ? Handlebars['default'] : Handlebars;
    Helpers0 = Helpers0 && Object.prototype.hasOwnProperty.call(Helpers0, 'default') ? Helpers0['default'] : Helpers0;

    if (!Helpers0.__initialized) {
      Helpers0(Handlebars);
      Helpers0.__initialized = true;
    }
    var Template = Handlebars.template(function (Handlebars,depth0,helpers,partials,data) {
      this.compilerInfo = [4,'>= 1.0.0'];
    helpers = this.merge(helpers, Handlebars.helpers); data = data || {};
      var buffer = "", stack1, functionType="function", escapeExpression=this.escapeExpression, self=this;

    function program1(depth0,data) {
      
      
      return "vertical-action-bar";
      }

    function program3(depth0,data) {
      
      
      return "horizontal-action-bar";
      }

    function program5(depth0,data) {
      
      var buffer = "", stack1, helper;
      buffer += "\n    <button class=\"btn-info small ";
      stack1 = helpers['if'].call(depth0, (depth0 && depth0.conditional), {hash:{},inverse:self.noop,fn:self.program(6, program6, data),data:data});
      if(stack1 || stack1 === 0) { buffer += stack1; }
      buffer += "\" data-control=\"";
      if (helper = helpers.id) { stack1 = helper.call(depth0, {hash:{},data:data}); }
      else { helper = (depth0 && depth0.id); stack1 = typeof helper === functionType ? helper.call(depth0, {hash:{},data:data}) : helper; }
      buffer += escapeExpression(stack1)
        + "\" ";
      stack1 = helpers['if'].call(depth0, (depth0 && depth0.title), {hash:{},inverse:self.noop,fn:self.program(8, program8, data),data:data});
      if(stack1 || stack1 === 0) { buffer += stack1; }
      buffer += ">\n        ";
      stack1 = helpers['if'].call(depth0, (depth0 && depth0.icon), {hash:{},inverse:self.noop,fn:self.program(10, program10, data),data:data});
      if(stack1 || stack1 === 0) { buffer += stack1; }
      buffer += "\n        ";
      if (helper = helpers.label) { stack1 = helper.call(depth0, {hash:{},data:data}); }
      else { helper = (depth0 && depth0.label); stack1 = typeof helper === functionType ? helper.call(depth0, {hash:{},data:data}) : helper; }
      buffer += escapeExpression(stack1)
        + "\n    </button>\n    ";
      return buffer;
      }
    function program6(depth0,data) {
      
      
      return " conditional hidden";
      }

    function program8(depth0,data) {
      
      var buffer = "", stack1, helper;
      buffer += " title=\"";
      if (helper = helpers.title) { stack1 = helper.call(depth0, {hash:{},data:data}); }
      else { helper = (depth0 && depth0.title); stack1 = typeof helper === functionType ? helper.call(depth0, {hash:{},data:data}) : helper; }
      buffer += escapeExpression(stack1)
        + "\"";
      return buffer;
      }

    function program10(depth0,data) {
      
      var buffer = "", stack1, helper;
      buffer += "<span class=\"icon icon-";
      if (helper = helpers.icon) { stack1 = helper.call(depth0, {hash:{},data:data}); }
      else { helper = (depth0 && depth0.icon); stack1 = typeof helper === functionType ? helper.call(depth0, {hash:{},data:data}) : helper; }
      buffer += escapeExpression(stack1)
        + "\"></span>";
      return buffer;
      }

      buffer += "<aside class=\"action-bar ";
      stack1 = helpers['if'].call(depth0, (depth0 && depth0.vertical), {hash:{},inverse:self.program(3, program3, data),fn:self.program(1, program1, data),data:data});
      if(stack1 || stack1 === 0) { buffer += stack1; }
      buffer += " clearfix\">\n    ";
      stack1 = helpers.each.call(depth0, (depth0 && depth0.buttons), {hash:{},inverse:self.noop,fn:self.program(5, program5, data),data:data});
      if(stack1 || stack1 === 0) { buffer += stack1; }
      buffer += "\n</aside>\n";
      return buffer;
      });
    function mainTpl(data, options, asString) {
      var html = Template(data, options);
      return (asString || true) ? html : $(html);
    }

    /**
     * This program is free software; you can redistribute it and/or
     * modify it under the terms of the GNU General Public License
     * as published by the Free Software Foundation; under version 2
     * of the License (non-upgradable).
     *
     * This program is distributed in the hope that it will be useful,
     * but WITHOUT ANY WARRANTY; without even the implied warranty of
     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     * GNU General Public License for more details.
     *
     * You should have received a copy of the GNU General Public License
     * along with this program; if not, write to the Free Software
     * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
     *
     * Copyright (c) 2016 (original work) Open Assessment Technologies SA ;
     */

    /**
     * Defines an action bar
     * @type {Object}
     */
    var actionbar = {
      /**
       * Gets the definition of a button
       * @param {String} id - The identifier of the button
       * @returns {Object|undefined}
       */
      getButton: function getButton(id) {
        if (this.is('rendered')) {
          return this.buttons[id];
        }
      },
      /**
       * Gets the DOM element of a button
       * @param {String} id - The identifier of the button
       * @returns {jQuery|undefined}
       */
      getButtonElement: function getButtonElement(id) {
        if (this.is('rendered')) {
          return this.controls.$buttons[id];
        }
      },
      /**
       * Shows a button
       * @param {String} id - The identifier of the button
       * @returns {actionbar}
       */
      showButton: function showButton(id) {
        var $btn = this.getButtonElement(id);
        if ($btn) {
          $btn.removeClass('hidden');
        }
        return this;
      },
      /**
       * Hides a button
       * @param {String} id - The identifier of the button
       * @returns {actionbar}
       */
      hideButton: function hideButton(id) {
        var $btn = this.getButtonElement(id);
        if ($btn) {
          $btn.addClass('hidden');
        }
        return this;
      },
      /**
       * Toggles a button according to a condition
       * @param {String} id - The identifier of the button
       * @param {Boolean} condition - If the condition is `true` the button will be displayed
       * @returns {actionbar}
       */
      toggleButton: function toggleButton(id, condition) {
        var $btn = this.getButtonElement(id);
        if ($btn) {
          if (typeof condition !== 'undefined') {
            condition = !condition;
          }
          $btn.toggleClass('hidden', condition);
        }
        return this;
      },
      /**
       * Shows the conditional buttons
       * @returns {actionbar}
       */
      showConditionals: function showConditionals() {
        if (this.is('rendered')) {
          this.controls.$conditional.removeClass('hidden');
        }
        return this;
      },
      /**
       * Hides the conditional buttons
       * @returns {actionbar}
       */
      hideConditionals: function hideConditionals() {
        if (this.is('rendered')) {
          this.controls.$conditional.addClass('hidden');
        }
        return this;
      },
      /**
       * Toggles the conditional buttons according to a condition
       * @param {Boolean} condition - If the condition is `true` the conditional buttons will be displayed
       * @returns {actionbar}
       */
      toggleConditionals: function toggleConditionals(condition) {
        if (this.is('rendered')) {
          if (typeof condition !== 'undefined') {
            condition = !condition;
          }
          this.controls.$conditional.toggleClass('hidden', condition);
        }
        return this;
      },
      /**
       * Shows all the buttons
       * @returns {actionbar}
       */
      showAll: function showAll() {
        if (this.is('rendered')) {
          this.controls.$all.removeClass('hidden');
        }
        return this;
      },
      /**
       * Hides all the buttons
       * @returns {actionbar}
       */
      hideAll: function hideAll() {
        if (this.is('rendered')) {
          this.controls.$all.addClass('hidden');
        }
        return this;
      },
      /**
       * Toggles all the buttons according to a condition
       * @param {Boolean} condition - If the condition is `true` the buttons will be displayed
       * @returns {actionbar}
       */
      toggleAll: function toggleAll(condition) {
        if (this.is('rendered')) {
          if (typeof condition !== 'undefined') {
            condition = !condition;
          }
          this.controls.$all.toggleClass('hidden', condition);
        }
        return this;
      }
    };

    /**
     * Builds an instance of the actionbar component
     * @param {Object} config
     * @param {Array} config.buttons - The list of buttons to display.
     * @param {String} config.buttons.id - The id of the button
     * @param {String} config.buttons.label - The text displayed in the button
     * @param {String} config.buttons.icon - An optional icon displayed in the button
     * @param {String} config.buttons.title - An optional tooltip displayed on the button
     * @param {Boolean} config.buttons.conditional - The button is hidden by default and must be displayed later
     * @param {Function} config.buttons.action - An action called when the button is clicked
     * @param {Boolean} [config.vertical] - Displays the action bar vertically
     * @returns {actionbar}
     *
     * @event init - Emitted when the component is initialized
     * @event destroy - Emitted when the component is destroying
     * @event render - Emitted when the component is rendered
     * @event button - Emitted when a button is clicked
     * @event show - Emitted when the component is shown
     * @event hide - Emitted when the component is hidden
     * @event enable - Emitted when the component is enabled
     * @event disable - Emitted when the component is disabled
     * @event template - Emitted when the template is changed
     */
    function actionbarFactory(config) {
      return component(actionbar).setTemplate(mainTpl)

      // uninstalls the component
      .on('destroy', function () {
        this.buttons = null;
        this.controls = null;
      })

      // renders the component
      .on('render', function () {
        var self = this;
        var $component = this.getElement();

        // vertical or horizontal ?
        this.setState('horizontal', $component.hasClass('horizontal-action-bar'));
        this.setState('vertical', $component.hasClass('vertical-action-bar'));

        // get access to all needed placeholders
        this.buttons = {};
        this.controls = {
          $buttons: {},
          $conditional: $component.find('button.conditional'),
          $all: $component.find('button')
        };
        _.forEach(this.config.buttons, function (button) {
          self.buttons[button.id] = button;
          self.controls.$buttons[button.id] = $component.find('[data-control="' + button.id + '"]');
        });

        // click on a button
        this.$component.on('click', 'button', function (e) {
          var $this = $$1(this);
          var buttonId = $this.closest('button').data('control');
          var button = self.getButton(buttonId);
          e.preventDefault();
          if (button && button.action) {
            button.action.call(self, buttonId, button);
          }

          /**
           * @event actionbar#button
           * @param {String} buttonId
           * @param {Object} button
           */
          self.trigger('button', buttonId, button);
        });
      }).init(config);
    }

    return actionbarFactory;

});
