define(['jquery', 'nouislider', 'ui/resourcemgr', 'ui/tooltip', 'lodash', 'i18n', 'core/mimetype', 'ui/mediaEditor/plugins/mediaAlignment/helper', 'ui/mediaEditor/mediaEditorComponent', 'handlebars', 'lib/handlebars/helpers'], function ($$1, nouislider, resourcemgr, tooltip, _, __, mimeType, alignmentHelper, mediaEditorComponent, Handlebars, Helpers0) { 'use strict';

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

    /*
     * 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) 2022 (original work) Open Assessment Technologies SA (under the project TAO-PRODUCT);
     */
    function getImage(widget) {
      let $img = widget.$original;
      let img = widget.element;
      if (widget.element.is('figure')) {
        $img = widget.$original.find('img');
        img = _.find(widget.element.getBody().elements, elem => elem.is('img'));
      }
      return {
        $img,
        img
      };
    }

    /*
     * 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) 2021 (original work) Open Assessment Technologies SA (under the project TAO-PRODUCT);
     */
    const mediaSizer = function mediaSizer(media, widget) {
      const {
        img,
        $img
      } = getImage(widget);
      const $mediaSpan = widget.$container;
      if (img.data('responsive') !== media.responsive) {
        // switch between responsive and absolute values
        img.data('responsive', media.responsive);
        // clean styles from prev mode
        $img.removeAttr('width');
        $img.removeAttr('height');
        $mediaSpan[0].removeAttribute('style');
      }
      _(['width', 'height']).forEach(function (sizeAttr) {
        let val;
        if (media[sizeAttr] === '' || typeof media[sizeAttr] === 'undefined' || media[sizeAttr] === null) {
          img.removeAttr(sizeAttr);
          $img.removeAttr(sizeAttr);
          $mediaSpan.css(sizeAttr, '');
        } else {
          val = Math.round(media[sizeAttr]);
          if (media.responsive) {
            val += '%';
            img.attr(sizeAttr, val);
            $img.attr(sizeAttr, '100%');
          } else {
            img.attr(sizeAttr, val);
            $img.attr(sizeAttr, val);
          }
          if (media.responsive || sizeAttr === 'width') {
            $mediaSpan.css(sizeAttr, val);
          }
        }
        //trigger choice container size adaptation
        widget.$container.trigger('contentChange.qti-widget');
      });
    };

    /*
     * 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) 2021 (original work) Open Assessment Technologies SA (under the project TAO-PRODUCT);
     */
    const getMedia = (imgQtiElement, $imgNode, cb) => {
      //init data-responsive:
      if (typeof imgQtiElement.data('responsive') === 'undefined') {
        if (imgQtiElement.attr('width') && !/[0-9]+%/.test(imgQtiElement.attr('width'))) {
          imgQtiElement.data('responsive', false);
        } else {
          imgQtiElement.data('responsive', true);
        }
      }
      if (typeof imgQtiElement.attr('original-width') !== 'undefined' && typeof imgQtiElement.attr('original-height') !== 'undefined' && typeof imgQtiElement.attr('type') !== 'undefined' && typeof imgQtiElement.attr('src') !== 'undefined' && typeof imgQtiElement.attr('width') !== 'undefined' && typeof imgQtiElement.attr('height') !== 'undefined') {
        cb({
          $node: $imgNode,
          type: imgQtiElement.attr('type'),
          src: imgQtiElement.attr('src'),
          width: imgQtiElement.attr('width'),
          height: imgQtiElement.attr('height'),
          responsive: imgQtiElement.data('responsive')
        });
      } else {
        mimeType.getResourceType($imgNode.attr('src'), function (err, type) {
          imgQtiElement.attr('type', type);
          cb({
            $node: $imgNode,
            type: imgQtiElement.attr('type'),
            src: imgQtiElement.attr('src'),
            width: imgQtiElement.attr('width'),
            height: imgQtiElement.attr('height'),
            responsive: imgQtiElement.data('responsive')
          });
        });
      }
    };
    const getMediaCb = (media, widget, mediaEditor, options) => {
      const $mediaResizer = widget.$form.find('.img-resizer');
      media.$container = widget.$container.parents('.widget-box');
      if (media.$container.length) {
        // eslint-disable-next-line no-unused-vars
        mediaEditor = mediaEditorComponent($mediaResizer, media, options).on('change', function (nMedia) {
          media = nMedia;
          widget.$original.prop('style', null); // not allowed by qti
          widget.$original.removeAttr('style');
          alignmentHelper.positionFloat(widget, media.align);
          mediaSizer(media, widget);
          widget.$original.removeClass('hidden');
        });
      }
    };
    function initMediaEditor(widget, mediaEditor, options) {
      if (mediaEditor) {
        mediaEditor.destroy();
      }
      if (!widget.$form.find('input[name=src]').val()) {
        return;
      }
      const {
        img,
        $img
      } = getImage(widget);
      getMedia(img, $img, m => getMediaCb(m, widget, mediaEditor, options));
    }

    /*
     * 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) 2021 (original work) Open Assessment Technologies SA (under the project TAO-PRODUCT);
     */
    /**
     * Extract a default label from a file/path name
     * @param {String} fileName - the file/path
     * @returns {String} a label
     */
    function extractLabel(fileName) {
      return fileName.replace(/\.[^.]+$/, '').replace(/^(.*)\//, '').replace(/\W/, ' ').substr(0, 255);
    }

    /*
     * 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) 2021 (original work) Open Assessment Technologies SA ;
     *
     */
    const initAdvanced = function (widget) {
      const $form = widget.$form;
      const {
        img
      } = getImage(widget);
      let src = img ? img.attr('src') : '';
      if (src) {
        $form.find('[data-role=advanced]').show();
      } else {
        $form.find('[data-role=advanced]').hide();
      }
    };
    const initUpload = function (widget) {
      const $form = widget.$form;
      const options = widget.options;
      const {
        img
      } = getImage(widget);
      const $uploadTrigger = $form.find('[data-role="upload-trigger"]');
      const $src = $form.find('input[name=src]');
      const $alt = $form.find('input[name=alt]');
      const _openResourceMgr = function () {
        $uploadTrigger.resourcemgr({
          title: __('Please select an image file from the resource manager. You can add files from your computer with the button "Add file(s)".'),
          appendContainer: options.mediaManager.appendContainer,
          mediaSourcesUrl: options.mediaManager.mediaSourcesUrl,
          browseUrl: options.mediaManager.browseUrl,
          uploadUrl: options.mediaManager.uploadUrl,
          deleteUrl: options.mediaManager.deleteUrl,
          downloadUrl: options.mediaManager.downloadUrl,
          fileExistsUrl: options.mediaManager.fileExistsUrl,
          params: {
            uri: options.uri,
            lang: options.lang,
            filters: [{
              mime: 'image/jpeg'
            }, {
              mime: 'image/png'
            }, {
              mime: 'image/gif'
            }, {
              mime: 'image/svg+xml'
            }, {
              mime: 'application/x-gzip',
              extension: 'svgz'
            }]
          },
          pathParam: 'path',
          path: options.mediaManager.path,
          root: options.mediaManager.root,
          select: function (e, files) {
            let file, alt;
            let confirmBox, cancel, save;
            if (files && files.length) {
              file = files[0].file;
              alt = files[0].alt;
              $src.val(file);
              if ($$1.trim($alt.val()) === '') {
                if (alt === '') {
                  alt = extractLabel(file);
                }
                img.attr('alt', alt);
                $alt.val(alt).trigger('change');
              } else {
                confirmBox = $$1('.change-alt-modal-feedback', $form);
                cancel = confirmBox.find('.cancel');
                save = confirmBox.find('.save');
                $$1('.alt-text', confirmBox).html(`"${$alt.val()}"<br>${__('with')}<br>"${alt}" ?`);
                confirmBox.modal({
                  width: 500
                });
                save.off('click').on('click', function () {
                  img.attr('alt', alt);
                  $alt.val(alt).trigger('change');
                  confirmBox.modal('close');
                });
                cancel.off('click').on('click', function () {
                  confirmBox.modal('close');
                });
              }
              _.defer(function () {
                img.attr('off-media-editor', 1);
                $src.trigger('change');
              });
            }
          },
          open: function () {
            // hide tooltip if displayed
            if ($src.data('$tooltip')) {
              $src.blur().data('$tooltip').hide();
            }
          },
          close: function () {
            // triggers validation:
            $src.blur();
          }
        });
      };
      $uploadTrigger.on('click', _openResourceMgr);

      //if empty, open file manager immediately
      if (!$src.val()) {
        _openResourceMgr();
      }
    };
    function initAll(widget, mediaEditor, options) {
      initAdvanced(widget);
      initMediaEditor(widget, mediaEditor, options);
      initUpload(widget);
    }

    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 stack1, helper, options, helperMissing=helpers.helperMissing;


      stack1 = (helper = helpers.dompurify || (depth0 && depth0.dompurify),options={hash:{},data:data},helper ? helper.call(depth0, (depth0 && depth0.text), options) : helperMissing.call(depth0, "dompurify", (depth0 && depth0.text), options));
      if(stack1 || stack1 === 0) { return stack1; }
      else { return ''; }
      });
    function tplCaptionText(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) 2022 (original work) Open Assessment Technologies SA (under the project TAO-PRODUCT);
     */
    const options = {
      mediaDimension: {
        active: true
      },
      mediaAlignment: {
        active: true
      }
    };
    const getImage$1 = widget => widget.$original.find('img');
    const getCaption = widget => widget.$original.find('figcaption');
    const getImageElement = widget => _.find(widget.element.getBody().elements, elem => elem.is('img'));
    const getCaptionElement = widget => _.find(widget.element.getBody().elements, elem => elem.is('figcaption'));
    const formCallbacks = _ref => {
      let {
        widget,
        formElement,
        mediaEditor,
        togglePlaceholder
      } = _ref;
      const $img = getImage$1(widget);
      let $figcaption = getCaption(widget);
      const imageElem = getImageElement(widget);
      let figcaptionElem = getCaptionElement(widget);
      return {
        src: _.throttle(function (elem, value) {
          imageElem.attr('src', value);
          $img.attr('src', widget.getAssetManager().resolve(value));
          $img.trigger('contentChange.qti-widget').change();
          togglePlaceholder(widget);
          imageElem.removeAttr('off-media-editor');
          if (widget.$form.find('[data-role=advanced]').is(':hidden')) {
            const initPanel = () => {
              initAdvanced(widget);
              initMediaEditor(widget, mediaEditor, options);
            };
            if ($img[0].complete) {
              initPanel();
            } else {
              $img.on('load.widget-panel', function () {
                initPanel();
                $img.off('.widget-panel');
              });
            }
          }
        }, 1000),
        alt: function (elem, value) {
          imageElem.attr('alt', value);
        },
        figcaption: function (elem, value) {
          // using dompurify to clean <script> tags
          const text = tplCaptionText({
            text: value
          });
          if (figcaptionElem && value) {
            // update existing capture
            $figcaption.html(text);
            figcaptionElem.body(text);
          } else if (!figcaptionElem && value) {
            // add capture
            figcaptionElem = widget.element.addCaption(text);
            $figcaption = $$1(`<figcaption>${text}</figcaption>`);
            widget.$original.append($figcaption);
          } else if (figcaptionElem && !value) {
            widget.element.removeCaption();
            $figcaption.remove();
            $figcaption = null;
            figcaptionElem = null;
          }
        },
        longdesc: formElement.getAttributeChangeCallback()
      };
    };
    const initForm = _ref2 => {
      let {
        widget,
        formElement,
        formTpl,
        mediaEditor,
        togglePlaceholder
      } = _ref2;
      const imageElem = getImageElement(widget);
      const figcaptionElem = getCaptionElement(widget);
      const showFigure = widget.element.attr('showFigure');
      widget.$form.html(formTpl({
        baseUrl: widget.options.baseUrl || '',
        src: imageElem.attr('src'),
        alt: imageElem.attr('alt'),
        figcaption: figcaptionElem ? figcaptionElem.body() : '',
        showFigure: showFigure
      }));
      widget.$form.find('textarea#figcaption').on('focus.qti-widget', () => widget.$container.addClass('edit-figcaption')).on('blur.qti-widget', () => widget.$container.removeClass('edit-figcaption'));

      // init upload, advanced and media editor
      initAll(widget, mediaEditor, options);

      // init standard ui widget
      formElement.initWidget(widget.$form);

      // init data change callbacks
      formElement.setChangeCallbacks(widget.$form, widget.element, formCallbacks({
        widget,
        formElement,
        mediaEditor,
        togglePlaceholder
      }));
    };

    /**
     * @param {Object} stateFactory
     * @param {Object} ActiveState
     * @param {Object} formTpl
     * @param {Object} formElement
     * @param {Object} inlineHelper
     * @returns
     */
    function FigureStateActive (_ref3) {
      let {
        stateFactory,
        ActiveState,
        formTpl,
        formElement,
        inlineHelper
      } = _ref3;
      /**
       * media Editor instance if has been initialized
       * @type {null}
       */
      let mediaEditor = null;
      let textareaObserver = null;
      let texareaHTMLElem = null;
      const FigureStateActive = stateFactory.extend(ActiveState, function () {
        this.initForm();
      }, function () {
        this.widget.$form.find('textarea#figcaption').off('.qti-widget');
        if (textareaObserver) {
          textareaObserver.unobserve(texareaHTMLElem);
        }
        this.widget.$form.empty();
      });
      FigureStateActive.prototype.initForm = function () {
        initForm({
          widget: this.widget,
          formElement,
          formTpl,
          mediaEditor,
          togglePlaceholder: inlineHelper.togglePlaceholder
        });
        const figurelem = this.widget.element;
        const $texarea = this.widget.$form.find('textarea#figcaption');
        texareaHTMLElem = $texarea[0];
        texareaHTMLElem.style.minHeight = '2em';
        function outputsize() {
          figurelem.data('heigthCaptionInput', $texarea.height());
        }
        if (typeof ResizeObserver !== 'undefined') {
          textareaObserver = new ResizeObserver(outputsize).observe(texareaHTMLElem);
          if (figurelem.data('heigthCaptionInput')) {
            $texarea.height(figurelem.data('heigthCaptionInput'));
          }
        }
      };
      return FigureStateActive;
    }

    return FigureStateActive;

});
