"use strict";
Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
const index_esm = require("../../min-dash/dist/index.esm.js");
const index_esm$1 = require("../../min-dom/dist/index.esm.js");
const index_esm$3 = require("../../tiny-svg/dist/index.esm.js");
const index_esm$2 = require("../../bpmn-moddle/dist/index.esm.js");
const index_es = require("../../inherits-browser/dist/index.es.js");
const Importer = require("./import/Importer.js");
const CompatibilityUtil = require("./util/CompatibilityUtil.js");
const PoweredByUtil = require("./util/PoweredByUtil.js");
const Diagram = require("../../diagram-js/lib/Diagram.js");
function BaseViewer(options) {
  options = index_esm.assign({}, DEFAULT_OPTIONS, options);
  this._moddle = this._createModdle(options);
  this._container = this._createContainer(options);
  addProjectLogo(this._container);
  this._init(this._container, this._moddle, options);
}
index_es.default(BaseViewer, Diagram.default);
BaseViewer.prototype.importXML = CompatibilityUtil.wrapForCompatibility(async function importXML(xml, bpmnDiagram) {
  const self = this;
  function ParseCompleteEvent(data) {
    const event = self.get("eventBus").createEvent(data);
    Object.defineProperty(event, "context", {
      enumerable: true,
      get: function() {
        console.warn(new Error(
          "import.parse.complete <context> is deprecated and will be removed in future library versions"
        ));
        return {
          warnings: data.warnings,
          references: data.references,
          elementsById: data.elementsById
        };
      }
    });
    return event;
  }
  let aggregatedWarnings = [];
  try {
    xml = this._emit("import.parse.start", { xml }) || xml;
    let parseResult;
    try {
      parseResult = await this._moddle.fromXML(xml, "bpmn:Definitions");
    } catch (error) {
      this._emit("import.parse.complete", {
        error
      });
      throw error;
    }
    let definitions = parseResult.rootElement;
    const references = parseResult.references;
    const parseWarnings = parseResult.warnings;
    const elementsById = parseResult.elementsById;
    aggregatedWarnings = aggregatedWarnings.concat(parseWarnings);
    definitions = this._emit("import.parse.complete", ParseCompleteEvent({
      error: null,
      definitions,
      elementsById,
      references,
      warnings: aggregatedWarnings
    })) || definitions;
    const importResult = await this.importDefinitions(definitions, bpmnDiagram);
    aggregatedWarnings = aggregatedWarnings.concat(importResult.warnings);
    this._emit("import.done", { error: null, warnings: aggregatedWarnings });
    return { warnings: aggregatedWarnings };
  } catch (err) {
    let error = err;
    aggregatedWarnings = aggregatedWarnings.concat(error.warnings || []);
    addWarningsToError(error, aggregatedWarnings);
    error = checkValidationError(error);
    this._emit("import.done", { error, warnings: error.warnings });
    throw error;
  }
});
BaseViewer.prototype.importDefinitions = CompatibilityUtil.wrapForCompatibility(async function importDefinitions(definitions, bpmnDiagram) {
  this._setDefinitions(definitions);
  const result = await this.open(bpmnDiagram);
  return { warnings: result.warnings };
});
BaseViewer.prototype.open = CompatibilityUtil.wrapForCompatibility(async function open(bpmnDiagramOrId) {
  const definitions = this._definitions;
  let bpmnDiagram = bpmnDiagramOrId;
  if (!definitions) {
    const error = new Error("no XML imported");
    addWarningsToError(error, []);
    throw error;
  }
  if (typeof bpmnDiagramOrId === "string") {
    bpmnDiagram = findBPMNDiagram(definitions, bpmnDiagramOrId);
    if (!bpmnDiagram) {
      const error = new Error("BPMNDiagram <" + bpmnDiagramOrId + "> not found");
      addWarningsToError(error, []);
      throw error;
    }
  }
  try {
    this.clear();
  } catch (error) {
    addWarningsToError(error, []);
    throw error;
  }
  const { warnings } = await Importer.importBpmnDiagram(this, definitions, bpmnDiagram);
  return { warnings };
});
BaseViewer.prototype.saveXML = CompatibilityUtil.wrapForCompatibility(async function saveXML(options) {
  options = options || {};
  let definitions = this._definitions, error, xml;
  try {
    if (!definitions) {
      throw new Error("no definitions loaded");
    }
    definitions = this._emit("saveXML.start", {
      definitions
    }) || definitions;
    const result2 = await this._moddle.toXML(definitions, options);
    xml = result2.xml;
    xml = this._emit("saveXML.serialized", {
      xml
    }) || xml;
  } catch (err) {
    error = err;
  }
  const result = error ? { error } : { xml };
  this._emit("saveXML.done", result);
  if (error) {
    throw error;
  }
  return result;
});
BaseViewer.prototype.saveSVG = CompatibilityUtil.wrapForCompatibility(async function saveSVG(options = {}) {
  this._emit("saveSVG.start");
  let svg, err;
  try {
    const canvas = this.get("canvas");
    const contentNode = canvas.getActiveLayer(), defsNode = index_esm$1.query("defs", canvas._svg);
    const contents = index_esm$3.innerSVG(contentNode), defs = defsNode ? "<defs>" + index_esm$3.innerSVG(defsNode) + "</defs>" : "";
    const bbox = contentNode.getBBox();
    svg = '<?xml version="1.0" encoding="utf-8"?>\n<!-- created with bpmn-js / http://bpmn.io -->\n<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\n<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="' + bbox.width + '" height="' + bbox.height + '" viewBox="' + bbox.x + " " + bbox.y + " " + bbox.width + " " + bbox.height + '" version="1.1">' + defs + contents + "</svg>";
  } catch (e) {
    err = e;
  }
  this._emit("saveSVG.done", {
    error: err,
    svg
  });
  if (err) {
    throw err;
  }
  return { svg };
});
BaseViewer.prototype._setDefinitions = function(definitions) {
  this._definitions = definitions;
};
BaseViewer.prototype.getModules = function() {
  return this._modules;
};
BaseViewer.prototype.clear = function() {
  if (!this.getDefinitions()) {
    return;
  }
  Diagram.default.prototype.clear.call(this);
};
BaseViewer.prototype.destroy = function() {
  Diagram.default.prototype.destroy.call(this);
  index_esm$1.remove(this._container);
};
BaseViewer.prototype.on = function(event, priority, callback, target) {
  return this.get("eventBus").on(event, priority, callback, target);
};
BaseViewer.prototype.off = function(event, callback) {
  this.get("eventBus").off(event, callback);
};
BaseViewer.prototype.attachTo = function(parentNode) {
  if (!parentNode) {
    throw new Error("parentNode required");
  }
  this.detach();
  if (parentNode.get && parentNode.constructor.prototype.jquery) {
    parentNode = parentNode.get(0);
  }
  if (typeof parentNode === "string") {
    parentNode = index_esm$1.query(parentNode);
  }
  parentNode.appendChild(this._container);
  this._emit("attach", {});
  this.get("canvas").resized();
};
BaseViewer.prototype.getDefinitions = function() {
  return this._definitions;
};
BaseViewer.prototype.detach = function() {
  const container = this._container, parentNode = container.parentNode;
  if (!parentNode) {
    return;
  }
  this._emit("detach", {});
  parentNode.removeChild(container);
};
BaseViewer.prototype._init = function(container, moddle, options) {
  const baseModules = options.modules || this.getModules(), additionalModules = options.additionalModules || [], staticModules = [
    {
      bpmnjs: ["value", this],
      moddle: ["value", moddle]
    }
  ];
  const diagramModules = [].concat(staticModules, baseModules, additionalModules);
  const diagramOptions = index_esm.assign(index_esm.omit(options, ["additionalModules"]), {
    canvas: index_esm.assign({}, options.canvas, { container }),
    modules: diagramModules
  });
  Diagram.default.call(this, diagramOptions);
  if (options && options.container) {
    this.attachTo(options.container);
  }
};
BaseViewer.prototype._emit = function(type, event) {
  return this.get("eventBus").fire(type, event);
};
BaseViewer.prototype._createContainer = function(options) {
  const container = index_esm$1.domify('<div class="bjs-container"></div>');
  index_esm$1.assignStyle(container, {
    width: ensureUnit(options.width),
    height: ensureUnit(options.height),
    position: options.position
  });
  return container;
};
BaseViewer.prototype._createModdle = function(options) {
  const moddleOptions = index_esm.assign({}, this._moddleExtensions, options.moddleExtensions);
  return new index_esm$2.default(moddleOptions);
};
BaseViewer.prototype._modules = [];
function addWarningsToError(err, warningsAry) {
  err.warnings = warningsAry;
  return err;
}
function checkValidationError(err) {
  const pattern = /unparsable content <([^>]+)> detected([\s\S]*)$/;
  const match = pattern.exec(err.message);
  if (match) {
    err.message = "unparsable content <" + match[1] + "> detected; this may indicate an invalid BPMN 2.0 diagram file" + match[2];
  }
  return err;
}
const DEFAULT_OPTIONS = {
  width: "100%",
  height: "100%",
  position: "relative"
};
function ensureUnit(val) {
  return val + (index_esm.isNumber(val) ? "px" : "");
}
function findBPMNDiagram(definitions, diagramId) {
  if (!diagramId) {
    return null;
  }
  return index_esm.find(definitions.diagrams, function(element) {
    return element.id === diagramId;
  }) || null;
}
function addProjectLogo(container) {
  const img = PoweredByUtil.BPMNIO_IMG;
  const linkMarkup = '<a href="http://bpmn.io" target="_blank" class="bjs-powered-by" title="Powered by bpmn.io" >' + img + "</a>";
  const linkElement = index_esm$1.domify(linkMarkup);
  index_esm$1.assignStyle(index_esm$1.query("svg", linkElement), PoweredByUtil.LOGO_STYLES);
  index_esm$1.assignStyle(linkElement, PoweredByUtil.LINK_STYLES, {
    position: "absolute",
    bottom: "15px",
    right: "15px",
    zIndex: "100"
  });
  container.appendChild(linkElement);
  index_esm$1.event.bind(linkElement, "click", function(event) {
    PoweredByUtil.open();
    event.preventDefault();
  });
}
exports.default = BaseViewer;
