define(['lodash', 'ui/component', 'handlebars', 'lib/handlebars/helpers', 'css!ui/loadingButton/css/button.css'], function (_, component, Handlebars, Helpers0, button_css) { 'use strict';

    _ = _ && 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, helper, functionType="function", escapeExpression=this.escapeExpression;


      buffer += "<button class=\"loading-button btn-";
      if (helper = helpers.type) { stack1 = helper.call(depth0, {hash:{},data:data}); }
      else { helper = (depth0 && depth0.type); stack1 = typeof helper === functionType ? helper.call(depth0, {hash:{},data:data}) : helper; }
      buffer += escapeExpression(stack1)
        + " small\" type=\"button\" 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)
        + "\">\n    <span class=\"spinner-icon icon-loop spinning\"></span>\n    <span class=\"start-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>\n    <span class=\"action-label\">";
      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)
        + "</span>\n    <span class=\"terminated-label\">";
      if (helper = helpers.terminatedLabel) { stack1 = helper.call(depth0, {hash:{},data:data}); }
      else { helper = (depth0 && depth0.terminatedLabel); stack1 = typeof helper === functionType ? helper.call(depth0, {hash:{},data:data}) : helper; }
      buffer += escapeExpression(stack1)
        + "</span>\n</button>";
      return buffer;
      });
    function buttonTpl(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) 2017 (original work) Open Assessment Technologies SA ;
     */
    var _defaults = {
      type: 'info',
      icon: 'property-advanced',
      title: '',
      label: 'OK',
      terminatedLabel: 'FINISHED'
    };
    var buttonApi = {
      start: function start() {
        this.setState('started', true);
        this.trigger('started');
      },
      terminate: function terminate() {
        if (this.is('started')) {
          this.setState('started', false);
          this.setState('terminated', true);
          this.disable();
          this.trigger('terminated');
        }
        return this;
      },
      reset: function reset() {
        if (this.is('terminated')) {
          this.setState('terminated', false);
          this.enable();
          this.trigger('reset');
        }
        return this;
      }
    };

    /**
     * Create a button with the lifecycle : render -> started -> terminated [-> reset]
     * @param {Object} config - the component config
     * @param {String} config.type - the icon type (info, success, error)
     * @param {String} config.icon - the button icon
     * @param {String} config.label - the button's label
     * @param {String} [config.title] - the button's title
     * @param {String} [config.terminatedLabel] - the button's label when terminated
     * @return {loadingButton} the component
     *
     * @event started - Emitted when the button is clicked and the triggered action supposed to be started
     * @event terminated - Emitted when the button action is stopped, interrupted
     * @event reset - Emitted when the button revert from the terminated stated to the initial one
     */
    function loadingButtonFactory(config) {
      var initConfig = _.defaults(config || {}, _defaults);

      /**
       * @typedef {loadingButton} the component
       */
      return component(buttonApi).setTemplate(buttonTpl).on('enable', function () {
        this.getElement().removeProp('disabled');
      }).on('disable', function () {
        this.getElement().prop('disabled', true);
      }).on('render', function () {
        var self = this;
        this.getElement().on('click', function (e) {
          e.preventDefault();
          if (!self.is('disabled') && !self.is('started') && !self.is('terminated')) {
            self.start();
          }
        });
      }).init(initConfig);
    }

    return loadingButtonFactory;

});
