import { Queue } from 'queue-typescript';
export class Shape {
    //  Constructor taking the ID and the curve of the shape.
    constructor(boundaryCurve = null) {
        this.parents = new Set();
        this.children = new Set();
        this.ports = new Set();
        this.BoundaryCurve = boundaryCurve;
    }
    get Parents() {
        return Array.from(this.parents.values());
    }
    get Children() {
        return Array.from(this.children.values());
    }
    get BoundaryCurve() {
        return this.boundaryCurve;
    }
    set BoundaryCurve(value) {
        this.boundaryCurve = value;
    }
    //  The bounding box of the shape.
    get BoundingBox() {
        return this.BoundaryCurve.boundingBox;
    }
    //  The set of Ports for this obstacle, usually RelativePorts.  In the event of overlapping
    //  obstacles, this identifies the obstacle to which the port applies.
    get Ports() {
        return this.ports;
    }
    //  Default constructor.
    static mkShape() {
        return new Shape(null);
    }
    //  A group is a shape that has children.
    get IsGroup() {
        return this.children.size > 0;
    }
    *Descendants() {
        const q = new Queue();
        for (const shape of this.Children) {
            q.enqueue(shape);
        }
        while (q.length > 0) {
            const sh = q.dequeue();
            yield sh;
            for (const shape of sh.Children) {
                q.enqueue(shape);
            }
        }
    }
    *Ancestors() {
        const q = new Queue();
        for (const shape of this.Parents) {
            q.enqueue(shape);
        }
        while (q.length > 0) {
            const sh = q.dequeue();
            yield sh;
            for (const shape of sh.Parents) {
                q.enqueue(shape);
            }
        }
    }
    //  Adds a parent. A shape can have several parents
    AddParent(shape) {
        this.parents.add(shape);
        shape.children.add(this);
    }
    AddChild(shape) {
        shape.parents.add(this);
        this.children.add(shape);
    }
    //
    RemoveChild(shape) {
        this.children.delete(shape);
        shape.parents.delete(this);
    }
    //
    RemoveParent(shape) {
        this.parents.delete(shape);
        shape.children.delete(this);
    }
    //
    ToString() {
        return this.UserData ? this.UserData.toString() : 'null';
    }
}
//# sourceMappingURL=shape.js.map