define(['i18n', 'jquery', 'taoTests/runner/plugin', 'taoQtiTest/runner/helpers/isReviewPanelEnabled', 'taoQtiTest/runner/plugins/content/accessibility/jumplinks/helpers', 'taoQtiTest/runner/plugins/content/accessibility/jumplinks/jumplinks', 'taoQtiTest/runner/plugins/content/accessibility/jumplinks/shortcuts', 'util/shortcut', 'util/namespace', 'handlebars', 'lib/handlebars/helpers'], function (__, $$1, pluginFactory, isReviewPanelEnabled, helpers, jumplinksFactory, shortcutsFactory, shortcut, namespaceHelper, Handlebars, Helpers0) { 'use strict';

    __ = __ && Object.prototype.hasOwnProperty.call(__, 'default') ? __['default'] : __;
    $$1 = $$1 && Object.prototype.hasOwnProperty.call($$1, 'default') ? $$1['default'] : $$1;
    pluginFactory = pluginFactory && Object.prototype.hasOwnProperty.call(pluginFactory, 'default') ? pluginFactory['default'] : pluginFactory;
    isReviewPanelEnabled = isReviewPanelEnabled && Object.prototype.hasOwnProperty.call(isReviewPanelEnabled, 'default') ? isReviewPanelEnabled['default'] : isReviewPanelEnabled;
    jumplinksFactory = jumplinksFactory && Object.prototype.hasOwnProperty.call(jumplinksFactory, 'default') ? jumplinksFactory['default'] : jumplinksFactory;
    shortcutsFactory = shortcutsFactory && Object.prototype.hasOwnProperty.call(shortcutsFactory, 'default') ? shortcutsFactory['default'] : shortcutsFactory;
    shortcut = shortcut && Object.prototype.hasOwnProperty.call(shortcut, 'default') ? shortcut['default'] : shortcut;
    namespaceHelper = namespaceHelper && Object.prototype.hasOwnProperty.call(namespaceHelper, 'default') ? namespaceHelper['default'] : namespaceHelper;
    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);  


      return "<div class=\"jump-links-container\"></div>\n";
      });
    function containerTpl(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) 2020 (original work) Open Assessment Technologies SA ;
     */

    /**
     * Creates the JumpLinks plugin.
     * adding jumplinks accessibility feature for quick navigation
     */
    var plugin = pluginFactory({
      name: 'jumplinks',
      /**
       * Initializes the plugin (called during runner's init)
       */
      init() {
        const testRunner = this.getTestRunner();
        const item = testRunner.getCurrentItem();
        const config = {
          isReviewPanelEnabled: isReviewPanelEnabled(testRunner),
          questionStatus: helpers.getItemStatus(item)
        };
        const testRunnerOptions = testRunner.getOptions();
        const pluginShortcuts = (testRunnerOptions.shortcuts || {})[this.getName()] || {};
        const areaBroker = this.getAreaBroker();
        const getJumpElement = helpers.getJumpElementFactory(areaBroker);
        const shortcutsConfig = navigator.appVersion.indexOf("Mac") !== -1 ? {
          shortcutsGroups: [{
            id: 'navigation-shortcuts',
            label: __('Navigation shortcuts'),
            shortcuts: [{
              id: 'next',
              shortcut: 'OPTION + Shift + N',
              label: __('Go to the next question')
            }, {
              id: 'previous',
              shortcut: 'OPTION + Shift + P',
              label: __('Go to the previous question')
            }, {
              id: 'current',
              shortcut: 'OPTION + Shift + Q',
              label: __('Go to the current question')
            }, {
              id: 'top',
              shortcut: 'OPTION + Shift + T',
              label: __('Go to the top of the page')
            }]
          }]
        } : {};
        if (testRunnerOptions.allowShortcuts) {
          pluginShortcuts.goToTop && shortcut.add(namespaceHelper.namespaceAll(pluginShortcuts.goToTop, this.getName(), true), function () {
            $$1('[tabindex]').first().focus();
          }, {
            avoidInput: true,
            prevent: true
          });
          pluginShortcuts.goToQuestion && shortcut.add(namespaceHelper.namespaceAll(pluginShortcuts.goToQuestion, this.getName(), true), function () {
            getJumpElement.question.focus();
          }, {
            avoidInput: true,
            prevent: true
          });
        }
        this.jumplinks = jumplinksFactory(config).on('render', () => {
          this.jumplinks.on('jump', jumpTo => {
            const $element = getJumpElement[jumpTo];
            $element.focus();
          });
          this.jumplinks.on('shortcuts', () => {
            if (this.shortcuts) {
              return;
            }
            this.shortcuts = shortcutsFactory(shortcutsConfig);
            this.shortcuts.render(this.getAreaBroker().getControlArea());
            this.shortcuts.on('close', () => {
              this.shortcuts.destroy();
              this.shortcuts = null;
            });
          });
        }).on('update', function update(params) {
          this.trigger('changeReviewPanel', params.isReviewPanelEnabled);
          this.trigger('changeQuesitionStatus', params.questionStatus);
        }).on('changeReviewPanel', function changeReviewPanel(enabled) {
          const elem = this.getElement();
          const panelJumplink = elem.find('[data-jump="teststatus"]').parent();
          if (enabled) {
            panelJumplink.removeClass('hidden');
          } else {
            panelJumplink.addClass('hidden');
          }
        }).on('changeQuesitionStatus', function changeQuesitionStatus(questionStatus) {
          const elem = this.getElement();
          const text = `${__('Question')} - ${questionStatus}`;
          elem.find('[data-jump="question"] > b').text(text);
        });
        testRunner.on('renderitem', () => {
          const currentItem = testRunner.getCurrentItem();
          const updatedConfig = {
            isReviewPanelEnabled: !helpers.isReviewPanelHidden(testRunner) && isReviewPanelEnabled(testRunner),
            questionStatus: helpers.getItemStatus(currentItem)
          };
          const announcedText = __('Item %s loaded', currentItem.position);
          let $announce = $$1('[aria-live=polite][role=alert]').first();
          if ($announce.length !== 1) {
            $announce = $$1('<div aria-live="polite" role="alert" class="visible-hidden"></div>');
            $$1('main').first().append($announce);
          }
          $announce.text(announcedText);
          this.jumplinks.trigger('update', updatedConfig);
        }).on('tool-flagitem', () => {
          const currentItem = testRunner.getCurrentItem();
          const questionStatus = helpers.getItemStatus(Object.assign({}, currentItem, {
            flagged: !currentItem.flagged
          }));
          this.jumplinks.trigger('changeQuesitionStatus', questionStatus);
        }).on('tool-reviewpanel', () => {
          const wasHidden = helpers.isReviewPanelHidden(testRunner);
          this.jumplinks.trigger('changeReviewPanel', wasHidden);
        }).after('renderitem', () => {
          getJumpElement.question.attr('tabindex', '-1').focus();
        });
      },
      /**
       * Called during the runner's render phase
       */
      render: function render() {
        const jumplinksContainer = $$1(containerTpl());
        $$1('.content-wrap').prepend(jumplinksContainer);
        this.jumplinks.render(jumplinksContainer);
      }
    });

    return plugin;

});
