import { Component, ChangeDetectionStrategy, HostListener } from '@angular/core';
import { RelationNodeEndpointBase } from '../relationsNodeEndpointBase';
import { INVALIDATE_DROP } from '../../misc/constants';
import * as i0 from "@angular/core";
//TODO: optimize window events, do not register for all time
/**
 * Component used to display relation node output
 */
export class RelationNodeOutputSAComponent extends RelationNodeEndpointBase {
    constructor() {
        super(...arguments);
        //######################### protected properties #########################
        /**
         * Relations
         */
        this.ɵrelations = [];
    }
    //######################### public properties - implementation of RelationsOutput #########################
    /**
     * @inheritdoc
     */
    get relations() {
        return this.ɵrelations;
    }
    //######################### public methods - implementation of OnDestroy #########################
    /**
     * Called when component is destroyed
     */
    ngOnDestroy() {
        if (this.ɵrelations) {
            const relations = [...this.ɵrelations];
            for (const relation of relations) {
                relation.destroy();
            }
        }
        this.canvasPositionChangeSubscription?.unsubscribe();
        this.canvasPositionChangeSubscription = null;
    }
    //######################### public methods - implementation of RelationsOutput #########################
    /**
     * @inheritdoc
     */
    startRelation() {
        const relation = this.canvas.createRelation();
        relation.start = this.getCoordinates();
        relation.output = this;
        relation.destroying.subscribe(() => {
            const index = this.ɵrelations.indexOf(relation);
            if (index >= 0) {
                this.ɵrelations.splice(index, 1);
            }
        });
        this.ɵrelations.push(relation);
        return relation;
    }
    //######################### public methods - overrides #########################
    /**
     * Updates node output relations
     */
    updateRelation() {
        if (!this.ɵrelations) {
            return;
        }
        for (const relation of this.ɵrelations) {
            relation.start = this.getCoordinates();
            relation.invalidateVisuals();
        }
    }
    //######################### protected methods - host listeners #########################
    /**
     * Mouse down event, creates new relation
     * @param event - Mouse event that occured
     */
    _onMouseDown(event) {
        event.stopImmediatePropagation();
        event.preventDefault();
        this.isDragging = true;
        this.canvasPositionChangeSubscription = this.canvas?.convasPositionChanged.subscribe(() => {
            if (this.relation) {
                this.relation.end = this.canvas.getPositionInCanvas({ x: this.lastMouseMovePosition.x, y: this.lastMouseMovePosition.y });
                this.relation.invalidateVisuals();
            }
        });
        this.relation = this.startRelation();
    }
    /**
     * Mouse enter event, marks input as active
     * @param event - Mouse event that occured
     */
    _onMouseEnter(_) {
        this.ɵrelations?.forEach(relation => relation?.highlight());
    }
    /**
     * Mouse leave event, clears marked active input
     * @param event - Mouse event that occured
     */
    _onMouseLeave(_) {
        this.ɵrelations?.forEach(relation => relation?.cancelHighlight());
    }
    /**
     * Mouse move event - whole window
     * @param event - Mouse event that occured
     */
    _onMouseMove(event) {
        if (this.isDragging) {
            event.stopImmediatePropagation();
            event.preventDefault();
            this.lastMouseMovePosition =
                {
                    x: event.clientX,
                    y: event.clientY
                };
            if (this.relation) {
                this.relation.end = this.canvas.getPositionInCanvas({ x: this.lastMouseMovePosition.x, y: this.lastMouseMovePosition.y });
                this.relation.invalidateVisuals();
            }
        }
    }
    /**
     * Mouse up event - whole window
     * @param event - Mouse event that occured
     */
    _onMouseUp(event) {
        if (this.isDragging) {
            this.isDragging = false;
            this.canvasPositionChangeSubscription?.unsubscribe();
            this.canvasPositionChangeSubscription = null;
            event.stopImmediatePropagation();
            event.preventDefault();
            this.relation?.invalidateVisuals(INVALIDATE_DROP);
        }
    }
}
RelationNodeOutputSAComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.4", ngImport: i0, type: RelationNodeOutputSAComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
RelationNodeOutputSAComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.0.4", type: RelationNodeOutputSAComponent, isStandalone: true, selector: "relation-node-output", host: { listeners: { "mousedown": "_onMouseDown($event)", "mouseenter": "_onMouseEnter($event)", "mouseleave": "_onMouseLeave($event)", "window:mousemove": "_onMouseMove($event)", "window:mouseup": "_onMouseUp($event)" } }, usesInheritance: true, ngImport: i0, template: '', isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.4", ngImport: i0, type: RelationNodeOutputSAComponent, decorators: [{
            type: Component,
            args: [{
                    selector: 'relation-node-output',
                    template: '',
                    standalone: true,
                    changeDetection: ChangeDetectionStrategy.OnPush
                }]
        }], propDecorators: { _onMouseDown: [{
                type: HostListener,
                args: ['mousedown', ['$event']]
            }], _onMouseEnter: [{
                type: HostListener,
                args: ['mouseenter', ['$event']]
            }], _onMouseLeave: [{
                type: HostListener,
                args: ['mouseleave', ['$event']]
            }], _onMouseMove: [{
                type: HostListener,
                args: ['window:mousemove', ['$event']]
            }], _onMouseUp: [{
                type: HostListener,
                args: ['window:mouseup', ['$event']]
            }] } });
//# sourceMappingURL=relationsNodeOutput.component.js.map