define(['lodash', 'ui/component', 'handlebars', 'lib/handlebars/helpers', 'css!ui/breadcrumbs/css/breadcrumbs.css'], function (_, component, Handlebars, Helpers0, breadcrumbs_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, functionType="function", escapeExpression=this.escapeExpression, self=this;

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

    function program3(depth0,data) {
      
      var buffer = "", stack1, helper;
      buffer += "\n    <li class=\"breadcrumb\" data-breadcrumb=\"";
      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)
        + "\">\n        ";
      stack1 = helpers['if'].call(depth0, (depth0 && depth0.url), {hash:{},inverse:self.program(7, program7, data),fn:self.program(4, program4, data),data:data});
      if(stack1 || stack1 === 0) { buffer += stack1; }
      buffer += "\n        ";
      stack1 = helpers['if'].call(depth0, (depth0 && depth0.entries), {hash:{},inverse:self.noop,fn:self.program(9, program9, data),data:data});
      if(stack1 || stack1 === 0) { buffer += stack1; }
      buffer += "\n    </li>\n    ";
      return buffer;
      }
    function program4(depth0,data) {
      
      var buffer = "", stack1, helper;
      buffer += "\n        <a href=\"";
      if (helper = helpers.url) { stack1 = helper.call(depth0, {hash:{},data:data}); }
      else { helper = (depth0 && depth0.url); stack1 = typeof helper === functionType ? helper.call(depth0, {hash:{},data:data}) : helper; }
      buffer += escapeExpression(stack1)
        + "\">";
      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);
      stack1 = helpers['if'].call(depth0, (depth0 && depth0.data), {hash:{},inverse:self.noop,fn:self.program(5, program5, data),data:data});
      if(stack1 || stack1 === 0) { buffer += stack1; }
      buffer += "</a>\n        ";
      return buffer;
      }
    function program5(depth0,data) {
      
      var buffer = "", stack1, helper;
      buffer += " - ";
      if (helper = helpers.data) { stack1 = helper.call(depth0, {hash:{},data:data}); }
      else { helper = (depth0 && depth0.data); stack1 = typeof helper === functionType ? helper.call(depth0, {hash:{},data:data}) : helper; }
      buffer += escapeExpression(stack1);
      return buffer;
      }

    function program7(depth0,data) {
      
      var buffer = "", stack1, helper;
      buffer += "\n        <span class=\"a\">";
      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);
      stack1 = helpers['if'].call(depth0, (depth0 && depth0.data), {hash:{},inverse:self.noop,fn:self.program(5, program5, data),data:data});
      if(stack1 || stack1 === 0) { buffer += stack1; }
      buffer += "</span>\n        ";
      return buffer;
      }

    function program9(depth0,data) {
      
      var buffer = "", stack1;
      buffer += "\n        <ul class=\"entries plain\">\n            ";
      stack1 = helpers.each.call(depth0, (depth0 && depth0.entries), {hash:{},inverse:self.noop,fn:self.program(10, program10, data),data:data});
      if(stack1 || stack1 === 0) { buffer += stack1; }
      buffer += "\n        </ul>\n        ";
      return buffer;
      }
    function program10(depth0,data) {
      
      var buffer = "", stack1, helper;
      buffer += "\n            <li data-breadcrumb=\"";
      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)
        + "\">\n                <a href=\"";
      if (helper = helpers.url) { stack1 = helper.call(depth0, {hash:{},data:data}); }
      else { helper = (depth0 && depth0.url); stack1 = typeof helper === functionType ? helper.call(depth0, {hash:{},data:data}) : helper; }
      buffer += escapeExpression(stack1)
        + "\">";
      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);
      stack1 = helpers['if'].call(depth0, (depth0 && depth0.data), {hash:{},inverse:self.noop,fn:self.program(5, program5, data),data:data});
      if(stack1 || stack1 === 0) { buffer += stack1; }
      buffer += "</a>\n            </li>\n            ";
      return buffer;
      }

      buffer += "<ul class=\"breadcrumbs plain";
      stack1 = helpers['if'].call(depth0, (depth0 && depth0.cls), {hash:{},inverse:self.noop,fn:self.program(1, program1, data),data:data});
      if(stack1 || stack1 === 0) { buffer += stack1; }
      buffer += "\">\n    ";
      stack1 = helpers.each.call(depth0, (depth0 && depth0.breadcrumbs), {hash:{},inverse:self.noop,fn:self.program(3, program3, data),data:data});
      if(stack1 || stack1 === 0) { buffer += stack1; }
      buffer += "\n</ul>\n";
      return buffer;
      });
    function breadcrumbsTpl(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) 2015 (original work) Open Assessment Technologies SA ;
     */

    /**
     * Defines a breadcrumbs component
     * @type {Object}
     */
    let breadcrumbs = {
      /**
       * Updates the component with a new set of entries
       * @param {Array} newBreadcrumbs
       * @param {String} [newBreadcrumbs.id] - The identifier of the breadcrumb
       * @param {String} [newBreadcrumbs.url] - The URL targeted by the breadcrumb
       * @param {String} [newBreadcrumbs.label] - The displayed label
       * @param {String} [newBreadcrumbs.data] - An extra label to display, usually related to the current context
       * @param {Array} [newBreadcrumbs.entries] - A list of parallels links
       * @param {Array} [newBreadcrumbs.cls] - CSS class to add to the container
       * @returns {jQuery}
       */
      update: function update(newBreadcrumbs) {
        var $oldComponent = this.getContainer();
        var $component;
        this.config.breadcrumbs = newBreadcrumbs;

        /**
         * Notifies the update
         * @event breadcrumbs#update
         * @param {breadcrumbs} newBreadcrumbs
         */
        this.trigger('update', newBreadcrumbs, this);
        $component = this.render();
        if ($oldComponent) {
          if (!this.config.renderTo) {
            $oldComponent.replaceWith($component);
          } else if (!this.config.replace) {
            $oldComponent.remove();
          }
        }
        return $component;
      }
    };

    /**
     * Remove the link from the last crumb
     */
    var removeLastLink = function removeLastLink() {
      let newBreadcrumbs = this.config.breadcrumbs;
      if (newBreadcrumbs && newBreadcrumbs.length) {
        newBreadcrumbs = _.cloneDeep(this.config.breadcrumbs);
        newBreadcrumbs[newBreadcrumbs.length - 1].url = null;
        this.config.breadcrumbs = newBreadcrumbs;
      }
    };

    /**
     * Builds an instance of the breadcrumbs component
     * @param {Object} config
     * @param {Array} [config.breadcrumbs] - The list of entries to display
     * @param {jQuery|HTMLElement|String} [config.renderTo] - An optional container in which renders the component
     * @param {Boolean} [config.replace] - When the component is appended to its container, clears the place before
     * @returns {breadcrumbs}
     */
    var breadcrumbsFactory = function breadcrumbsFactory(config) {
      return component(breadcrumbs).on('init', removeLastLink).on('update', removeLastLink).setTemplate(breadcrumbsTpl).init(config);
    };

    return breadcrumbsFactory;

});
