define(['jquery', 'lodash', 'ui/component', 'ui/mediaEditor/plugins/mediaDimension/mediaDimensionComponent', 'ui/mediaEditor/plugins/mediaAlignment/mediaAlignmentComponent', 'handlebars', 'lib/handlebars/helpers'], function ($$1, _, component, mediaDimensionComponent, mediaAlignmentComponent, 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;
    mediaDimensionComponent = mediaDimensionComponent && Object.prototype.hasOwnProperty.call(mediaDimensionComponent, 'default') ? mediaDimensionComponent['default'] : mediaDimensionComponent;
    mediaAlignmentComponent = mediaAlignmentComponent && Object.prototype.hasOwnProperty.call(mediaAlignmentComponent, 'default') ? mediaAlignmentComponent['default'] : mediaAlignmentComponent;
    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, self=this;

    function program1(depth0,data) {
      
      
      return "<div class=\"media-dimension\"></div>";
      }

    function program3(depth0,data) {
      
      
      return "<div class=\"media-align\"></div>";
      }

      buffer += "<div class=\"media-editor\">\n    ";
      stack1 = helpers['if'].call(depth0, ((stack1 = (depth0 && depth0.mediaDimension)),stack1 == null || stack1 === false ? stack1 : stack1.active), {hash:{},inverse:self.noop,fn:self.program(1, program1, data),data:data});
      if(stack1 || stack1 === 0) { buffer += stack1; }
      buffer += "\n    ";
      stack1 = helpers['if'].call(depth0, ((stack1 = (depth0 && depth0.mediaAlignment)),stack1 == null || stack1 === false ? stack1 : stack1.active), {hash:{},inverse:self.noop,fn:self.program(3, program3, data),data:data});
      if(stack1 || stack1 === 0) { buffer += stack1; }
      buffer += "\n</div>\n";
      return buffer;
      });
    function tpl(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) 2021 (original work) Open Assessment Technologies SA;
     *
     * @author Oleksander Zagovorychev <zagovorichev@gmail.com>
     */

    /**
     * @typedef {Object} mediaObject
     * @property $node
     * @property $container
     * @property type
     * @property src
     * @property width
     * @property height
     */

    /**
     * @typedef {Object} mediaEditorConfig
     * @property mediaDimension {{active: boolean}}
     * @property mediaAlignment {{active: boolean}}
     */

    /**
     * target - jQuery element with media $()
     * container - container to which an target is attached
     *
     * @type mediaEditorConfig
     * @private
     */
    const defaultConfig = {
      mediaDimension: {
        active: false
      },
      mediaAlignment: {
        active: false
      }
    };

    /**
     * Creates media editor
     *
     * @param {Object} $container - jQuery pointer
     * @param {mediaObject} media
     * @param {mediaEditorConfig} config
     * @returns {component|*}
     */
    function mediaEditorFactory($container, media, config) {
      /**
       * Active Plugins
       * @type {Array}
       */
      const plugins = [];

      /**
       * Current component
       */
      const mediaEditorComponent = component({}, defaultConfig);
      mediaEditorComponent.setTemplate(tpl).on('init', function () {
        if (!media || !media.$node || !media.$node.length) {
          throw new Error('mediaEditorComponent requires media.$node');
        }
        if (!media || !media.$container || !media.$container.length) {
          throw new Error('mediaEditorComponent requires media.$container');
        }
        this.render($container);
      }).on('render', function () {
        const $dimensionTools = $$1('.media-dimension', this.getTemplate());
        const $alignmentTools = $$1('.media-align', this.getTemplate());
        let dimensionPlugin;
        let alignmentPlugin;
        if (this.getConfig().mediaDimension.active) {
          dimensionPlugin = mediaDimensionComponent($dimensionTools, media, {
            responsive: media.responsive,
            showResponsiveToggle: this.getConfig().mediaDimension.showResponsiveToggle
          }).on('change', conf => {
            media.responsive = conf.responsive;
            if (conf.responsive) {
              // percent
              media.width = conf.sizeProps['%'].current.width;
              media.height = null;
            } else {
              media.width = conf.sizeProps.px.current.width;
              media.height = conf.sizeProps.px.current.height;
            }
            this.trigger('change', media);
          });
          plugins.push(dimensionPlugin);
        }
        if (this.getConfig().mediaAlignment.active) {
          alignmentPlugin = mediaAlignmentComponent($alignmentTools, media).spread(this, 'change');
          plugins.push(alignmentPlugin);
        }
      }).on('destroy', function () {
        _.forEach(plugins, function (plugin) {
          plugin.destroy();
        });
      });
      _.defer(function () {
        mediaEditorComponent.init(config);
      });
      return mediaEditorComponent;
    }

    return mediaEditorFactory;

});
