System.register(['reactive-jsx', 'src/client/graphics.js', 'utils', 'src/client/vivide/vivide.js'], function (_export, _context) {
  "use strict";

  var _childExpression, _childText, _childElement, _children, _attributeExpression, _attributeStringLiteral, _attributes, _element, _addSourceLocation, pt, debounce, through, asDragImageFor, getObjectFor, removeTempKey, letsScript;

  return {
    setters: [function (_reactiveJsx) {
      _childExpression = _reactiveJsx.childExpression;
      _childText = _reactiveJsx.childText;
      _childElement = _reactiveJsx.childElement;
      _children = _reactiveJsx.children;
      _attributeExpression = _reactiveJsx.attributeExpression;
      _attributeStringLiteral = _reactiveJsx.attributeStringLiteral;
      _attributes = _reactiveJsx.attributes;
      _element = _reactiveJsx.element;
      _addSourceLocation = _reactiveJsx.addSourceLocation;
    }, function (_srcClientGraphicsJs) {
      pt = _srcClientGraphicsJs.pt;
    }, function (_utils) {
      debounce = _utils.debounce;
      through = _utils.through;
      asDragImageFor = _utils.asDragImageFor;
      getObjectFor = _utils.getObjectFor;
      removeTempKey = _utils.removeTempKey;
    }, function (_srcClientVivideVivideJs) {
      letsScript = _srcClientVivideVivideJs.letsScript;
    }],
    execute: function () {
      const __SystemJSRewritingHack = {};
      _recorder_._src_client_draganddrop_js = _recorder_._src_client_draganddrop_js || {};
      Object.defineProperty(_recorder_._src_client_draganddrop_js, '__unload__', {
        get() {
          return __unload__;
        },

        set(thisIsVererySecretVariableName) {
          _export('__unload__', __unload__ = thisIsVererySecretVariableName);

          return true;
        },

        enumerable: true,
        configurable: true
      });
      Object.defineProperty(_recorder_._src_client_draganddrop_js, 'findDropContext', {
        get() {
          return findDropContext;
        },

        set(thisIsVererySecretVariableName) {
          findDropContext = thisIsVererySecretVariableName;
          return true;
        },

        enumerable: true,
        configurable: true
      });
      Object.defineProperty(_recorder_._src_client_draganddrop_js, 'appendToContainerAt', {
        get() {
          return appendToContainerAt;
        },

        set(thisIsVererySecretVariableName) {
          appendToContainerAt = thisIsVererySecretVariableName;
          return true;
        },

        enumerable: true,
        configurable: true
      });
      Object.defineProperty(_recorder_._src_client_draganddrop_js, 'applyDragCSSClass', {
        get() {
          return applyDragCSSClass;
        },

        set(thisIsVererySecretVariableName) {
          _export('applyDragCSSClass', applyDragCSSClass = thisIsVererySecretVariableName);

          return true;
        },

        enumerable: true,
        configurable: true
      });
      Object.defineProperty(_recorder_._src_client_draganddrop_js, 'pt', {
        get() {
          return pt;
        },

        set(thisIsVererySecretVariableName) {
          pt = thisIsVererySecretVariableName;
          return true;
        },

        enumerable: true,
        configurable: true
      });
      Object.defineProperty(_recorder_._src_client_draganddrop_js, 'removeTempKey', {
        get() {
          return removeTempKey;
        },

        set(thisIsVererySecretVariableName) {
          removeTempKey = thisIsVererySecretVariableName;
          return true;
        },

        enumerable: true,
        configurable: true
      });
      Object.defineProperty(_recorder_._src_client_draganddrop_js, 'getObjectFor', {
        get() {
          return getObjectFor;
        },

        set(thisIsVererySecretVariableName) {
          getObjectFor = thisIsVererySecretVariableName;
          return true;
        },

        enumerable: true,
        configurable: true
      });
      Object.defineProperty(_recorder_._src_client_draganddrop_js, 'asDragImageFor', {
        get() {
          return asDragImageFor;
        },

        set(thisIsVererySecretVariableName) {
          asDragImageFor = thisIsVererySecretVariableName;
          return true;
        },

        enumerable: true,
        configurable: true
      });
      Object.defineProperty(_recorder_._src_client_draganddrop_js, 'through', {
        get() {
          return through;
        },

        set(thisIsVererySecretVariableName) {
          through = thisIsVererySecretVariableName;
          return true;
        },

        enumerable: true,
        configurable: true
      });
      Object.defineProperty(_recorder_._src_client_draganddrop_js, 'debounce', {
        get() {
          return debounce;
        },

        set(thisIsVererySecretVariableName) {
          debounce = thisIsVererySecretVariableName;
          return true;
        },

        enumerable: true,
        configurable: true
      });
      Object.defineProperty(_recorder_._src_client_draganddrop_js, 'letsScript', {
        get() {
          return letsScript;
        },

        set(thisIsVererySecretVariableName) {
          letsScript = thisIsVererySecretVariableName;
          return true;
        },

        enumerable: true,
        configurable: true
      });
      function applyDragCSSClass() {
        this.addEventListener('dragenter', evt => this.classList.add("drag"), false);
        this.addEventListener('dragleave', evt => this.classList.remove("drag"), false);
        this.addEventListener('drop', evt => this.classList.remove("drag"));
      }

      _export('applyDragCSSClass', applyDragCSSClass);

      function appendToContainerAt(node, evt) {
        dropOnDocumentBehavior.openAt(node, evt
        // document.body.appendChild(node);
        // lively.setGlobalPosition(node, pt(evt.clientX, evt.clientY));
        );
      }

      //class DataTransferItemHandler {
      //  handle() {
      //    
      //  }
      //}

      class DropOnBodyHandler {
        constructor(mimeType, handler) {
          this.mimeType = mimeType;
          this.handler = handler;
        }

        handle(evt) {
          const dt = evt.dataTransfer;
          if (!dt.types.includes(this.mimeType)) {
            return false;
          }

          const element = this.handler(dt.getData(this.mimeType));
          if (element) {
            if (element.then) {
              element.then(r => {
                appendToContainerAt(r, evt);
              });
            } else {
              appendToContainerAt(element, evt);
            }
            return true;
          } else {
            return false;
          }
        }
      }

      Object.defineProperty(_recorder_._src_client_draganddrop_js, 'DropOnBodyHandler', {
        get() {
          return DropOnBodyHandler;
        },

        set(thisIsVererySecretVariableName) {
          DropOnBodyHandler = thisIsVererySecretVariableName;
          return true;
        },

        enumerable: true,
        configurable: true
      });
      function findDropContext(element, path, container = document.body) {
        return path.find(ea => {
          return ea && (ea === container || ea.classList && ea.classList.contains("lively-content") || ea.localName == "lively-folder");
        }) || container;
      }

      // drop and a dragged html element into a container
      class DropElementHandler {
        constructor(container, customHandler) {
          this.container = container;
          if (customHandler) {
            this.handleElement = customHandler;
          }
        }

        handleElement(element, evt) {
          var container = findDropContext(element, evt.composedPath(), this.container);
          container.appendChild(element);
          lively.setGlobalPosition(element, lively.getPosition(evt));
          if (element.lastDragOffset) {
            lively.moveBy(element, element.lastDragOffset);
          }
        }

        handle(evt) {
          const dt = evt.dataTransfer;
          if (!dt.types.includes("lively/element")) {
            return false;
          }
          const tempKey = dt.getData("lively/element");
          const element = getObjectFor(tempKey);
          if (!element) return false;

          this.handleElement(element, evt);

          removeTempKey(tempKey);
          return true;
        }

        static handle(evt, container, cb) {
          new this(container, cb).handle(evt);
        }
      }

      _export('DropElementHandler', DropElementHandler);

      Object.defineProperty(_recorder_._src_client_draganddrop_js, 'DropElementHandler', {
        get() {
          return DropElementHandler;
        },

        set(thisIsVererySecretVariableName) {
          _export('DropElementHandler', DropElementHandler = thisIsVererySecretVariableName);

          return true;
        },

        enumerable: true,
        configurable: true
      });
      const dropOnDocumentBehavior = {

        removeListeners() {
          lively.removeEventListener("dropOnDocumentBehavior", document);
        },

        load() {
          // #HACK: we remove listeners here, because this module is called three times (without unloading in between!!)
          this.removeListeners();
          lively.addEventListener("dropOnDocumentBehavior", document, "dragover", this.onDragOver.bind(this));
          lively.addEventListener("dropOnDocumentBehavior", document, "drop", this.onDrop.bind(this));

          this.handlers = [
          // lively elements
          new DropElementHandler(document.body),
          // {
          //   handle(evt) {
          //     const dt = evt.dataTransfer;
          //     if(!dt.types.includes("lively/element")) { return false; }
          //     const tempKey = dt.getData("lively/element");
          //     const element = getObjectFor(tempKey);
          //     if (!element) return false;
          //     document.body.appendChild(element)
          //     lively.setGlobalPosition(element, lively.getPosition(evt))
          //     if (element.lastDragOffset) {
          //       lively.moveBy(element, element.lastDragOffset)
          //     }
          //     removeTempKey(tempKey);
          //     return true;
          //   }
          // },
          // vivide list
          {
            handle(evt) {
              const dt = evt.dataTransfer;
              if (!dt.types.includes("vivide")) {
                return false;
              }
              if (!dt.types.includes("javascript/object")) {
                return false;
              }
              const dataTempKey = dt.getData("javascript/object");
              const data = getObjectFor(dataTempKey);
              const viewTempKey = dt.getData("vivide/source-view");
              const sourceView = getObjectFor(viewTempKey);
              getObjectFor;
              letsScript(data, evt, sourceView);
              return true;
            }
          },

          // move a desktop item
          {
            handle(evt) {
              const dt = evt.dataTransfer;
              if (!dt.types.includes("desktop-icon/object")) {
                return false;
              }
              const tempKey = dt.getData("desktop-icon/object");
              const icon = getObjectFor(tempKey);
              removeTempKey(tempKey);

              const offset = dt.types.includes("desktop-icon/offset") ? JSON.parse(dt.getData("desktop-icon/offset")) : pt(0, 0);
              lively.setGlobalPosition(icon, pt(evt.clientX, evt.clientY).subPt(offset));
              return true;
            }
          },

          // knot/url to desktop item
          {
            handle(evt) {
              const dt = evt.dataTransfer;
              if (!dt.types.includes("knot/url")) {
                return false;
              }
              const knotURL = dt.getData("knot/url");

              _addSourceLocation(lively.create('knot-desktop-icon'), {
                file: 'https://lively-kernel.org/lively4/lively4-function-completion/src/client/draganddrop.js',
                end: {
                  column: 44,
                  line: 164
                },
                start: {
                  column: 10,
                  line: 164
                }
              }).through(icon => lively.setGlobalPosition(icon, pt(evt.clientX, evt.clientY))).then(icon => icon.knotURL = knotURL);

              return true;
            }
          }, new DropOnBodyHandler('text/uri-list', urlString => {
            if (!urlString.match(/^data\:image\/png/)) {
              return false;
            }

            return _element('img', _attributes(_attributeStringLiteral('class', 'lively-content'), _attributeExpression('src', urlString)), _children(), {
              file: 'https://lively-kernel.org/lively4/lively4-function-completion/src/client/draganddrop.js',
              end: {
                column: 65,
                line: 175
              },
              start: {
                column: 15,
                line: 175
              }
            });
          }),

          // open javascript/object in inspector
          {
            handle(evt) {
              const dt = evt.dataTransfer;
              if (!dt.types.includes("javascript/object")) {
                return false;
              }
              const tempKey = dt.getData("javascript/object");

              lively.openInspector(getObjectFor(tempKey), pt(evt.clientX, evt.clientY).subPt(lively.getGlobalPosition(document.body)));
              removeTempKey(tempKey);

              return true;
            }
          }, new DropOnBodyHandler('text/uri-list', urlString => {
            if (!urlString.match(/^plex:\//)) {
              return false;
            }
            var existing = document.body.querySelector(`plex-link[src="${urlString}"]`);
            if (existing) {
              existing.remove();
            }
            lively.notify("dropped " + urlString);
            return _element('plex-link', _attributes(_attributeExpression('src', urlString)), _children(), {
              file: 'https://lively-kernel.org/lively4/lively4-function-completion/src/client/draganddrop.js',
              end: {
                column: 54,
                line: 201
              },
              start: {
                column: 15,
                line: 201
              }
            });
          }), new DropOnBodyHandler('text/uri-list', urlString => {
            var link = _element('div', _attributes(_attributeStringLiteral('class', 'lively-content')), _children(_childElement(_element('a', _attributes(_attributeExpression('href', urlString)), _children(_childText('\n          '), _childExpression(urlString.replace(/\/$/, "").replace(/.*\//, "")), _childText('\n        ')), {
              file: 'https://lively-kernel.org/lively4/lively4-function-completion/src/client/draganddrop.js',
              end: {
                column: 12,
                line: 208
              },
              start: {
                column: 47,
                line: 206
              }
            }))), {
              file: 'https://lively-kernel.org/lively4/lively4-function-completion/src/client/draganddrop.js',
              end: {
                column: 18,
                line: 208
              },
              start: {
                column: 19,
                line: 206
              }
            });
            // register the event... to be able to remove it again...
            lively.addEventListener("link", link, "click", evt => {
              // #TODO make this bevior persistent?
              evt.preventDefault();
              evt.stopPropagation();
              lively.openBrowser(urlString);
              return true;
            });
            return link;
          }), new DropOnBodyHandler('text/html', htmlString => {
            const div = _element('div', _attributes(), _children(), {
              file: 'https://lively-kernel.org/lively4/lively4-function-completion/src/client/draganddrop.js',
              end: {
                column: 31,
                line: 221
              },
              start: {
                column: 20,
                line: 221
              }
            });
            div.innerHTML = htmlString;

            return div;
          }), new DropOnBodyHandler('text/plain', text => {
            return _element('p', _attributes(), _children(_childExpression(text)), {
              file: 'https://lively-kernel.org/lively4/lively4-function-completion/src/client/draganddrop.js',
              end: {
                column: 28,
                line: 228
              },
              start: {
                column: 15,
                line: 228
              }
            });
          }),

          // just an ui interaction, no data
          {
            handle(evt) {
              return evt.dataTransfer.types.includes("ui/interaction");
            }
          }];
        },

        openAt(node, evt) {
          var target = this.lastDropTarget || document.body;
          target.appendChild(node);
          lively.setGlobalPosition(node, pt(evt.clientX, evt.clientY));
          if (this.lastDropTargetHighlight) this.lastDropTargetHighlight.remove();
        },

        onDragOver(evt) {
          this.lastDropTarget = Array.from(evt.composedPath()).find(ea => ea && (ea.classList && ea.classList.contains("lively-content") || ea.localName == "lively-folder"));
          if (this.lastDropTargetHighlight) this.lastDropTargetHighlight.remove();
          this.lastDropTargetHighlight = lively.showElement(this.lastDropTarget);

          evt.stopPropagation();
          evt.preventDefault();
        },

        handleFiles(evt) {
          const files = evt.dataTransfer.files;

          if (files.length === 0) {
            return false;
          }

          lively.notify(`Dropped ${files.length} file(s).`);
          Array.from(files).forEach(async file => {
            const extension = lively.files.extension(file.name
            // #Research how do we deal with content vs. container... drop a picture here or a file that contains the picture? #Journal #Interesting
            );if (extension == "png" && !evt.ctrlKey) {
              // #Refactor #TODO use lively.files.readBlobAsDataURL
              const reader = new FileReader();
              reader.onload = event => {
                const dataURL = event.target.result.replace(/^data\:image\/png;/, `data:image/png;name=${file.name};`);
                const img = _element('img', _attributes(_attributeStringLiteral('class', 'lively-content'), _attributeExpression('src', dataURL)), _children(), {
                  file: 'https://lively-kernel.org/lively4/lively4-function-completion/src/client/draganddrop.js',
                  end: {
                    column: 74,
                    line: 274
                  },
                  start: {
                    column: 26,
                    line: 274
                  }
                });
                appendToContainerAt(img, evt);
              };
              reader.readAsDataURL(file);
            }
            // else if (extension == "html") {
            //   var source = await lively.files.readBlobAsText(file)
            //   lively.clipboard.pasteHTMLDataInto(source, document.body, false, lively.getPosition(evt));
            // } 
            else {
                var item = await _element('lively-file', _attributes(), _children(), {
                  file: 'https://lively-kernel.org/lively4/lively4-function-completion/src/client/draganddrop.js',
                  end: {
                    column: 55,
                    line: 284
                  },
                  start: {
                    column: 28,
                    line: 284
                  }
                });
                item.classList.add("lively-content" // for persistence
                // #TODO check for existing "file"
                );item.name = file.name;
                this.openAt(item, evt);
                item.url = await lively.files.readBlobAsDataURL(file);
              }
          });
          return true;
        },

        async onDrop(evt) {
          // var target = evt.composedPath().find(ea => ea.classList.contains("lively-content") )
          const dt = evt.dataTransfer;

          /*
          console.group("Drop Event on body");
          console.log(dt);
          console.log(`#files ${dt.files.length}`);
          console.log(Array.from(dt.items));
          lively.notify(Array.from(dt.types).join(" "));
          console.groupEnd();
          */

          evt.stopPropagation();
          evt.preventDefault();

          if (this.handleFiles(evt)) {
            return;
          }

          if (Array.from(dt.types).length > 0) {
            if (this.handlers.find(handler => handler.handle(evt))) {
              return;
            }
          }
          var cssText = evt.dataTransfer.getData("lively/cssText");
          if (this.lastDropTarget && cssText) {
            cssText.split(/; */).forEach(pair => {
              var name, value;
              [name, value] = pair.split(/: */);
              lively.notify("set " + this.lastDropTarget + "'s " + name + " to " + value);
              name = name.replace(/ /g, "");
              this.lastDropTarget.style[name] = value;
              // window.LastDT = this.lastDropTarget
              // window.LastName = name
              // window.LastCSS = value
              // target.style["background"] = "red"
            });
          } else {

            lively.warn("Dragged content contained neither files nor handled items");
          }
        }
      };

      Object.defineProperty(_recorder_._src_client_draganddrop_js, 'dropOnDocumentBehavior', {
        get() {
          return dropOnDocumentBehavior;
        },

        set(thisIsVererySecretVariableName) {
          dropOnDocumentBehavior = thisIsVererySecretVariableName;
          return true;
        },

        enumerable: true,
        configurable: true
      });
      function __unload__() {
        dropOnDocumentBehavior.removeListeners();
      }

      _export('__unload__', __unload__);

      dropOnDocumentBehavior.load();
    }
  };
});