H5P.Collage = (function ($, EventDispatcher) {

  /**
   * Create a new collage.
   *
   * @class H5P.Collage
   * @extends H5P.EventDispatcher
   * @param {Object} parameters
   * @param {number} contentId
   */
  function Collage(parameters, contentId) {
    var self = this;

    // Initialize event inheritance
    EventDispatcher.call(self);

    // Content defaults
    setDefaults(parameters, {
      collage: {
        template: '2-1',
        options: {
          heightRatio: 0.75,
          spacing: 0.5,
          frame: true
        },
        clips: []
      }
    });
    var content = parameters.collage;
    var $wrapper;

    // Create new template for adding clips to
    var template = new Collage.Template(content.options.spacing);

    // Add clips to columns
    template.on('columnAdded', function (event) {
      var $col = event.data;
      var clipIndex = self.clips.length;

      // Set default
      if (!content.clips[clipIndex]) {
        content.clips[clipIndex] = {};
      }

      // Add new clip
      var clip = new Collage.Clip($col, content.clips[clipIndex], contentId, self);
      self.clips.push(clip);

      self.trigger('clipAdded', clip);
      clip.load();
    });

    /**
     * Creates the HTML the first time the collage is attaced.
     *
     * @private
     */
    var createHtml = function () {
      // Create collage wrapper
      var wrapperOptions = {
        'class': 'h5p-collage-wrapper',
        css: {}
      };
      if (content.options.frame) {
        wrapperOptions.css.borderWidth = content.options.spacing + 'em';
      }
      $wrapper = $('<div/>', wrapperOptions);

      // Add template
      template.appendTo($wrapper);

      // Render template
      self.setLayout(content.template);
    };

    /**
     * Attach the collage to the given container.
     *
     * @param {H5P.jQuery} $container
     */
    self.attach = function ($container) {
      this.triggerConsumed();
      if ($wrapper === undefined) {
        createHtml();
        var $parent = $container.parent();
        if (!$parent.hasClass('h5p-frame')) {
          $parent.css('backgroundColor', 'transparent');
        }
      }

      // Add to DOM
      $container.addClass('h5p-collage').html('').append($wrapper);
    };

    /**
     * Trigger the 'consumed' xAPI event when this commences
     *
     * (Will be more sophisticated in future version)
     */
    self.triggerConsumed = function () {
      var xAPIEvent = this.createXAPIEventTemplate({
        id: 'http://activitystrea.ms/schema/1.0/consume',
        display: {
          'en-US': 'consumed'
        }
      }, {
        result: {
          completion: true
        }
      });
      this.trigger(xAPIEvent);
    };

    /**
     * Set a new collage layout.
     *
     * @param {string} newLayout
     */
    self.setLayout = function (newLayout) {
      self.clips = [];
      template.setLayout(newLayout);
    };

    /**
     * Set the spacing between the collage clips.
     *
     * @param {number} newSpacing
     */
    self.setSpacing = function (newSpacing) {
      template.setSpacing(newSpacing);
    };

    /**
     * Set the frame around the collage.
     *
     * @param {number} newFrameWidth
     */
    self.setFrame = function (newFrameWidth) {
      $wrapper.css('borderWidth', newFrameWidth + 'em');
    };

    /**
     * Set the height / aspect ratio of the collage.
     *
     * @param {number} newHeight
     */
    self.setHeight = function (newHeight) {
      // Update template
      var wrapperSize = $wrapper[0].getBoundingClientRect();
      $wrapper.css('height', (wrapperSize.width * newHeight) + 'px');
    };

    /**
     * Handle resize events
     */
    self.on('resize', function () {
      if ($wrapper === undefined) {
        return;
      }

      // Get outer width without rounding
      var width = $wrapper[0].getBoundingClientRect().width;
      $wrapper.css({
        fontSize: ((width / 480) * 16) + 'px',
        height: (content.options.heightRatio * width) + 'px'
      });

      // Position clips
      for (let i = 0; i < self.clips.length; i++) {
        if (!self.clips[i].isPositioned()) {
          self.clips[i].positionImage()
        }
      }
    });
  }

  // Extends the event dispatcher
  Collage.prototype = Object.create(EventDispatcher.prototype);
  Collage.prototype.constructor = Collage;

  /**
   * Simple recusive function the helps set default values without
   * destroying object references.
   *
   * @param {object} params values
   * @param {object} values default values
   */
  var setDefaults = function (params, values) {
    for (var prop in values) {
      if (values.hasOwnProperty(prop)) {
        if (params[prop] === undefined) {
          params[prop] = values[prop];
        }
        else if (params[prop] instanceof Object && !(params[prop] instanceof Array)) {
          setDefaults(params[prop], values[prop]);
        }
      }
    }
  };

  return Collage;
})(H5P.jQuery, H5P.EventDispatcher);
;(function ($, EventDispatcher, Collage) {

  /**
   * Collage Template
   *
   * @class H5P.Collage.Template
   * @extends H5P.EventDispatcher
   * @param {number} spacing
   * @param {string} layout
   */
  Collage.Template = function (spacing, layout) {
    var self = this;

    // Initialize event inheritance
    EventDispatcher.call(self);

    // Create template wrapper
    var $wrapper;

    // Half the spacing
    spacing /= 2;

    // Keep track of our rows
    var table = [];

    /**
     * Add columns to row.
     *
     * @private
     * @param {H5P.jQuery} $row
     * @param {number} num
     */
    var addCols = function ($row, num) {
      var cols = [];

      for (var i = 0; i < num; i++) {
        // Add column to row
        var $col = $('<div/>', {
          'class': 'h5p-collage-col',
          css: {
            width: (100 / num) + '%',
            borderLeftWidth: (i === 0 ? 0 : spacing + 'em'),
            borderRightWidth: (i === num - 1 ? 0 : spacing + 'em')
          },
          appendTo: $row
        });

        self.trigger('columnAdded', $col);
        cols.push($col);
      }

      return cols;
    };

    /**
     * Add rows to wrapper.
     *
     * @private
     * @param {Array} rows
     */
    var addRows = function (rows) {
      for (var i = 0; i < rows.length; i++) {
        // Add row to wrapper
        var $row = $('<div/>', {
          'class': 'h5p-collage-row',
          css: {
            height: (100 / rows.length) + '%',
            borderTopWidth: (i === 0 ? 0 : spacing + 'em'),
            borderBottomWidth: (i === rows.length - 1 ? 0 : spacing + 'em')
          },
          appendTo: $wrapper
        });

        // Add row columns
        table.push({
          $row: $row,
          cols: addCols($row, Number(rows[i]))
        });
      }
    };

    /**
     * Append template to given container.
     *
     * @param {H5P.jQuery} $container
     */
    self.appendTo = function ($container) {
      // Create wrapper
      $wrapper = $('<div/>', {
        'class': 'h5p-collage-template'
      });

      // Initialize right away if we have a layout
      if (layout) {
        self.setLayout(layout);
      }

      // Insert our wrapper into the given container
      $wrapper.appendTo($container);
    };

    /**
     * Set a new layout for the template.
     *
     * @param {string} newLayout
     */
    self.setLayout = function (newLayout) {
      $wrapper.html('');
      addRows(newLayout.split('-'));
    };

    /**
     * Set the spacing between the clips.
     *
     * @param {number} newSpacing
     */
    self.setSpacing = function (newSpacing) {
      spacing = newSpacing / 2;

      // Update table styling
      for (var i = 0; i < table.length; i++) {
        var row = table[i];
        row.$row.css({
          borderTopWidth: (i === 0 ? 0 : spacing + 'em'),
          borderBottomWidth: (i === table.length - 1 ? 0 : spacing + 'em')
        });

        for (var j = 0; j < row.cols.length; j++) {
          row.cols[j].css({
            borderLeftWidth: (j === 0 ? 0 : spacing + 'em'),
            borderRightWidth: (j === row.cols.length - 1 ? 0 : spacing + 'em')
          });
        }
      }
    };
  };

  // Extends the event dispatcher
  Collage.Template.prototype = Object.create(EventDispatcher.prototype);
  Collage.Template.prototype.constructor = Collage.Template;

})(H5P.jQuery, H5P.EventDispatcher, H5P.Collage);
;(function ($, Collage, EventDispatcher) {

  /**
   * Collage Clip
   *
   * @class H5P.Collage.Clip
   * @extends H5P.EventDispatcher
   * @param {H5P.jQuery} $container
   * @param {Object} content
   * @param {number} contentId
   * @param {H5P.Collage} parent
   */
  Collage.Clip = function ($container, content, contentId, parent) {
    var self = this;

    // Initialize event inheritance
    EventDispatcher.call(self);

    // Photo wrapper
    self.$wrapper = $('<div/>', {
      'class': 'h5p-collage-photo',
      appendTo: $container
    });

    // Clip resource
    var $img;

    // Always available
    self.content = content;

    // Instance of H5P.Collage
    self.parent = parent;

    // Keep track of image has been positioned
    let isPositioned = false;

    /**
     * Position the clip image according to params.
     */
    self.positionImage = function () {
      if (self.$wrapper[0].offsetParent === null || isPositioned || !$img || !$img.length) {
        return; // Not visible, position will not be correct
      }

      // Determine image ratio
      const imageRatio = $img[0].width ? ($img[0].width / $img[0].height) : (content.image.width && content.image.height ? content.image.width / content.image.height : null);
      if (imageRatio === null) {
        return; // Skip
      }
      isPositioned = true;

      // Find container raioratios
      var containerSize = window.getComputedStyle(self.$wrapper[0]);
      var containerRatio = (parseFloat(containerSize.width) / parseFloat(containerSize.height));

      // Make sure image covers the whole container
      if (isNaN(containerRatio) || imageRatio > containerRatio) {
        self.prop = 'height';
      }
      else {
        self.prop = 'width';
      }
      $img.css(self.prop, (content.scale * 100) + '%');

      // Pan image
      $img.css('margin', content.offset.top + '% 0 0 ' + content.offset.left + '%');
    };
    /**
     * Decode html
     */
    self.decodeHTML = value => ($('<textarea/>').html(value).text());

    /**
     * Triggers the loading of the image.
     */
    self.load = function () {
      if (self.empty()) {
        self.$wrapper.addClass('h5p-collage-empty');

        // Workaround to trigger an event when the image set as background
        // via CSS finishes loading
        if (
          typeof self.parent?.getLibraryFilePath === 'function' &&
          self.parent?.libraryInfo
        ) {
          const img = new Image();
          img.src = self.parent.getLibraryFilePath('h5p.svg')
          img.onload = () => {
            self.trigger('loaded');
          };
        }
        return; // No image set
      }
      else {
        self.$wrapper.removeClass('h5p-collage-empty');
      }

      // Create image
      $img = $('<img/>', {
        'class': 'h5p-collage-image',
        alt: self.decodeHTML(content.alt),
        title: self.decodeHTML(content.title),
        src: H5P.getPath(content.image.path, contentId),
        prependTo: self.$wrapper,
        on: {
          load: function () {
            // Make sure it's in the correct position
            $(this).get(0).style.removeProperty('width');
            $(this).get(0).style.removeProperty('height');
            isPositioned = false;
            requestAnimationFrame(() => {
              self.positionImage();
            });

            self.trigger('loaded');
          }
        }
      });
      setTimeout(function () {
        // Wait for next tick to make sure everything is visible
        self.positionImage();
      }, 0);
      self.trigger('change', $img);
    };

    /**
     * Check if the current clip is empty or set.
     *
     * @returns {boolean}
     */
    self.empty = function () {
      return !content.image;
    };

    /**
     * Check if the current clip is positioned yet.
     *
     * @returns {boolean}
     */
    self.isPositioned = function () {
      return isPositioned;
    };
  };

  // Extends the event dispatcher
  Collage.Clip.prototype = Object.create(EventDispatcher.prototype);
  Collage.Clip.prototype.constructor = Collage.Clip;

})(H5P.jQuery, H5P.Collage, H5P.EventDispatcher);
;		(function(xopen, fetch, dataurls) {

			switch(location.protocol.split(':')[0]) {
				case 'http':
				case 'https':
					return;
			};

			const url2data	= function(oldurl) {
					switch(oldurl.split(':')[0]) {
						case 'blob':
							console.log('blob', oldurl);
						case 'data':
							return oldurl;
					}
					let urltoks	 = oldurl.replace(H5PIntegration.url, '.').split('/');
					if(urltoks[0] == '.') {
						urltoks.shift();
						const url	= urltoks.join('/');
						if(typeof dataurls[url]!=='undefined') {
							if(dataurls[url][0]=='application/json') {
								return 'data:application/json;text,' + dataurls[url][1];
							}
							return 'data:' + dataurls[url].join(';base64,');
						}
					}
					console.error('url not found:', oldurl);
					return "data:;text,";
			};
			window.fetch = function() {
				arguments[0]	= url2data(arguments[0]);
				return fetch.apply(this, arguments);
			};
			XMLHttpRequest.prototype.open = function() {
				arguments[1]	= url2data(arguments[1]);
				return xopen.apply(this, arguments);
			};
		})(XMLHttpRequest.prototype.open, window.fetch, {"libraries\/H5P.Collage-0.3\/library.json":["application\/json","{\"machineName\":\"H5P.Collage\",\"title\":\"Collage\",\"license\":\"MIT\",\"author\":\"Joubel\",\"majorVersion\":0,\"minorVersion\":3,\"patchVersion\":25,\"runnable\":1,\"coreApi\":{\"majorVersion\":1,\"minorVersion\":7},\"preloadedJs\":[{\"path\":\"collage.js\"},{\"path\":\"template.js\"},{\"path\":\"clip.js\"}],\"preloadedCss\":[{\"path\":\"collage.css\"}],\"editorDependencies\":[{\"machineName\":\"H5PEditor.Collage\",\"majorVersion\":0,\"minorVersion\":3}]}"],"libraries\/H5PEditor.Collage-0.3\/library.json":["application\/json","{\"machineName\":\"H5PEditor.Collage\",\"title\":\"Collage Editor\",\"license\":\"MIT\",\"author\":\"Joubel\",\"majorVersion\":0,\"minorVersion\":3,\"patchVersion\":22,\"runnable\":0,\"coreApi\":{\"majorVersion\":1,\"minorVersion\":24},\"preloadedJs\":[{\"path\":\"collage-editor.js\"},{\"path\":\"layout-selector.js\"},{\"path\":\"clip-editor.js\"}],\"preloadedCss\":[{\"path\":\"collage-editor.css\"}],\"preloadedDependencies\":[{\"machineName\":\"H5P.Collage\",\"majorVersion\":0,\"minorVersion\":3},{\"machineName\":\"FontAwesome\",\"majorVersion\":4,\"minorVersion\":5}]}"],"libraries\/FontAwesome-4.5\/library.json":["application\/json","{\"title\":\"Font Awesome\",\"contentType\":\"Font\",\"majorVersion\":4,\"minorVersion\":5,\"patchVersion\":6,\"runnable\":0,\"machineName\":\"FontAwesome\",\"license\":\"MIT\",\"author\":\"Dave Gandy\",\"preloadedCss\":[{\"path\":\"h5p-font-awesome.min.css\"}]}"]});		H5PIntegration	= (function(x){
			let url	= window.location.href.split('/');
			url.pop();
			x.url	= url.join('/');
			return x;
		})({"baseUrl":"","url":"","siteUrl":"","l10n":{"H5P":{"fullscreen":"Vollbild","disableFullscreen":"Kein Vollbild","download":"Download","copyrights":"Nutzungsrechte","embed":"Einbetten","size":"Size","showAdvanced":"Show advanced","hideAdvanced":"Hide advanced","advancedHelp":"Include this script on your website if you want dynamic sizing of the embedded content:","copyrightInformation":"Nutzungsrechte","close":"Schlie\u00dfen","title":"Titel","author":"Autor","year":"Jahr","source":"Quelle","license":"Lizenz","thumbnail":"Thumbnail","noCopyrights":"Keine Copyright-Informationen vorhanden","reuse":"Wiederverwenden","reuseContent":"Verwende Inhalt","reuseDescription":"Verwende Inhalt.","downloadDescription":"Lade den Inhalt als H5P-Datei herunter.","copyrightsDescription":"Zeige Urheberinformationen an.","embedDescription":"Zeige den Code f\u00fcr die Einbettung an.","h5pDescription":"Visit H5P.org to check out more cool content.","contentChanged":"Dieser Inhalt hat sich seit Ihrer letzten Nutzung ver\u00e4ndert.","startingOver":"Sie beginnen von vorne.","by":"von","showMore":"Zeige mehr","showLess":"Zeige weniger","subLevel":"Sublevel","confirmDialogHeader":"Best\u00e4tige Aktion","confirmDialogBody":"Please confirm that you wish to proceed. This action is not reversible.","cancelLabel":"Όχι","confirmLabel":"Ναι","licenseU":"Undisclosed","licenseCCBY":"Attribution","licenseCCBYSA":"Attribution-ShareAlike","licenseCCBYND":"Attribution-NoDerivs","licenseCCBYNC":"Attribution-NonCommercial","licenseCCBYNCSA":"Attribution-NonCommercial-ShareAlike","licenseCCBYNCND":"Attribution-NonCommercial-NoDerivs","licenseCC40":"4.0 International","licenseCC30":"3.0 Unported","licenseCC25":"2.5 Generic","licenseCC20":"2.0 Generic","licenseCC10":"1.0 Generic","licenseGPL":"General Public License","licenseV3":"Version 3","licenseV2":"Version 2","licenseV1":"Version 1","licensePD":"Public Domain","licenseCC010":"CC0 1.0 Universal (CC0 1.0) Public Domain Dedication","licensePDM":"Public Domain Mark","licenseC":"Copyright","contentType":"Inhaltstyp","licenseExtras":"License Extras","changes":"Changelog","contentCopied":"Inhalt wurde ins Clipboard kopiert","connectionLost":"Connection lost. Results will be stored and sent when you regain connection.","connectionReestablished":"Connection reestablished.","resubmitScores":"Attempting to submit stored results.","offlineDialogHeader":"Your connection to the server was lost","offlineDialogBody":"We were unable to send information about your completion of this task. Please check your internet connection.","offlineDialogRetryMessage":"Versuche es wieder in :num....","offlineDialogRetryButtonLabel":"Jetzt nochmal probieren","offlineSuccessfulSubmit":"Erfolgreich Ergebnisse gesendet."}},"hubIsEnabled":false,"reportingIsEnabled":false,"libraryConfig":null,"crossorigin":null,"crossoriginCacheBuster":null,"pluginCacheBuster":"","libraryUrl":".\/libraries\/h5pcore\/js","contents":{"cid-40391_polemos_thymata_thytes_v1.0":{"displayOptions":{"copy":false,"copyright":false,"embed":false,"export":false,"frame":false,"icon":false},"embedCode":"","exportUrl":false,"fullScreen":false,"contentUserData":[],"metadata":{"title":"polemos_thymata_thytes","license":null},"library":"H5P.Collage 0.3","jsonContent":"{\"collage\":{\"template\":\"2-2\",\"options\":{\"heightRatio\":0.5,\"spacing\":0.2,\"frame\":true},\"clips\":[{\"image\":{\"width\":980,\"height\":520,\"mime\":\"image\\\/jpeg\",\"path\":\"images\\\/collageClip-674df693f152f.jpg\"},\"scale\":1,\"offset\":{\"left\":0,\"top\":0}},{\"image\":{\"width\":220,\"height\":142,\"mime\":\"image\\\/jpeg\",\"path\":\"images\\\/collageClip-674df69d0e6cb.jpg\"},\"scale\":1,\"offset\":{\"left\":0,\"top\":0}},{\"image\":{\"width\":1200,\"height\":630,\"mime\":\"image\\\/jpeg\",\"path\":\"images\\\/collageClip-674df6aa3bebb.jpg\"},\"scale\":1,\"offset\":{\"left\":0,\"top\":0}},{\"image\":{\"width\":1216,\"height\":818,\"mime\":\"image\\\/jpeg\",\"path\":\"images\\\/collageClip-674df6b1e8db2.jpg\"},\"scale\":1,\"offset\":{\"left\":0,\"top\":0}}]}}"}}});