import { NXComponent, AXComponent, AXValuableComponent, AXFocusableComponent } from '@acorex/cdk/common';
import * as i2 from '@acorex/components/button';
import { AXButtonModule } from '@acorex/components/button';
import * as i1 from '@acorex/components/text-box';
import { AXTextBoxModule } from '@acorex/components/text-box';
import * as i3 from '@angular/common';
import { CommonModule } from '@angular/common';
import * as i0 from '@angular/core';
import { inject, NgZone, signal, effect, Injectable, ViewEncapsulation, ChangeDetectionStrategy, Component, viewChild, output, afterNextRender, input, computed, HostListener, NgModule } from '@angular/core';
import * as i4 from '@angular/forms';
import { FormsModule } from '@angular/forms';
import { Subject } from 'rxjs';

class AXFlowChartService {
    constructor() {
        this.zone = inject(NgZone);
        this.initialFlowChartEdge = signal([], ...(ngDevMode ? [{ debugName: "initialFlowChartEdge" }] : []));
        this.initialFlowChartNode = signal([], ...(ngDevMode ? [{ debugName: "initialFlowChartNode" }] : []));
        this.selectedNode = signal(null, ...(ngDevMode ? [{ debugName: "selectedNode" }] : []));
        this.selectedEdge = signal(null, ...(ngDevMode ? [{ debugName: "selectedEdge" }] : []));
        this.svgService = signal(null, ...(ngDevMode ? [{ debugName: "svgService" }] : []));
        this.canvasService = signal(null, ...(ngDevMode ? [{ debugName: "canvasService" }] : []));
        this.lineClick = new Subject();
        this.lineDbClick = new Subject();
        this.nodeClick = new Subject();
        this.nodeDbClick = new Subject();
        this.onEdgeUpdate = new Subject();
        this.onNodeUpdate = new Subject();
        this.nodesMap = new Map();
        this.eventListeners = new Map();
        this.anchorClickBuffer = null;
        this.currentConnection = null;
        this.draggingConnection = false;
        this.tempLine = null;
        this.#eff2 = effect(() => {
            if (this.initialFlowChartEdge()) {
                setTimeout(() => {
                    this.drawEdges(this.initialFlowChartEdge());
                });
            }
        }, ...(ngDevMode ? [{ debugName: "#eff2" }] : []));
        this.#eff3 = effect(() => {
            if (this.initialFlowChartNode()) {
                this.createNode(this.initialFlowChartNode());
            }
        }, ...(ngDevMode ? [{ debugName: "#eff3" }] : []));
    }
    #eff2;
    #eff3;
    addEventListener(element, event, handler) {
        const elementId = element.dataset['id'] || 'global';
        if (!this.eventListeners.has(elementId)) {
            this.eventListeners.set(elementId, new Map());
        }
        const elementListeners = this.eventListeners.get(elementId);
        if (elementListeners) {
            const boundHandler = handler.bind(this);
            elementListeners.set(event, boundHandler);
            element.addEventListener(event, boundHandler);
        }
    }
    removeEventListeners(elementId) {
        const elementListeners = this.eventListeners.get(elementId);
        if (elementListeners) {
            elementListeners.forEach((handler, event) => {
                const element = this.nodesMap.get(elementId);
                if (element) {
                    element.removeEventListener(event, handler);
                }
            });
            this.eventListeners.delete(elementId);
        }
    }
    setupNodeEventListeners(el, node) {
        this.addEventListener(el, 'click', (e) => {
            this.nodeClick.next({ target: el, event: e });
            this.selectedNode.set(node);
            el.classList.add('selected');
            this.nodesMap.forEach((existingNode) => {
                if (existingNode !== el) {
                    existingNode.classList.remove('selected');
                }
            });
        });
        this.addEventListener(el, 'dblclick', (e) => {
            this.nodeDbClick.next({ target: el, event: e });
        });
        this.addEventListener(el, 'mouseenter', () => {
            el.classList.add('hover');
        });
        this.addEventListener(el, 'mouseleave', () => {
            el.classList.remove('hover');
        });
    }
    setupAnchorEventListeners(dot, el) {
        // start drag to connect
        this.addEventListener(dot, 'mousedown', (e) => {
            const mouseEvent = e;
            mouseEvent.stopPropagation();
            mouseEvent.preventDefault();
            const pos = this.getAnchorPoint(el, dot.dataset['anchor']);
            this.currentConnection = {
                source: {
                    id: dot.dataset['nodeId'],
                    anchor: dot.dataset['anchor'],
                },
                mouse: { x: mouseEvent.clientX, y: mouseEvent.clientY },
            };
            this.startTempLine(pos.x, pos.y);
            this.draggingConnection = true;
        });
        this.addEventListener(dot, 'click', (e) => {
            e.stopPropagation();
            if (dot.classList.contains('selected')) {
                dot.classList.remove('selected');
            }
            else {
                dot.classList.add('selected');
            }
            const clicked = {
                nodeId: dot.dataset['nodeId'],
                anchor: dot.dataset['anchor'],
            };
            console.log(clicked);
            if (!this.anchorClickBuffer) {
                this.anchorClickBuffer = clicked;
            }
            else {
                const source = this.anchorClickBuffer;
                const target = clicked;
                if (source.nodeId !== target.nodeId) {
                    this.pushAndCreateEdgeData({ id: source.nodeId, anchor: source.anchor }, { id: target.nodeId, anchor: target.anchor });
                }
                this.anchorClickBuffer = null;
            }
        });
        this.addEventListener(dot, 'mouseenter', () => {
            dot.classList.add('hover');
        });
        this.addEventListener(dot, 'mouseleave', () => {
            dot.classList.remove('hover');
        });
    }
    addAnchors(el, type) {
        ['top', 'bottom', 'left', 'right'].forEach((anchor) => {
            const dot = document.createElement('div');
            dot.className = 'ax-flow-chart-anchor';
            dot.dataset['anchor'] = anchor;
            dot.dataset['nodeId'] = el.dataset['id'];
            this.positionAnchor(dot, anchor, type);
            el.appendChild(dot);
            this.setupAnchorEventListeners(dot, el);
        });
    }
    makeDraggable(el) {
        let offsetX = 0, offsetY = 0, isDragging = false;
        this.addEventListener(el, 'mousedown', (e) => {
            const mouseEvent = e;
            if (mouseEvent.target.classList.contains('ax-flow-chart-anchor'))
                return;
            isDragging = true;
            offsetX = mouseEvent.clientX - el.offsetLeft;
            offsetY = mouseEvent.clientY - el.offsetTop;
            mouseEvent.preventDefault();
        });
        const mousemoveHandler = (e) => {
            if (isDragging) {
                el.style.left = e.clientX - offsetX + 'px';
                el.style.top = e.clientY - offsetY + 'px';
                this.drawEdges(this.initialFlowChartEdge());
                this.initialFlowChartNode.update((value) => {
                    const node = value.find((node) => node.id === el.dataset['id']);
                    if (node) {
                        node.x = e.clientX - offsetX;
                        node.y = e.clientY - offsetY;
                    }
                    return value;
                });
            }
            const elementId = e.target.id;
            if (elementId === 'ax-flow-chart-renderer-connections' || elementId === 'ax-flow-chart-renderer-canvas') {
                if (this.draggingConnection && this.tempLine) {
                    this.tempLine.setAttribute('x2', e.offsetX.toString());
                    this.tempLine.setAttribute('y2', e.offsetY.toString());
                }
            }
        };
        const mouseupHandler = (e) => {
            isDragging = false;
            if (this.draggingConnection) {
                const target = e.target.closest('.ax-flow-chart-anchor');
                if (target && target.dataset['nodeId'] !== this.currentConnection?.source?.id) {
                    this.currentConnection = {
                        ...this.currentConnection,
                        target: {
                            id: target.dataset['nodeId'],
                            anchor: target.dataset['anchor'],
                        },
                    };
                    this.finishConnection();
                }
                this.clearTempLine();
                this.draggingConnection = false;
            }
        };
        // Add global event listeners
        this.zone.runOutsideAngular(() => {
            document.addEventListener('mousemove', mousemoveHandler);
            document.addEventListener('mouseup', mouseupHandler);
        });
        // Store global listeners
        const globalListeners = this.eventListeners.get('global');
        if (globalListeners) {
            globalListeners.set('mousemove', mousemoveHandler);
            globalListeners.set('mouseup', mouseupHandler);
        }
    }
    positionAnchor(dot, anchor, type) {
        if (type !== 'diamond') {
            switch (anchor) {
                case 'top':
                    dot.style.top = '0%';
                    dot.style.left = '50%';
                    break;
                case 'bottom':
                    dot.style.top = '100%';
                    dot.style.left = '50%';
                    break;
                case 'left':
                    dot.style.top = '50%';
                    dot.style.left = '0%';
                    break;
                case 'right':
                    dot.style.top = '50%';
                    dot.style.left = '100%';
                    break;
            }
        }
        else {
            switch (anchor) {
                case 'top':
                    dot.style.top = '0%';
                    dot.style.left = '0%';
                    break;
                case 'bottom':
                    dot.style.top = '100%';
                    dot.style.left = '100%';
                    break;
                case 'left':
                    dot.style.top = '100%';
                    dot.style.left = '0%';
                    break;
                case 'right':
                    dot.style.top = '0%';
                    dot.style.left = '100%';
                    break;
            }
        }
    }
    getAnchorPoint(el, anchor) {
        const rect = el.getBoundingClientRect();
        const centerX = el.offsetLeft + rect.width / 2;
        const centerY = el.offsetTop + rect.height / 2;
        switch (anchor) {
            case 'top':
                return { x: centerX, y: el.offsetTop };
            case 'bottom':
                return { x: centerX, y: el.offsetTop + rect.height };
            case 'left':
                return { x: el.offsetLeft, y: centerY };
            case 'right':
                return { x: el.offsetLeft + rect.width, y: centerY };
            default:
                return { x: centerX, y: centerY };
        }
    }
    startTempLine(x, y) {
        const svgElement = this.svgService()?.nativeElement;
        if (!svgElement)
            return;
        this.tempLine = document.createElementNS('http://www.w3.org/2000/svg', 'line');
        this.tempLine.setAttribute('x1', x.toString());
        this.tempLine.setAttribute('y1', y.toString());
        this.tempLine.setAttribute('x2', x.toString());
        this.tempLine.setAttribute('y2', y.toString());
        this.tempLine.setAttribute('stroke', 'rgba(var(--ax-sys-color-on-lightest-surface),0.5)');
        this.tempLine.setAttribute('stroke-width', '2');
        this.tempLine.setAttribute('stroke-dasharray', '4');
        svgElement.appendChild(this.tempLine);
    }
    clearTempLine() {
        if (this.tempLine && this.tempLine.parentElement) {
            this.svgService()?.nativeElement.removeChild(this.tempLine);
            this.tempLine = null;
        }
    }
    pushAndCreateEdgeData(source, target) {
        const newEdge = {
            id: `edge-${Math.random().toString()}`,
            source,
            target,
        };
        this.onEdgeUpdate.next(newEdge);
        this.initialFlowChartEdge.update((value) => [...value, newEdge]);
        this.drawEdges();
    }
    drawEdges(edges) {
        const svg = this.svgService()?.nativeElement;
        if (!svg)
            return;
        // Clear existing edges
        svg.innerHTML = '';
        // Use provided edges or get from signal
        const edgesToDraw = edges || this.initialFlowChartEdge();
        edgesToDraw.forEach((edge) => {
            const sourceNode = this.nodesMap.get(edge.source.id);
            const targetNode = this.nodesMap.get(edge.target.id);
            if (sourceNode) {
                const sourceAnchor = sourceNode.querySelector(`[data-anchor="${edge.source.anchor}"]`);
                if (sourceAnchor)
                    sourceAnchor.classList.add('selected');
            }
            if (targetNode) {
                const targetAnchor = targetNode.querySelector(`[data-anchor="${edge.target.anchor}"]`);
                if (targetAnchor)
                    targetAnchor.classList.add('selected');
            }
            if (sourceNode && targetNode) {
                const sourcePoint = this.getAnchorPoint(sourceNode, edge.source.anchor);
                const targetPoint = this.getAnchorPoint(targetNode, edge.target.anchor);
                const line = this.createLine(sourcePoint, targetPoint, edge);
                line.classList.add('ax-flow-chart-line');
                // Add click event listener for line selection
                this.addEventListener(line, 'click', (e) => {
                    e.stopPropagation();
                    this.lineClick.next({ target: edge, event: e });
                    this.selectedEdge.set(edge);
                    this.selectedNode.set(null);
                    // Remove selection from all other lines
                    document.querySelectorAll('.ax-flow-chart-line').forEach((l) => {
                        if (l !== line)
                            l.classList.remove('selected');
                    });
                    // Add selection to clicked line
                    line.classList.add('selected');
                    // Remove selection from all nodes
                    this.nodesMap.forEach((node) => node.classList.remove('selected'));
                });
                svg.appendChild(line);
            }
        });
    }
    createLine(from, to, edge) {
        const line = document.createElementNS('http://www.w3.org/2000/svg', 'line');
        line.setAttribute('x1', from.x.toString());
        line.setAttribute('y1', from.y.toString());
        line.setAttribute('x2', to.x.toString());
        line.setAttribute('y2', to.y.toString());
        line.setAttribute('stroke', 'rgba(var(--ax-sys-color-on-surface))');
        line.setAttribute('stroke-width', '3');
        line.classList.add('ax-flow-chart-line');
        line.addEventListener('click', (e) => {
            this.lineClick.next({ target: edge, event: e });
            this.selectedEdge.set(edge);
        });
        line.addEventListener('dblclick', (e) => {
            this.lineDbClick.next({ target: edge, event: e });
        });
        return line;
    }
    finishConnection() {
        if (this.currentConnection?.source && this.currentConnection?.target) {
            this.pushAndCreateEdgeData(this.currentConnection.source, this.currentConnection.target);
        }
        this.currentConnection = null;
    }
    removeEdge(edge) {
        this.initialFlowChartEdge.update((value) => value.filter((e) => e.id !== edge.id));
        // Remove selected class from connected anchors
        const sourceNode = this.nodesMap.get(edge.source.id);
        const targetNode = this.nodesMap.get(edge.target.id);
        if (sourceNode) {
            const sourceAnchor = sourceNode.querySelector(`[data-anchor="${edge.source.anchor}"]`);
            if (sourceAnchor)
                sourceAnchor.classList.remove('selected');
        }
        if (targetNode) {
            const targetAnchor = targetNode.querySelector(`[data-anchor="${edge.target.anchor}"]`);
            if (targetAnchor)
                targetAnchor.classList.remove('selected');
        }
    }
    createNode(nodes) {
        document.querySelectorAll('.ax-flow-chart-node')?.forEach((node) => node.remove());
        nodes.forEach((node) => {
            const el = document.createElement('div');
            const p = document.createElement('p');
            p.innerText = node.label;
            el.appendChild(p);
            el.className = 'ax-flow-chart-node';
            el.classList.add(`ax-${node.type}`);
            el.style.left = node.x + 'px';
            el.style.top = node.y + 'px';
            el.dataset['id'] = node.id;
            this.addAnchors(el, node.type);
            this.makeDraggable(el);
            this.setupNodeEventListeners(el, node);
            this.canvasService().nativeElement.appendChild(el);
            this.nodesMap.set(node.id, el);
        });
    }
    removeNode(nodeId) {
        this.initialFlowChartNode.update((value) => value.filter((e) => e.id !== nodeId));
        this.initialFlowChartEdge().forEach((edge) => {
            if (edge.source.id === nodeId || edge.target.id === nodeId) {
                this.removeEdge(edge);
            }
        });
        document.querySelector(`[data-id="${nodeId}"]`)?.remove();
        this.anchorClickBuffer = null;
    }
    cleanup() {
        this.nodesMap.forEach((_, id) => this.removeEventListeners(id));
        this.nodesMap.clear();
        this.eventListeners.clear();
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: AXFlowChartService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
    static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: AXFlowChartService }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: AXFlowChartService, decorators: [{
            type: Injectable
        }] });

class AXFlowChartCreatorComponent extends NXComponent {
    constructor() {
        super(...arguments);
        this.service = inject(AXFlowChartService);
        this.selectedShape = signal('rectangle', ...(ngDevMode ? [{ debugName: "selectedShape" }] : []));
        this.label = 'Label';
    }
    selectShapeHandler(shape) {
        this.selectedShape.set(shape);
    }
    createShapeHandler() {
        const newNode = {
            id: Math.random().toString(),
            type: this.selectedShape(),
            label: this.label,
            x: 0,
            y: 0,
        };
        this.service.initialFlowChartNode.update((value) => [...value, newNode]);
        this.service.onNodeUpdate.next(newNode);
    }
    printChart() {
        const printWindow = window.open('', '_blank');
        if (!printWindow)
            return;
        const canvas = this.service.canvasService()?.nativeElement;
        if (!canvas)
            return;
        // Get all styles from the document and component
        const styles = Array.from(document.styleSheets)
            .map((sheet) => {
            try {
                return Array.from(sheet.cssRules)
                    .map((rule) => rule.cssText)
                    .join('\n');
            }
            catch (e) {
                return '';
            }
        })
            .join('\n');
        // Add print-specific styles for anchors
        const printStyles = `
      ${styles}
      .ax-flow-chart-anchor {
        opacity: 1 !important;
      }
    `;
        // Create the print content with proper styling
        const printContent = `
      <!DOCTYPE html>
      <html>
        <head>
          <title>Flow Chart Print</title>
          <style>
            ${printStyles}
          </style>
        </head>
        <body>
          <ax-flow-chart-renderer>
            ${canvas.outerHTML}
          </ax-flow-chart-renderer>
        </body>
      </html>
    `;
        printWindow.document.write(printContent);
        printWindow.document.close();
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: AXFlowChartCreatorComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.9", type: AXFlowChartCreatorComponent, isStandalone: true, selector: "ax-flow-chart-creator", providers: [{ provide: AXComponent, useExisting: AXFlowChartCreatorComponent }], usesInheritance: true, ngImport: i0, template: "<div class=\"ax-shape-container\">\n  <div\n    [ngClass]=\"{ 'ax-shape-selected': selectedShape() === 'rectangle' }\"\n    (click)=\"selectShapeHandler('rectangle')\"\n    class=\"ax-rectangle\"\n  ></div>\n  <div\n    [ngClass]=\"{ 'ax-shape-selected': selectedShape() === 'circle' }\"\n    (click)=\"selectShapeHandler('circle')\"\n    class=\"ax-circle\"\n  ></div>\n  <div\n    [ngClass]=\"{ 'ax-shape-selected': selectedShape() === 'diamond' }\"\n    (click)=\"selectShapeHandler('diamond')\"\n    class=\"ax-diamond\"\n  ></div>\n</div>\n<ax-text-box class=\"ax-sm\" [(ngModel)]=\"label\" placeholder=\"Label\"> </ax-text-box>\n\n<ax-button class=\"ax-sm\" (onClick)=\"createShapeHandler()\" color=\"primary\" text=\"Create\"></ax-button>\n<ax-button color=\"primary\" text=\"Print\" class=\"ax-sm\" (click)=\"printChart()\"></ax-button>\n", styles: ["ax-flow-chart-creator{display:flex;gap:1rem;align-items:center;padding:1rem}ax-flow-chart-creator .ax-shape-container{display:flex;gap:1rem}ax-flow-chart-creator .ax-shape-container .ax-shape-selected{border:2px solid rgba(var(--ax-sys-color-danger-darker-surface))!important}ax-flow-chart-creator .ax-shape-container .ax-rectangle,ax-flow-chart-creator .ax-shape-container .ax-circle,ax-flow-chart-creator .ax-shape-container .ax-diamond{border:2px solid rgba(var(--ax-sys-color-border-surface));display:flex;justify-content:center;align-items:center;width:30px;height:30px;cursor:pointer}ax-flow-chart-creator .ax-shape-container .ax-circle{border-radius:1000vmax;aspect-ratio:1}ax-flow-chart-creator .ax-shape-container .ax-diamond{transform:rotate(45deg) scale(.75);aspect-ratio:1}\n"], dependencies: [{ kind: "ngmodule", type: AXTextBoxModule }, { kind: "component", type: i1.AXTextBoxComponent, selector: "ax-text-box", inputs: ["disabled", "tabIndex", "readonly", "value", "state", "name", "id", "placeholder", "maxLength", "allowNull", "type", "autoComplete", "look", "mask-options", "class"], outputs: ["onBlur", "onFocus", "valueChange", "stateChange", "onValueChanged", "readonlyChange", "disabledChange", "onKeyDown", "onKeyUp", "onKeyPress"] }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i2.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: AXFlowChartCreatorComponent, decorators: [{
            type: Component,
            args: [{ selector: 'ax-flow-chart-creator', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, imports: [AXTextBoxModule, AXButtonModule, CommonModule, FormsModule], providers: [{ provide: AXComponent, useExisting: AXFlowChartCreatorComponent }], template: "<div class=\"ax-shape-container\">\n  <div\n    [ngClass]=\"{ 'ax-shape-selected': selectedShape() === 'rectangle' }\"\n    (click)=\"selectShapeHandler('rectangle')\"\n    class=\"ax-rectangle\"\n  ></div>\n  <div\n    [ngClass]=\"{ 'ax-shape-selected': selectedShape() === 'circle' }\"\n    (click)=\"selectShapeHandler('circle')\"\n    class=\"ax-circle\"\n  ></div>\n  <div\n    [ngClass]=\"{ 'ax-shape-selected': selectedShape() === 'diamond' }\"\n    (click)=\"selectShapeHandler('diamond')\"\n    class=\"ax-diamond\"\n  ></div>\n</div>\n<ax-text-box class=\"ax-sm\" [(ngModel)]=\"label\" placeholder=\"Label\"> </ax-text-box>\n\n<ax-button class=\"ax-sm\" (onClick)=\"createShapeHandler()\" color=\"primary\" text=\"Create\"></ax-button>\n<ax-button color=\"primary\" text=\"Print\" class=\"ax-sm\" (click)=\"printChart()\"></ax-button>\n", styles: ["ax-flow-chart-creator{display:flex;gap:1rem;align-items:center;padding:1rem}ax-flow-chart-creator .ax-shape-container{display:flex;gap:1rem}ax-flow-chart-creator .ax-shape-container .ax-shape-selected{border:2px solid rgba(var(--ax-sys-color-danger-darker-surface))!important}ax-flow-chart-creator .ax-shape-container .ax-rectangle,ax-flow-chart-creator .ax-shape-container .ax-circle,ax-flow-chart-creator .ax-shape-container .ax-diamond{border:2px solid rgba(var(--ax-sys-color-border-surface));display:flex;justify-content:center;align-items:center;width:30px;height:30px;cursor:pointer}ax-flow-chart-creator .ax-shape-container .ax-circle{border-radius:1000vmax;aspect-ratio:1}ax-flow-chart-creator .ax-shape-container .ax-diamond{transform:rotate(45deg) scale(.75);aspect-ratio:1}\n"] }]
        }] });

class AXFlowChartRendererComponent extends NXComponent {
    constructor() {
        super(...arguments);
        this.canvas = viewChild('canvas', ...(ngDevMode ? [{ debugName: "canvas" }] : []));
        this.svg = viewChild('connections', ...(ngDevMode ? [{ debugName: "svg" }] : []));
        this.service = inject(AXFlowChartService);
        this.onLineClick = output();
        this.onLineDbClick = output();
        this.onNodeClick = output();
        this.onNodeDbClick = output();
        this.onEdgeUpdate = output();
        this.onNodeUpdate = output();
        this.#init = afterNextRender(() => {
            this.setupEventListeners();
        });
        this.#eff = effect(() => {
            if (this.canvas() && this.svg()) {
                this.initializeServices();
            }
        }, ...(ngDevMode ? [{ debugName: "#eff" }] : []));
    }
    #init;
    #eff;
    setupEventListeners() {
        this.service.lineClick.subscribe((value) => {
            this.onLineClick.emit(value);
        });
        this.service.lineDbClick.subscribe((value) => {
            this.onLineDbClick.emit(value);
        });
        this.service.nodeClick.subscribe((value) => {
            this.onNodeClick.emit(value);
        });
        this.service.nodeDbClick.subscribe((value) => {
            this.onNodeDbClick.emit(value);
        });
        this.service.onEdgeUpdate.subscribe((newEdge) => {
            this.onEdgeUpdate.emit(newEdge);
        });
        this.service.onNodeUpdate.subscribe((newNode) => {
            this.onNodeUpdate.emit(newNode);
        });
    }
    initializeServices() {
        this.service.canvasService.set(this.canvas());
        this.service.svgService.set(this.svg());
        // Add click handlers for parent elements
        const canvas = this.canvas()?.nativeElement;
        const svg = this.svg()?.nativeElement;
        if (canvas) {
            canvas.addEventListener('click', (e) => {
                if (e.target === canvas) {
                    this.service.selectedNode.set(null);
                    this.service.selectedEdge.set(null);
                    document.querySelectorAll('.ax-flow-chart-node').forEach((node) => node.classList.remove('selected'));
                    document.querySelectorAll('.ax-flow-chart-line').forEach((line) => line.classList.remove('selected'));
                }
            });
        }
        if (svg) {
            svg.addEventListener('click', (e) => {
                if (e.target === svg) {
                    this.service.selectedNode.set(null);
                    this.service.selectedEdge.set(null);
                    document.querySelectorAll('.ax-flow-chart-node').forEach((node) => node.classList.remove('selected'));
                    document.querySelectorAll('.ax-flow-chart-line').forEach((line) => line.classList.remove('selected'));
                }
            });
        }
    }
    ngOnDestroy() {
        this.cleanup();
    }
    cleanup() {
        this.service.cleanup();
        this.service.lineClick.unsubscribe();
        this.service.lineDbClick.unsubscribe();
        this.service.nodeClick.unsubscribe();
        this.service.nodeDbClick.unsubscribe();
        this.service.onEdgeUpdate.unsubscribe();
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: AXFlowChartRendererComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "20.3.9", type: AXFlowChartRendererComponent, isStandalone: true, selector: "ax-flow-chart-renderer", outputs: { onLineClick: "onLineClick", onLineDbClick: "onLineDbClick", onNodeClick: "onNodeClick", onNodeDbClick: "onNodeDbClick", onEdgeUpdate: "onEdgeUpdate", onNodeUpdate: "onNodeUpdate" }, providers: [{ provide: AXComponent, useExisting: AXFlowChartRendererComponent }], viewQueries: [{ propertyName: "canvas", first: true, predicate: ["canvas"], descendants: true, isSignal: true }, { propertyName: "svg", first: true, predicate: ["connections"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<div id=\"ax-flow-chart-renderer-canvas\" #canvas>\n  <svg class=\"ax-flow-chart-renderer-svg\" id=\"ax-flow-chart-renderer-connections\" #connections></svg>\n</div>\n", styles: ["ax-flow-chart-renderer{overflow:hidden;width:var(--ax-comp-flow-chart-width, 100%);height:var(--ax-comp-flow-chart-height, 30rem);-webkit-print-color-adjust:exact;print-color-adjust:exact}ax-flow-chart-renderer #ax-flow-chart-renderer-canvas{position:relative;width:100%;height:100%}ax-flow-chart-renderer .ax-flow-chart-node{position:absolute;padding:1rem;background-color:rgba(var(--ax-sys-color-surface));color:rgba(var(--ax-sys-color-on-surface));border:2px solid rgba(var(--ax-sys-color-border-surface));cursor:move;-webkit-user-select:none;user-select:none}ax-flow-chart-renderer .ax-flow-chart-node.selected{border:2px solid rgba(var(--ax-sys-color-danger-darker-surface))}ax-flow-chart-renderer .ax-flow-chart-node .ax-flow-chart-anchor{opacity:0;transition:opacity .5s ease}ax-flow-chart-renderer .ax-flow-chart-node:hover .ax-flow-chart-anchor,ax-flow-chart-renderer .ax-flow-chart-node.selected .ax-flow-chart-anchor{opacity:1}ax-flow-chart-renderer .ax-flow-chart-anchor{position:absolute;width:10px;height:10px;background-color:rgba(var(--ax-sys-color-on-lightest-surface));border-radius:50%;cursor:crosshair;transform:translate(-50%,-50%)}ax-flow-chart-renderer .ax-flow-chart-anchor.selected{background-color:rgba(var(--ax-sys-color-primary-surface))}ax-flow-chart-renderer .ax-flow-chart-anchor.hover{transition:.3s all ease;scale:1.3;background-color:rgba(var(--ax-sys-color-danger-darkest-surface))}ax-flow-chart-renderer .ax-flow-chart-anchor:before{content:\"\";position:absolute;top:-7px;left:-7px;right:-7px;bottom:-7px}ax-flow-chart-renderer .ax-flow-chart-renderer-svg{position:absolute;top:0;left:0;overflow:visible}ax-flow-chart-renderer .ax-flow-chart-line:hover{transition:.3s all ease;stroke:rgba(var(--ax-sys-color-danger-darker-surface));cursor:pointer}ax-flow-chart-renderer .ax-flow-chart-line.selected{stroke:rgba(var(--ax-sys-color-primary-surface))}ax-flow-chart-renderer .ax-rectangle,ax-flow-chart-renderer .ax-circle,ax-flow-chart-renderer .ax-diamond{border:2px solid rgba(var(--ax-sys-color-border-surface));display:flex;justify-content:center;align-items:center;width:auto;height:auto}ax-flow-chart-renderer .ax-circle{border-radius:1000vmax;aspect-ratio:1}ax-flow-chart-renderer .ax-diamond{transform:rotate(45deg) scale(.75);aspect-ratio:1}ax-flow-chart-renderer .ax-diamond p{transform:rotate(-45deg) scale(1.25)}ax-flow-chart-renderer .ax-diamond .ax-flow-chart-anchor{width:14px;height:14px}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: AXFlowChartRendererComponent, decorators: [{
            type: Component,
            args: [{ selector: 'ax-flow-chart-renderer', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, providers: [{ provide: AXComponent, useExisting: AXFlowChartRendererComponent }], template: "<div id=\"ax-flow-chart-renderer-canvas\" #canvas>\n  <svg class=\"ax-flow-chart-renderer-svg\" id=\"ax-flow-chart-renderer-connections\" #connections></svg>\n</div>\n", styles: ["ax-flow-chart-renderer{overflow:hidden;width:var(--ax-comp-flow-chart-width, 100%);height:var(--ax-comp-flow-chart-height, 30rem);-webkit-print-color-adjust:exact;print-color-adjust:exact}ax-flow-chart-renderer #ax-flow-chart-renderer-canvas{position:relative;width:100%;height:100%}ax-flow-chart-renderer .ax-flow-chart-node{position:absolute;padding:1rem;background-color:rgba(var(--ax-sys-color-surface));color:rgba(var(--ax-sys-color-on-surface));border:2px solid rgba(var(--ax-sys-color-border-surface));cursor:move;-webkit-user-select:none;user-select:none}ax-flow-chart-renderer .ax-flow-chart-node.selected{border:2px solid rgba(var(--ax-sys-color-danger-darker-surface))}ax-flow-chart-renderer .ax-flow-chart-node .ax-flow-chart-anchor{opacity:0;transition:opacity .5s ease}ax-flow-chart-renderer .ax-flow-chart-node:hover .ax-flow-chart-anchor,ax-flow-chart-renderer .ax-flow-chart-node.selected .ax-flow-chart-anchor{opacity:1}ax-flow-chart-renderer .ax-flow-chart-anchor{position:absolute;width:10px;height:10px;background-color:rgba(var(--ax-sys-color-on-lightest-surface));border-radius:50%;cursor:crosshair;transform:translate(-50%,-50%)}ax-flow-chart-renderer .ax-flow-chart-anchor.selected{background-color:rgba(var(--ax-sys-color-primary-surface))}ax-flow-chart-renderer .ax-flow-chart-anchor.hover{transition:.3s all ease;scale:1.3;background-color:rgba(var(--ax-sys-color-danger-darkest-surface))}ax-flow-chart-renderer .ax-flow-chart-anchor:before{content:\"\";position:absolute;top:-7px;left:-7px;right:-7px;bottom:-7px}ax-flow-chart-renderer .ax-flow-chart-renderer-svg{position:absolute;top:0;left:0;overflow:visible}ax-flow-chart-renderer .ax-flow-chart-line:hover{transition:.3s all ease;stroke:rgba(var(--ax-sys-color-danger-darker-surface));cursor:pointer}ax-flow-chart-renderer .ax-flow-chart-line.selected{stroke:rgba(var(--ax-sys-color-primary-surface))}ax-flow-chart-renderer .ax-rectangle,ax-flow-chart-renderer .ax-circle,ax-flow-chart-renderer .ax-diamond{border:2px solid rgba(var(--ax-sys-color-border-surface));display:flex;justify-content:center;align-items:center;width:auto;height:auto}ax-flow-chart-renderer .ax-circle{border-radius:1000vmax;aspect-ratio:1}ax-flow-chart-renderer .ax-diamond{transform:rotate(45deg) scale(.75);aspect-ratio:1}ax-flow-chart-renderer .ax-diamond p{transform:rotate(-45deg) scale(1.25)}ax-flow-chart-renderer .ax-diamond .ax-flow-chart-anchor{width:14px;height:14px}\n"] }]
        }], propDecorators: { canvas: [{ type: i0.ViewChild, args: ['canvas', { isSignal: true }] }], svg: [{ type: i0.ViewChild, args: ['connections', { isSignal: true }] }], onLineClick: [{ type: i0.Output, args: ["onLineClick"] }], onLineDbClick: [{ type: i0.Output, args: ["onLineDbClick"] }], onNodeClick: [{ type: i0.Output, args: ["onNodeClick"] }], onNodeDbClick: [{ type: i0.Output, args: ["onNodeDbClick"] }], onEdgeUpdate: [{ type: i0.Output, args: ["onEdgeUpdate"] }], onNodeUpdate: [{ type: i0.Output, args: ["onNodeUpdate"] }] } });

class AXFlowChartComponent extends NXComponent {
    constructor() {
        super(...arguments);
        this.flowChartService = inject(AXFlowChartService);
        this.initialFlowChartNode = input.required(...(ngDevMode ? [{ debugName: "initialFlowChartNode" }] : []));
        this.initialFlowChartEdge = input.required(...(ngDevMode ? [{ debugName: "initialFlowChartEdge" }] : []));
        this.selectedNode = computed(() => this.flowChartService.selectedNode(), ...(ngDevMode ? [{ debugName: "selectedNode" }] : []));
        this.selectedEdge = computed(() => this.flowChartService.selectedEdge(), ...(ngDevMode ? [{ debugName: "selectedEdge" }] : []));
        this.#init = afterNextRender(() => {
            this.flowChartService.initialFlowChartNode.set(this.initialFlowChartNode());
            this.flowChartService.initialFlowChartEdge.set(this.initialFlowChartEdge());
        });
    }
    #init;
    handleKeyboardEvent(event) {
        if (event.key === 'Delete') {
            const selectedNode = this.selectedNode();
            const selectedEdge = this.selectedEdge();
            if (selectedNode) {
                this.removeNode(selectedNode.id);
            }
            else if (selectedEdge) {
                this.removeEdge(selectedEdge);
            }
        }
    }
    /**
     * Draws edges on the flow chart.
     *
     * @param edges Array of edges to draw.
     * @returns void
     */
    drawEdges(edges) {
        this.flowChartService.drawEdges(edges);
    }
    /**
     * Removes a specific edge from the flow chart.
     *
     * @param edge The edge object to remove.
     * @returns void
     */
    removeEdge(edge) {
        this.flowChartService.removeEdge(edge);
    }
    /**
     * Creates one or more nodes on the flow chart.
     *
     * @param nodes Array of node definitions to create.
     * @returns void
     */
    createNode(nodes) {
        this.flowChartService.createNode(nodes);
    }
    /**
     * Removes a node by its identifier.
     *
     * @param nodeId The unique id of the node to remove.
     * @returns void
     */
    removeNode(nodeId) {
        this.flowChartService.removeNode(nodeId);
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: AXFlowChartComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.3.9", type: AXFlowChartComponent, isStandalone: true, selector: "ax-flow-chart", inputs: { initialFlowChartNode: { classPropertyName: "initialFlowChartNode", publicName: "initialFlowChartNode", isSignal: true, isRequired: true, transformFunction: null }, initialFlowChartEdge: { classPropertyName: "initialFlowChartEdge", publicName: "initialFlowChartEdge", isSignal: true, isRequired: true, transformFunction: null } }, host: { listeners: { "document:keydown": "handleKeyboardEvent($event)" } }, providers: [
            AXFlowChartService,
            { provide: AXComponent, useExisting: AXFlowChartComponent },
            { provide: AXValuableComponent, useExisting: AXFlowChartComponent },
            { provide: AXFocusableComponent, useExisting: AXFlowChartComponent },
        ], usesInheritance: true, ngImport: i0, template: "<ng-content select=\"ax-header\"></ng-content>\n<ng-content select=\"ax-flow-chart-renderer\"></ng-content>\n<ng-content select=\"ax-footer\"></ng-content>\n", styles: ["ax-flow-chart{display:flex;flex-direction:column;width:100%;height:100%;border:1px solid rgba(var(--ax-sys-color-border-lightest-surface));border-radius:var(--ax-sys-border-radius)}ax-flow-chart ax-header{border-bottom:1px solid rgba(var(--ax-sys-color-border-lightest-surface))}ax-flow-chart ax-footer{border-top:1px solid rgba(var(--ax-sys-color-border-lightest-surface))}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: AXFlowChartComponent, decorators: [{
            type: Component,
            args: [{ selector: 'ax-flow-chart', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, providers: [
                        AXFlowChartService,
                        { provide: AXComponent, useExisting: AXFlowChartComponent },
                        { provide: AXValuableComponent, useExisting: AXFlowChartComponent },
                        { provide: AXFocusableComponent, useExisting: AXFlowChartComponent },
                    ], template: "<ng-content select=\"ax-header\"></ng-content>\n<ng-content select=\"ax-flow-chart-renderer\"></ng-content>\n<ng-content select=\"ax-footer\"></ng-content>\n", styles: ["ax-flow-chart{display:flex;flex-direction:column;width:100%;height:100%;border:1px solid rgba(var(--ax-sys-color-border-lightest-surface));border-radius:var(--ax-sys-border-radius)}ax-flow-chart ax-header{border-bottom:1px solid rgba(var(--ax-sys-color-border-lightest-surface))}ax-flow-chart ax-footer{border-top:1px solid rgba(var(--ax-sys-color-border-lightest-surface))}\n"] }]
        }], propDecorators: { initialFlowChartNode: [{ type: i0.Input, args: [{ isSignal: true, alias: "initialFlowChartNode", required: true }] }], initialFlowChartEdge: [{ type: i0.Input, args: [{ isSignal: true, alias: "initialFlowChartEdge", required: true }] }], handleKeyboardEvent: [{
                type: HostListener,
                args: ['document:keydown', ['$event']]
            }] } });

const COMPONENT = [AXFlowChartRendererComponent, AXFlowChartCreatorComponent, AXFlowChartComponent];
const MODULES = [CommonModule];
class AXFlowChartModule {
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: AXFlowChartModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
    static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.9", ngImport: i0, type: AXFlowChartModule, imports: [CommonModule, AXFlowChartRendererComponent, AXFlowChartCreatorComponent, AXFlowChartComponent], exports: [AXFlowChartRendererComponent, AXFlowChartCreatorComponent, AXFlowChartComponent] }); }
    static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: AXFlowChartModule, imports: [MODULES, AXFlowChartCreatorComponent] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: AXFlowChartModule, decorators: [{
            type: NgModule,
            args: [{
                    imports: [...MODULES, ...COMPONENT],
                    exports: [...COMPONENT],
                    providers: [],
                }]
        }] });

/**
 * Generated bundle index. Do not edit.
 */

export { AXFlowChartComponent, AXFlowChartCreatorComponent, AXFlowChartModule, AXFlowChartRendererComponent };
//# sourceMappingURL=acorex-components-flow-chart.mjs.map
