import { css, html, BaseCustomWebComponentConstructorAppend } from '@node-projects/base-custom-webcomponent';
import { OverlayLayer } from './extensions/OverlayLayer.js';
export class OverlayLayerView extends BaseCustomWebComponentConstructorAppend {
    static template = html `
    <svg id="svg" style="pointer-events: none;">
      <defs id="defs"></defs>
      <g id="background"></g>
      <g id="normal"></g>
      <g id="foreground"></g>
    </svg>`;
    static style = css `
    svg {
      width: 100%;
      height: 100%;
      overflow: visible;
    }

    .svg-invisible { stroke: transparent; fill: transparent; pointer-events: auto; }
    .svg-snapline { stroke: purple; stroke-dasharray: 4; fill: transparent; }
    .svg-selector { stroke: black; fill: #3899ec55; stroke-width: 1; stroke-dasharray: 2; }
    .svg-primary-selection-move { stroke: #3899ec; fill: #3899ec; cursor: move; pointer-events: auto; }
    .svg-position  { stroke: black; stroke-dasharray: 2; }
    .svg-path { stroke: #3899ec; fill: orange; pointer-events: auto; }
    .svg-path-line { stroke: #3899ec; stroke-dasharray: 2; }
    .svg-draw-new-element { stroke: black; fill: transparent; stroke-width: 1; }
    .svg-toolbar-container { overflow: visible }
    .svg-toolbar-container > div { padding: 5px; display: flex; gap: 2px; background: white; border-radius: 4px; box-shadow: 0 2px 10px 0 rgba(19,23,32,.2); align-items: center; }
    
    node-projects-image-button-list-selector img {
      height: 16px;
      border: 1px solid black;
      border-radius: 4px;
      box-sizing: border-box;
      pointer-events: auto;
      cursor: pointer;
    }
    node-projects-image-button-list-selector img:hover {
      background: lightgray;
    }
    node-projects-image-button-list-selector img:active {
      translate: 1px 1px
    }
    `;
    static is = 'node-projects-overlay-layer-view';
    _serviceContainer;
    _svg;
    _gBackground;
    _gNormal;
    _gForeground;
    _defs;
    _id = 0;
    constructor(serviceContainer) {
        super();
        this._serviceContainer = serviceContainer;
        this._svg = this._getDomElement('svg');
        this._gBackground = this._getDomElement('background');
        this._gNormal = this._getDomElement('normal');
        this._gForeground = this._getDomElement('foreground');
        this._defs = this._getDomElement('defs');
        this._initialize();
    }
    _initialize() {
        const styles = [OverlayLayerView.style];
        const alreadyApplied = new Set();
        for (const extList of this._serviceContainer.designerExtensions) {
            for (const ext of extList[1]) {
                if (ext.constructor.style) {
                    if (Array.isArray(ext.constructor.style)) {
                        for (const s of ext.constructor.style) {
                            if (!alreadyApplied.has(s)) {
                                alreadyApplied.add(s);
                                styles.push(s);
                            }
                        }
                    }
                    else if (!alreadyApplied.has(ext.constructor.style)) {
                        alreadyApplied.add(ext.constructor.style);
                        styles.push(ext.constructor.style);
                    }
                }
                if (ext.style) {
                    if (Array.isArray(ext.style)) {
                        for (const s of ext.style) {
                            if (!alreadyApplied.has(s)) {
                                alreadyApplied.add(s);
                                styles.push(s);
                            }
                        }
                    }
                    else if (!alreadyApplied.has(ext.style)) {
                        alreadyApplied.add(ext.style);
                        styles.push(ext.style);
                    }
                }
                if (ext.svgDefs) {
                    if (Array.isArray(ext.svgDefs)) {
                        for (const s of ext.svgDefs) {
                            if (!alreadyApplied.has(s)) {
                                alreadyApplied.add(s);
                                const a = document.createElementNS("http://www.w3.org/2000/svg", "defs");
                                a.innerHTML = s;
                                for (let n of [...a.children])
                                    this._defs.appendChild(n);
                            }
                        }
                    }
                    else if (!alreadyApplied.has(ext.svgDefs)) {
                        alreadyApplied.add(ext.svgDefs);
                        const a = document.createElementNS("http://www.w3.org/2000/svg", "defs");
                        a.innerHTML = ext.svgDefs;
                        for (let n of [...a.children])
                            this._defs.appendChild(n);
                    }
                }
                if (ext.constructor.svgDefs) {
                    if (Array.isArray(ext.constructor.svgDefs)) {
                        for (const s of ext.constructor.svgDefs) {
                            if (!alreadyApplied.has(s)) {
                                alreadyApplied.add(s);
                                const a = document.createElementNS("http://www.w3.org/2000/svg", "defs");
                                a.innerHTML = s;
                                for (let n of [...a.children])
                                    this._defs.appendChild(n);
                            }
                        }
                    }
                    else if (!alreadyApplied.has(ext.constructor.svgDefs)) {
                        alreadyApplied.add(ext.constructor.svgDefs);
                        const a = document.createElementNS("http://www.w3.org/2000/svg", "defs");
                        a.innerHTML = ext.constructor.svgDefs;
                        for (let n of [...a.children])
                            this._defs.appendChild(n);
                    }
                }
            }
        }
        for (const ext of this._serviceContainer.designerPointerExtensions) {
            if (ext.style) {
                if (!alreadyApplied.has(ext.style)) {
                    alreadyApplied.add(ext.style);
                    styles.push(ext.style);
                }
            }
            if (ext.svgDefs) {
                if (!alreadyApplied.has(ext.svgDefs)) {
                    alreadyApplied.add(ext.svgDefs);
                    const a = document.createElementNS("http://www.w3.org/2000/svg", "defs");
                    a.innerHTML = ext.svgDefs;
                    for (let n of [...a.children])
                        this._defs.appendChild(n);
                }
            }
        }
        if (this._serviceContainer.overlayLayerViewAdditionalStyles) {
            for (const style of this._serviceContainer.overlayLayerViewAdditionalStyles) {
                if (!alreadyApplied.has(style)) {
                    alreadyApplied.add(style);
                    styles.push(style);
                }
            }
        }
        this.shadowRoot.adoptedStyleSheets = styles;
    }
    backgroundFragment;
    foregroundFragment;
    normalFragment;
    batchCount = 0;
    startBatch() {
        if (this.batchCount == 0) {
            this.backgroundFragment = document.createDocumentFragment();
            this.foregroundFragment = document.createDocumentFragment();
            this.normalFragment = document.createDocumentFragment();
        }
        this.batchCount++;
    }
    endBatch() {
        this.batchCount--;
        if (this.batchCount == 0) {
            if (this.backgroundFragment.hasChildNodes)
                this._gBackground.appendChild(this.backgroundFragment);
            if (this.foregroundFragment.hasChildNodes)
                this._gForeground.appendChild(this.foregroundFragment);
            if (this.normalFragment.hasChildNodes)
                this._gNormal.appendChild(this.normalFragment);
            this.backgroundFragment = null;
            this.foregroundFragment = null;
            this.normalFragment = null;
        }
    }
    addOverlay(overlaySource, element, overlayLayer = OverlayLayer.Normal) {
        element.setAttribute("overlay-source", overlaySource);
        switch (overlayLayer) {
            case OverlayLayer.Background:
                if (this.backgroundFragment)
                    this.backgroundFragment.appendChild(element);
                else
                    this._gBackground.appendChild(element);
                break;
            case OverlayLayer.Foreground:
                if (this.foregroundFragment)
                    this.foregroundFragment.appendChild(element);
                else
                    this._gForeground.appendChild(element);
                break;
            default:
                if (this.normalFragment)
                    this.normalFragment.appendChild(element);
                else
                    this._gNormal.appendChild(element);
                break;
        }
    }
    removeOverlay(element) {
        try {
            element?.parentElement?.removeChild(element);
        }
        catch (err) {
            console.error(err);
        }
    }
    removeAllNodesWithClass(className) {
        const nodes = this._svg.querySelectorAll('.' + className);
        for (const e of nodes) {
            e.parentNode.removeChild(e);
        }
    }
    removeAllOverlays() {
        const nodes = this._svg.querySelectorAll('svg > g > *');
        for (const e of nodes) {
            e.parentNode.removeChild(e);
        }
    }
    createPoint() {
        //@ts-ignore
        return this._svg.createSVGPoint();
    }
    drawGroup(overlaySource, className, group, overlayLayer) {
        if (!group) {
            group = document.createElementNS("http://www.w3.org/2000/svg", "g");
            this.addOverlay(overlaySource, group, overlayLayer);
        }
        if (className)
            group.setAttribute('class', className);
        return group;
    }
    drawLine(overlaySource, x1, y1, x2, y2, className, line, overlayLayer) {
        if (!line) {
            line = document.createElementNS("http://www.w3.org/2000/svg", "line");
            this.addOverlay(overlaySource, line, overlayLayer);
        }
        line.setAttribute('x1', x1);
        line.setAttribute('y1', y1);
        line.setAttribute('x2', x2);
        line.setAttribute('y2', y2);
        if (className)
            line.setAttribute('class', className);
        return line;
    }
    drawCircle(overlaySource, x, y, radius, className, circle, overlayLayer) {
        if (!circle) {
            circle = document.createElementNS("http://www.w3.org/2000/svg", "circle");
            this.addOverlay(overlaySource, circle, overlayLayer);
        }
        circle.setAttribute('cx', x);
        circle.setAttribute('cy', y);
        circle.setAttribute('r', radius);
        if (className)
            circle.setAttribute('class', className);
        return circle;
    }
    drawRect(overlaySource, x, y, w, h, className, rect, overlayLayer) {
        if (!rect) {
            rect = document.createElementNS("http://www.w3.org/2000/svg", "rect");
            this.addOverlay(overlaySource, rect, overlayLayer);
        }
        rect.setAttribute('x', x);
        rect.setAttribute('y', y);
        rect.setAttribute('width', w);
        rect.setAttribute('height', h);
        if (className)
            rect.setAttribute('class', className);
        return rect;
    }
    drawPath(overlaySource, data, className, path, overlayLayer) {
        if (!path) {
            path = document.createElementNS("http://www.w3.org/2000/svg", "path");
            this.addOverlay(overlaySource, path, overlayLayer);
        }
        path.setAttribute('d', data);
        if (className)
            path.setAttribute('class', className);
        return path;
    }
    drawText(overlaySource, text, x, y, className, textEl, overlayLayer) {
        if (!textEl) {
            textEl = document.createElementNS("http://www.w3.org/2000/svg", "text");
            this.addOverlay(overlaySource, textEl, overlayLayer);
        }
        textEl.setAttribute('x', x);
        textEl.setAttribute('y', y);
        textEl.textContent = text;
        if (className)
            textEl.setAttribute('class', className);
        return textEl;
    }
    drawHTML(overlaySource, html, x, y, w, h, className, htmlObj, overlayLayer) {
        if (!htmlObj) {
            htmlObj = document.createElementNS("http://www.w3.org/2000/svg", "foreignObject");
            this.addOverlay(overlaySource, htmlObj, overlayLayer);
        }
        htmlObj.setAttribute('x', x);
        htmlObj.setAttribute('y', y);
        htmlObj.setAttribute('width', w);
        htmlObj.setAttribute('height', h);
        if (typeof html === 'string')
            htmlObj.innerHTML = html;
        else
            htmlObj.appendChild(html);
        if (className)
            htmlObj.setAttribute('class', className);
        return htmlObj;
    }
    drawTextWithBackground(overlaySource, text, x, y, backgroundColor, className, existingEls, overlayLayer) {
        if (!existingEls) {
            let filter = document.createElementNS("http://www.w3.org/2000/svg", "filter");
            filter.setAttribute("x", "0");
            filter.setAttribute("y", "0");
            filter.setAttribute("width", "1");
            filter.setAttribute("height", "1");
            filter.setAttribute("id", "solid_" + (++this._id));
            let flood = document.createElementNS("http://www.w3.org/2000/svg", "feFlood");
            flood.setAttribute("flood-color", backgroundColor);
            filter.appendChild(flood);
            let composite = document.createElementNS("http://www.w3.org/2000/svg", "feComposite");
            composite.setAttribute("in", "SourceGraphic");
            composite.setAttribute("operator", "xor");
            filter.appendChild(composite);
            this._defs.appendChild(filter);
            let textEl1 = document.createElementNS("http://www.w3.org/2000/svg", "text");
            textEl1.setAttribute("filter", "url(#solid_" + this._id + ")");
            let textEl2 = document.createElementNS("http://www.w3.org/2000/svg", "text");
            this.addOverlay(overlaySource, textEl1, overlayLayer);
            this.addOverlay(overlaySource, textEl2, overlayLayer);
            filter.setAttribute("overlay-source", overlaySource);
            flood.setAttribute("overlay-source", overlaySource);
            existingEls = [filter, flood, textEl1, textEl2];
        }
        existingEls[2].setAttribute('x', x);
        existingEls[3].setAttribute('x', x);
        existingEls[2].setAttribute('y', y);
        existingEls[3].setAttribute('y', y);
        existingEls[2].textContent = text;
        existingEls[3].textContent = text;
        if (className) {
            existingEls[2].setAttribute('class', className);
            existingEls[3].setAttribute('class', className);
        }
        return existingEls;
    }
}
customElements.define(OverlayLayerView.is, OverlayLayerView);
//# sourceMappingURL=overlayLayerView.js.map