import { Arr } from '@ephox/katamari';
import { Insert, Remove, SugarBody, Traverse } from '@ephox/sugar';
import * as InternalAttachment from '../../system/InternalAttachment';
const attach = (parent, child) => {
    attachWith(parent, child, Insert.append);
};
const attachWith = (parent, child, insertion) => {
    parent.getSystem().addToWorld(child);
    insertion(parent.element, child.element);
    if (SugarBody.inBody(parent.element)) {
        InternalAttachment.fireAttaching(child);
    }
    parent.syncComponents();
};
const doDetach = (component) => {
    InternalAttachment.fireDetaching(component);
    Remove.remove(component.element);
    component.getSystem().removeFromWorld(component);
};
const detach = (component) => {
    const parent = Traverse.parent(component.element).bind((p) => component.getSystem().getByDom(p).toOptional());
    doDetach(component);
    parent.each((p) => {
        p.syncComponents();
    });
};
const detachChildren = (component) => {
    // This will not detach the component, but will detach its children and sync at the end.
    const subs = component.components();
    Arr.each(subs, doDetach);
    // Clear the component also.
    Remove.empty(component.element);
    component.syncComponents();
};
const attachSystem = (element, guiSystem) => {
    attachSystemWith(element, guiSystem, Insert.append);
};
const attachSystemAfter = (element, guiSystem) => {
    attachSystemWith(element, guiSystem, Insert.after);
};
const attachSystemWith = (element, guiSystem, inserter) => {
    inserter(element, guiSystem.element);
    const children = Traverse.children(guiSystem.element);
    Arr.each(children, (child) => {
        guiSystem.getByDom(child).each(InternalAttachment.fireAttaching);
    });
};
const detachSystem = (guiSystem) => {
    const children = Traverse.children(guiSystem.element);
    Arr.each(children, (child) => {
        guiSystem.getByDom(child).each(InternalAttachment.fireDetaching);
    });
    Remove.remove(guiSystem.element);
};
export { attach, attachWith, detach, detachChildren, attachSystem, attachSystemAfter, detachSystem };
//# sourceMappingURL=Attachment.js.map