/*
THIS INFRAGISTICS ULTIMATE SOFTWARE LICENSE  AGREEMENT ("AGREEMENT") LOCATED HERE:
https://www.infragistics.com/legal/license/igultimate-la
https://www.infragistics.com/legal/license/igultimate-eula
GOVERNS THE LICENSING, INSTALLATION AND USE OF INFRAGISTICS SOFTWARE. BY DOWNLOADING AND/OR INSTALLING AND USING INFRAGISTICS SOFTWARE:  you are indicating that you have read and understand this Agreement, and agree to be legally bound by it on behalf of the yourself and your company.
*/
import { List$1 } from "./List$1";
import { LabelCollisionPlacementPositions_$type } from "./LabelCollisionPlacementPositions";
import { LabelInfo } from "./LabelInfo";
import { QuadTree } from "./QuadTree";
import { LinkedList$1 } from "./LinkedList$1";
import { QuadTreeBoundingBox } from "./QuadTreeBoundingBox";
import { Random } from "./Random";
import { HashSet$1 } from "./HashSet$1";
import { Base, runOn, Point_$type, markType } from "./type";
import { GeometryUtil } from "./GeometryUtil";
import { truncate } from "./number";
export class LabelCollisionManager extends Base {
    constructor(a, b, c, d, e, f, g, h) {
        super();
        this.k = null;
        this.g = null;
        this.f = null;
        this.d = null;
        this.c = 0;
        this.b = null;
        this.o = 0;
        this.u = 0;
        this.t = 0;
        this.i = new LinkedList$1(LabelInfo.$);
        this.q = 0;
        this.j = new List$1(LabelInfo.$, 0);
        this.s = 0;
        this.p = 0;
        this.l = 0;
        this.m = 0;
        this.r = 0;
        this.h = false;
        this.d = new QuadTree(a, b, 8, 8);
        this.c = e;
        this.b = c;
        this.k = new List$1(LabelCollisionPlacementPositions_$type, 0);
        this.k.add(0);
        this.k.add(5);
        this.k.add(7);
        this.k.add(2);
        this.k.add(3);
        this.k.add(6);
        this.k.add(1);
        this.k.add(4);
        this.o = d;
        this.u = f;
        this.t = g;
        this.h = h;
    }
    e(a, b, c, d) {
        let e = 0;
        let f = 0;
        switch (b) {
            case 0:
                e = a.o;
                f = ((a.p - a.m) - a.k) - this.o;
                break;
            case 4:
                e = ((a.o - a.n) - a.l) - this.o;
                f = ((a.p - a.m) - a.k) - this.o;
                break;
            case 5:
                e = ((a.o + a.n) + a.l) + this.o;
                f = ((a.p - a.m) - a.k) - this.o;
                break;
            case 1:
                e = ((a.o - a.n) - a.l) - this.o;
                f = a.p;
                break;
            case 2:
                e = ((a.o + a.n) + a.l) + this.o;
                f = a.p;
                break;
            case 3:
                e = a.o;
                f = ((a.p + a.m) + a.k) + this.o;
                break;
            case 6:
                e = ((a.o - a.n) - a.l) - this.o;
                f = ((a.p + a.m) + a.k) + this.o;
                break;
            case 7:
                e = ((a.o + a.n) + a.l) + this.o;
                f = ((a.p + a.m) + a.k) + this.o;
                break;
        }
        let g = new QuadTreeBoundingBox();
        g.b = e + c;
        g.c = f + d;
        g.e = a.l;
        g.d = a.k;
        g.g = a;
        return g;
    }
    aa(a, b, c, d, e) {
        this.z(a, b, c, d, e);
    }
    z(a, b, c, d, e) {
        this.d.d(a);
        a.b = b;
        a.c = c;
        a.e = d;
        a.d = e;
        this.d.c(a);
    }
    ae(a) {
        this.d.d(a);
    }
    w(a) {
        this.q++;
        this.i.f(a);
        a.e = this.i.d;
        a.c = new QuadTreeBoundingBox();
        a.c.b = a.o;
        a.c.c = a.p;
        a.c.e = a.n;
        a.c.d = a.m;
        a.c.g = a;
        this.d.c(a.c);
    }
    af(a) {
        if (a.c != null) {
            this.d.d(a.c);
            a.c = null;
        }
        if (a.b != null) {
            this.d.d(a.b);
            a.b = null;
        }
        if (a.e != null) {
            this.i.h(a.e);
            a.e = null;
        }
        this.q--;
    }
    ac(a) {
        this.d.d(a.c);
        a.c.b = a.o;
        a.c.c = a.p;
        a.c.e = a.n;
        a.c.d = a.m;
        this.d.c(a.c);
    }
    ab(a) {
        this.d.d(a.b);
        a.b.b = a.g;
        a.b.c = a.h;
        a.b.e = a.l;
        a.b.d = a.k;
        this.d.c(a.b);
    }
    ag() {
        this.p = 0;
        this.l = 4;
        this.m = 20;
        let a = truncate(Math.ceil((this.t / 33) * this.u));
        this.s = a;
        this.x();
    }
    x() {
        this.j.clear();
        this.ad(false);
        if (this.c == 0) {
            for (let a = 0; a < this.u; a++) {
                this.m = this.l * (this.s - this.p) / this.s;
                this.y();
                this.p++;
                if (this.p > this.s) {
                    if (this.f != null) {
                        this.f();
                    }
                    return;
                }
            }
            if (this.g != null) {
                this.g(this.j);
            }
            this.b.executeDelayed(runOn(this, this.x), 33);
        }
        else {
            if (this.c == 2) {
                let b = this.i.c;
                this.d.i();
                while (b != null) {
                    let c = b.c;
                    if (c.b != null) {
                        this.d.d(c.b);
                        c.b = null;
                        c.d = false;
                        c.f = null;
                    }
                    b = b.a;
                }
                this.r = 0;
                this.ad(true);
            }
            if (this.g != null) {
                this.g(this.j);
            }
        }
    }
    y() {
        let a = truncate(Math.round((this.q - 1) * LabelCollisionManager.v.nextDouble()));
        let b = 0;
        let c = this.i.c;
        let d = this.n(null);
        while (c != null) {
            let e = c.c;
            if (b == a) {
                let f = truncate(Math.round((this.k.count - 1) * LabelCollisionManager.v.nextDouble()));
                while (this.k._inner[f] == e.a) {
                    f = truncate(Math.round((this.k.count - 1) * LabelCollisionManager.v.nextDouble()));
                }
                let g = e.b;
                let h = this.e(e, this.k._inner[f], 0, 0);
                e.b = h;
                this.d.d(g);
                this.d.c(h);
                let i = this.n(e);
                let j = d > i;
                if (!j) {
                    let k = Math.exp(-(i - d) / this.m);
                    if (LabelCollisionManager.v.nextDouble() < k) {
                        j = true;
                    }
                }
                if (!j) {
                    this.d.d(h);
                    this.d.c(g);
                    e.b = g;
                    if (!this.h) {
                        this.n(e);
                    }
                }
                else {
                    e.a = this.k._inner[f];
                    e.g = e.b.b;
                    e.h = e.b.c;
                    this.j.add(e);
                }
                break;
            }
            b++;
            c = c.a;
        }
    }
    n(a) {
        if (this.h) {
            let b = 0;
            let c = this.i.c;
            while (c != null) {
                let d = c.c;
                let e = d.d;
                d.d = false;
                if (d.b != null) {
                    let f = this.d.e(d.b);
                    for (let g = 0; g < f.count; g++) {
                        let h = f._inner[g].l.c;
                        while (h != null) {
                            let i = h.c;
                            if (i.g == d) {
                                h = h.a;
                                continue;
                            }
                            if (d.b.a(i)) {
                                d.d = true;
                                b += d.b.f(i);
                            }
                            h = h.a;
                        }
                    }
                    if (d.d != e) {
                        this.j.add(d);
                    }
                }
                c = c.a;
            }
            return b;
        }
        else {
            if (a != null) {
                let j = new HashSet$1(LabelInfo.$, 0);
                let k = new HashSet$1(LabelInfo.$, 0);
                let l = new List$1(LabelInfo.$, 0);
                if (a.f != null) {
                    for (let m = 0; m < a.f.count; m++) {
                        j.add_1(a.f._inner[m]);
                    }
                }
                let n = a.d;
                a.d = false;
                if (a.b != null) {
                    let o = this.d.e(a.b);
                    for (let p = 0; p < o.count; p++) {
                        let q = o._inner[p].l.c;
                        while (q != null) {
                            let r = q.c;
                            if (r.g == a) {
                                q = q.a;
                                continue;
                            }
                            if (a.b.a(r)) {
                                a.d = true;
                                k.add_1(r.g);
                                l.add(r.g);
                            }
                            q = q.a;
                        }
                    }
                    if (a.d != n) {
                        this.j.add(a);
                    }
                    if (a.f != null) {
                        for (let s = a.f.count - 1; s >= 0; s--) {
                            if (!k.contains(a.f._inner[s])) {
                                let t = a.f._inner[s];
                                t.f.remove(a);
                                a.f.removeAt(s);
                                if (t.f.count == 0) {
                                    this.r--;
                                }
                                j.remove(t);
                                if (j.count == 0) {
                                    this.r--;
                                }
                            }
                        }
                    }
                    for (let u = 0; u < l.count; u++) {
                        let v = l._inner[u];
                        if (!j.contains(v)) {
                            if (a.f == null) {
                                a.f = new List$1(LabelInfo.$, 0);
                            }
                            a.f.add(v);
                            if (j.count == 0) {
                                this.r++;
                            }
                            j.add_1(v);
                            if (v.f == null) {
                                v.f = new List$1(LabelInfo.$, 0);
                            }
                            if (v.f.count == 0) {
                                this.r++;
                            }
                            v.f.add(a);
                        }
                    }
                }
            }
            return this.r;
        }
    }
    ad(a) {
        let b = this.i.c;
        while (b != null) {
            let c = b.c;
            if (c.b == null || a) {
                let d = false;
                if (a) {
                    let e = this.d.a(c.o, c.p, 1.5);
                    let f = this.a(e);
                    for (let g = 0; g < f.length; g++) {
                        let h = f[g];
                        let i = this.e(c, h, 0, 0);
                        let j = this.d.e(i);
                        d = true;
                        for (let k = 0; k < j.count; k++) {
                            let l = j._inner[k].l.c;
                            while (l != null) {
                                let m = l.c;
                                if (i.a(m)) {
                                    d = false;
                                    break;
                                }
                                l = l.a;
                            }
                        }
                        if (d) {
                            c.b = i;
                            c.a = h;
                            c.g = c.b.b;
                            c.h = c.b.c;
                            this.d.c(c.b);
                            this.j.add(c);
                            break;
                        }
                    }
                }
                if (!d) {
                    for (let n = 0; n < this.k.count; n++) {
                        let o = this.e(c, this.k._inner[n], 0, 0);
                        let p = this.d.e(o);
                        d = true;
                        for (let q = 0; q < p.count; q++) {
                            let r = p._inner[q].l.c;
                            while (r != null) {
                                let s = r.c;
                                if (o.a(s)) {
                                    d = false;
                                    break;
                                }
                                r = r.a;
                            }
                        }
                        if (d) {
                            c.b = o;
                            c.a = this.k._inner[n];
                            c.g = c.b.b;
                            c.h = c.b.c;
                            this.d.c(c.b);
                            this.j.add(c);
                            break;
                        }
                    }
                }
                if (!d) {
                    this.r++;
                    let t = Number.POSITIVE_INFINITY;
                    let u = 0;
                    let v = null;
                    for (let w = 0; w < this.k.count; w++) {
                        let x = 0;
                        let y = null;
                        if (!this.h) {
                            y = new List$1(LabelInfo.$, 0);
                        }
                        let z = this.e(c, this.k._inner[w], 0, 0);
                        let aa = this.d.e(z);
                        for (let ab = 0; ab < aa.count; ab++) {
                            let ac = aa._inner[ab].l.c;
                            while (ac != null) {
                                let ad = ac.c;
                                if (z.a(ad)) {
                                    x += z.f(ad);
                                    if (!this.h) {
                                        y.add(ad.g);
                                    }
                                }
                                ac = ac.a;
                            }
                        }
                        if (x < t) {
                            t = x;
                            u = w;
                            if (!this.h) {
                                v = y;
                            }
                        }
                    }
                    let ae = this.e(c, this.k._inner[u], 0, 0);
                    c.d = true;
                    if (!this.h) {
                        c.f = v;
                        for (let af = 0; af < v.count; af++) {
                            let ag = v._inner[af];
                            if (ag.f == null) {
                                ag.f = new List$1(LabelInfo.$, 0);
                            }
                            if (ag.f.count == 0) {
                                this.r++;
                            }
                            ag.f.add(c);
                        }
                    }
                    c.b = ae;
                    c.a = this.k._inner[u];
                    c.g = c.b.b;
                    c.h = c.b.c;
                    this.d.c(c.b);
                    this.j.add(c);
                }
            }
            b = b.a;
        }
    }
    a(a) {
        let b = new Array(3);
        let c = GeometryUtil.e({ $type: Point_$type, x: 0, y: 0 }, { $type: Point_$type, x: a.a, y: a.b });
        c = c * 180 / Math.PI;
        c = GeometryUtil.g(c);
        if ((c >= 0 && c <= 22.5) || (c >= 337.5 && c <= 360)) {
            b[0] = 2;
            b[1] = 5;
            b[2] = 7;
        }
        if (c >= 22.5 && c <= 67.5) {
            b[0] = 2;
            b[1] = 7;
            b[2] = 3;
        }
        if (c >= 67.5 && c <= 112.5) {
            b[0] = 7;
            b[1] = 3;
            b[2] = 6;
        }
        if (c >= 112.5 && c <= 157.5) {
            b[0] = 3;
            b[1] = 6;
            b[2] = 1;
        }
        if (c >= 157.5 && c <= 202.5) {
            b[0] = 6;
            b[1] = 1;
            b[2] = 4;
        }
        if (c >= 202.5 && c <= 247.5) {
            b[0] = 1;
            b[1] = 4;
            b[2] = 0;
        }
        if (c >= 247.5 && c <= 292.5) {
            b[0] = 4;
            b[1] = 0;
            b[2] = 5;
        }
        if (c >= 292.5 && c <= 337.5) {
            b[0] = 0;
            b[1] = 5;
            b[2] = 2;
        }
        return b;
    }
}
LabelCollisionManager.v = new Random(0);
LabelCollisionManager.$t = markType(LabelCollisionManager, 'LabelCollisionManager');
/*<BeginStatics Name="Infragistics.LabelCollisionManager" />*/
/*<EndStatics Name="Infragistics.LabelCollisionManager" />*/
//# sourceMappingURL=LabelCollisionManager.js.map