/*
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 { Base, EventArgs, runOn, markType } from "igniteui-angular-core";
import { KDTreeNode2D } from "./KDTreeNode2D";
import { KDTreeThunk } from "./KDTreeThunk";
import { Stack$1 } from "igniteui-angular-core";
import { List$1 } from "igniteui-angular-core";
import { KNearestResult } from "./KNearestResult";
import { SearchData } from "./SearchData";
import { intDivide, isNaN_ } from "igniteui-angular-core";
/**
 * @hidden
 */
export let KDTree2D = /*@__PURE__*/ (() => {
    class KDTree2D extends Base {
        constructor(a, ..._rest) {
            super();
            this.a = null;
            this.j = null;
            this.i = null;
            this.m = 0;
            this.q = {};
            this.progressiveThunkCompleted = null;
            this.g = false;
            this.e = null;
            this.f = null;
            this.d = null;
            a = (a == void 0) ? 0 : a;
            switch (a) {
                case 0:
                    {
                        let c = _rest[0];
                        let d = _rest[1];
                        let e = _rest[2];
                        this.f = e;
                        this.d = this.c(c, 0, c.length - 1, 0, d);
                    }
                    break;
                case 1:
                    {
                        let c = _rest[0];
                        this.f = c;
                    }
                    break;
            }
        }
        get r() {
            return this.q;
        }
        static b(a, b, c) {
            let d = new KDTree2D(1, c);
            d.d = new KDTreeNode2D();
            d.d.g = true;
            d.a = a;
            d.j = new Stack$1(KDTreeThunk.$);
            d.i = new List$1(KDTreeThunk.$, 0);
            let e = new KDTreeThunk();
            e.e = 0;
            e.b = a.length - 1;
            e.c = 0;
            e.d = b;
            e.a = d.d;
            d.j.h(e);
            return d;
        }
        h(a) {
            if (this.j.f == 0 && this.i.count == 0) {
                this.a = null;
                return false;
            }
            if (this.j.f == 0 && this.i.count > 0) {
                return true;
            }
            this.m = this.j.d().c;
            while (this.j.f > 0 && this.j.d().c == this.m) {
                this.i.add(this.j.e());
            }
            if (a != null) {
                a.setTimeout(runOn(this, this.z), 0);
            }
            else {
                window.setTimeout(runOn(this, this.z), 0);
            }
            return true;
        }
        t() {
            this.g = true;
        }
        z() {
            let a;
            for (let b = 0; b < this.i.count; b++) {
                if (this.g || this.a == null) {
                    return;
                }
                if (this.a.length == 0) {
                    continue;
                }
                a = this.i._inner[b];
                this.w(a.a, this.a, a.e, a.b, a.c, a.d);
            }
            this.i.clear();
            if (this.progressiveThunkCompleted != null) {
                this.progressiveThunkCompleted(this, new EventArgs());
            }
        }
        w(a, b, c, d, e, f) {
            a.g = false;
            a.f = (e % 2) == 0;
            a.h = (d - c);
            if (c == d) {
                a.b = b[c];
                return;
            }
            if (c > d) {
                a.g = true;
                return;
            }
            if ((d - c) + 1 <= f) {
                a.b = b[c];
                a.a = new Array((d - c) + 1);
                let g = 0;
                for (let h = c; h <= d; h++) {
                    a.a[g++] = b[h];
                }
                return;
            }
            let i = Math.max(intDivide((d - c), 2), 1);
            let j = this.o(b, c, d, a.f, i);
            a.b = b[j];
            if (c <= j - 1) {
                a.c = ((() => {
                    let $ret = new KDTreeNode2D();
                    $ret.g = true;
                    return $ret;
                })());
                a.c.h = ((j - 1) - c) + 1;
                this.j.h(((() => {
                    let $ret = new KDTreeThunk();
                    $ret.e = c;
                    $ret.b = j - 1;
                    $ret.c = e + 1;
                    $ret.d = f;
                    $ret.a = a.c;
                    return $ret;
                })()));
            }
            else {
                a.c = null;
            }
            if (j + 1 <= d) {
                a.d = ((() => {
                    let $ret = new KDTreeNode2D();
                    $ret.g = true;
                    return $ret;
                })());
                a.d.h = (d - (j + 1)) + 1;
                this.j.h(((() => {
                    let $ret = new KDTreeThunk();
                    $ret.e = j + 1;
                    $ret.b = d;
                    $ret.c = e + 1;
                    $ret.d = f;
                    $ret.a = a.d;
                    return $ret;
                })()));
            }
            else {
                a.d = null;
            }
        }
        c(a, b, c, d, e) {
            let f = new KDTreeNode2D();
            f.f = (d % 2) == 0;
            f.h = (c - b);
            if (b == c) {
                f.b = a[b];
                return f;
            }
            if (b > c) {
                return null;
            }
            if ((c - b) + 1 <= e) {
                f.b = a[b];
                f.a = new Array(c - b + 1);
                let g = 0;
                for (let h = b; h <= c; h++) {
                    f.a[g++] = a[h];
                }
                return f;
            }
            let i = Math.max(intDivide((c - b), 2), 1);
            let j = this.o(a, b, c, f.f, i);
            f.b = a[j];
            f.c = this.c(a, b, j - 1, d + 1, e);
            f.d = this.c(a, j + 1, c, d + 1, e);
            return f;
        }
        n(a, b, c, d, e) {
            let f = b ? a[e].a : a[e].b;
            let g = a[e];
            a[e] = a[d];
            a[d] = g;
            let h = c;
            for (let i = c; i < d; i++) {
                let j;
                if (b) {
                    j = a[i].a;
                }
                else {
                    j = a[i].b;
                }
                if (j <= f) {
                    g = a[h];
                    a[h] = a[i];
                    a[i] = g;
                    h++;
                }
            }
            g = a[d];
            a[d] = a[h];
            a[h] = g;
            return h;
        }
        o(a, b, c, d, e) {
            if (b == c) {
                return b;
            }
            if (this.e == null) {
                this.e = this.f.getGenerator("KDTreePivot");
            }
            let f = this.e.next(b, c);
            let g = this.n(a, d, b, c, f);
            let h = g - b + 1;
            if (h == e) {
                return g;
            }
            else if (e < h) {
                return this.o(a, b, g - 1, d, e);
            }
            else {
                return this.o(a, g + 1, c, d, e - h);
            }
        }
        x(a, b, c, d) {
            this.y(a, b, c, d, this.d);
        }
        y(a, b, c, d, e) {
            if (e == null || e.g) {
                return;
            }
            if (e.c == null && e.d == null) {
                this.s(a, b, c, e, e.b, true, 0, d);
                if (a.a) {
                    return;
                }
                if (e.a != null && e.a.length > 0) {
                    for (let f = 0; f < e.a.length; f++) {
                        this.s(a, b, c, e, e.a[f], false, f, d);
                        if (a.a) {
                            return;
                        }
                    }
                }
                return;
            }
            this.s(a, b, c, e, e.b, true, 0, d);
            if (a.a) {
                return;
            }
            if (e.f) {
                if (b <= e.b.a) {
                    this.y(a, b, c, d, e.c);
                    if (a.a) {
                        return;
                    }
                    if (this.k(b, c, e.b.a, c) < a.c) {
                        this.y(a, b, c, d, e.d);
                    }
                    if (a.a) {
                        return;
                    }
                }
                else {
                    this.y(a, b, c, d, e.d);
                    if (a.a) {
                        return;
                    }
                    if (this.k(b, c, e.b.a, c) < a.c) {
                        this.y(a, b, c, d, e.c);
                    }
                    if (a.a) {
                        return;
                    }
                }
            }
            else {
                if (c <= e.b.b) {
                    this.y(a, b, c, d, e.c);
                    if (a.a) {
                        return;
                    }
                    if (this.k(b, c, b, e.b.b) < a.c) {
                        this.y(a, b, c, d, e.d);
                    }
                    if (a.a) {
                        return;
                    }
                }
                else {
                    this.y(a, b, c, d, e.d);
                    if (a.a) {
                        return;
                    }
                    if (this.k(b, c, b, e.b.b) < a.c) {
                        this.y(a, b, c, d, e.c);
                    }
                    if (a.a) {
                        return;
                    }
                }
            }
        }
        s(a, b, c, d, e, f, g, h) {
            if (a.a) {
                return;
            }
            if (a.e > a.f) {
                a.a = true;
                return;
            }
            if (a.b.count < h) {
                if (isNaN_(a.d)) {
                    a.d = this.k(b, c, e.a, e.b);
                    a.c = a.d;
                    a.g = 0;
                }
                a.b.add(((() => {
                    let $ret = new KNearestResult();
                    $ret.b = f;
                    $ret.e = g;
                    $ret.a = d;
                    $ret.c = e.a;
                    $ret.d = e.b;
                    return $ret;
                })()));
                a.e++;
                let i = this.k(b, c, e.a, e.b);
                if (i < a.d) {
                    a.d = i;
                }
                if (i > a.c) {
                    a.c = i;
                    a.g = a.b.count - 1;
                }
                return;
            }
            let j = 0;
            if (j < a.c) {
                if (j < a.d) {
                    a.d = j;
                }
                a.b._inner[a.g] = ((() => {
                    let $ret = new KNearestResult();
                    $ret.b = f;
                    $ret.e = g;
                    $ret.a = d;
                    $ret.c = e.a;
                    $ret.d = e.b;
                    return $ret;
                })());
                let k = 0;
                let l = 0;
                for (let m = 0; m < a.b.count; m++) {
                    let n = this.k(b, c, a.b._inner[m].c, a.b._inner[m].d);
                    if (n > k) {
                        k = n;
                        l = m;
                    }
                }
                a.e++;
            }
        }
        k(a, b, c, d) {
            return (a - c) * (a - c) + (b - d) * (b - d);
        }
        u(a, b, c, d, e, f) {
            this.v(a, this.d, b, c, d, e, f, false, 0);
        }
        v(a, b, c, d, e, f, g, h, i) {
            if (b == null) {
                return;
            }
            let j = b.e;
            if (i > c.g || ((g - f) < c.f && (e - d) < c.e)) {
                if (b.e == null) {
                    b.e = new SearchData();
                }
                j = b.e;
                j.a = true;
                j.d = d;
                j.b = e;
                j.e = f;
                j.c = g;
                a.add(b);
                return;
            }
            if (j != null) {
                j.a = false;
            }
            if (b.c == null && b.d == null) {
                a.add(b);
                return;
            }
            let k;
            let l;
            let m;
            let n;
            let o;
            let p;
            let q;
            let r;
            if (b.f) {
                k = d;
                l = b.b.a;
                m = f;
                n = g;
                o = b.b.a;
                p = e;
                q = f;
                r = g;
            }
            else {
                k = d;
                l = e;
                m = f;
                n = b.b.b;
                o = d;
                p = e;
                q = b.b.b;
                r = g;
            }
            if (h) {
                a.add(b);
                this.v(a, b.c, c, k, l, m, n, true, i + 1);
                this.v(a, b.d, c, o, p, q, r, true, i + 1);
            }
            else {
                let s = false;
                if (k >= c.c && l <= c.a && m >= c.d && n <= c.b) {
                    s = true;
                    a.add(b);
                    this.v(a, b.c, c, k, l, m, n, true, i + 1);
                }
                else if (!(c.c > l || c.a < k || c.d > n || c.b < m)) {
                    s = true;
                    a.add(b);
                    this.v(a, b.c, c, k, l, m, n, false, i + 1);
                }
                if (o >= c.c && p <= c.a && q >= c.d && r <= c.b) {
                    if (!s) {
                        a.add(b);
                    }
                    this.v(a, b.d, c, o, p, q, r, true, i + 1);
                }
                else if (!(c.c > p || c.a < o || c.d > r || c.b < q)) {
                    if (!s) {
                        a.add(b);
                    }
                    this.v(a, b.d, c, o, p, q, r, false, i + 1);
                }
            }
        }
        aa() {
            this.p(this.d);
        }
        p(a) {
            if (a == null) {
                return 0;
            }
            if (this.p(a.c) + this.p(a.d) != a.h) {
                let b = 0;
            }
            return a.h + 1;
        }
    }
    KDTree2D.$t = markType(KDTree2D, 'KDTree2D');
    return KDTree2D;
})();
