import { line, curveBundle } from 'd3';
import { Subject } from 'rxjs';
import { INVALIDATE_DROP } from './constants';
const STROKE_WIDTH = '3px';
const HIGHLIGHT_STROKE_WIDTH = '5px';
/**
 * Class that represents node relation path
 */
export class NodeRelationPath {
    /**
     * Occurs when this relation is being destroyed
     */
    get destroying() {
        return this.destroyingSubject.asObservable();
    }
    //######################### constructor #########################
    constructor(parentGroup, relationManager, history, start, end) {
        this.parentGroup = parentGroup;
        this.relationManager = relationManager;
        this.history = history;
        this.start = start;
        this.end = end;
        //######################### protected fields #########################
        /**
         * Subject used for emitting destroying event
         */
        this.destroyingSubject = new Subject();
        //######################### public properties #########################
        /**
         * Output from which relation start
         */
        this.output = null;
        /**
         * Input where relation ends
         */
        this.input = null;
        this.path = this.parentGroup.append('path')
            .attr('fill', 'transparent')
            .attr('stroke', '#48B8B8')
            .attr('stroke-width', STROKE_WIDTH)
            .on('mouseover', () => {
            this.highlight();
        })
            .on('mouseout', () => {
            this.cancelHighlight();
        });
        this.lineGenerator = line()
            .curve(curveBundle.beta(0.75));
    }
    //######################### public methods #########################
    /**
     * Method used for destroying this relation node
     */
    destroy() {
        var _a;
        (_a = this.path) === null || _a === void 0 ? void 0 : _a.remove();
        this.destroyingSubject.next();
    }
    /**
     * Highlights relation path and its input/output
     */
    highlight() {
        var _a, _b;
        this.path.attr('stroke-width', HIGHLIGHT_STROKE_WIDTH);
        (_a = this.input) === null || _a === void 0 ? void 0 : _a.highlight();
        (_b = this.output) === null || _b === void 0 ? void 0 : _b.highlight();
    }
    /**
     * Cancel hight for relation path
     */
    cancelHighlight() {
        var _a, _b;
        this.path.attr('stroke-width', STROKE_WIDTH);
        (_a = this.input) === null || _a === void 0 ? void 0 : _a.cancelHighlight();
        (_b = this.output) === null || _b === void 0 ? void 0 : _b.cancelHighlight();
    }
    /**
     * Explicitly runs invalidation of content (change detection)
     * @param propertyName - Name of property that has changed
     */
    invalidateVisuals(propertyName) {
        if (propertyName == INVALIDATE_DROP) {
            const activeInput = this.relationManager.getActiveInput();
            this.relationManager.setActiveInput(null);
            //drop not on input
            if (!activeInput) {
                this.destroy();
                this.start = null;
                this.end = null;
                this.input = null;
                this.output = null;
            }
            //drop on input peer
            else {
                if (activeInput.addRelation(this)) {
                    this.end = activeInput.getCoordinates();
                    this.input = activeInput;
                    this.history.getNewState();
                }
                else {
                    this.destroy();
                    this.start = null;
                    this.end = null;
                    this.input = null;
                    this.output = null;
                    this.history.getNewState();
                }
            }
        }
        if (!this.start || !this.end) {
            return;
        }
        let points;
        //path from right to left
        if (this.end.x <= this.start.x) {
            let width = this.start.x - this.end.x;
            const tenth = (this.end.y - this.start.y) / 10;
            if (width < 12) {
                width = 12;
            }
            width *= 1.3;
            points =
                [
                    [this.start.x, this.start.y],
                    [this.start.x + 40, this.start.y],
                    [this.start.x + width, this.start.y + tenth],
                    [this.end.x - width, this.start.y + (9 * tenth)],
                    [this.end.x - 40, this.end.y],
                    [this.end.x, this.end.y]
                ];
        }
        //path from left to right
        else {
            const width = this.end.x - this.start.x;
            const third = width / 3;
            points =
                [
                    [this.start.x, this.start.y],
                    [this.start.x + third, this.start.y],
                    [this.end.x - third, this.end.y],
                    [this.end.x, this.end.y]
                ];
        }
        this.path.attr('d', this.lineGenerator(points));
    }
}
//# sourceMappingURL=nodeRelationPath.js.map