/*
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 { CategoryBucketCalculator } from "./CategoryBucketCalculator";
import { Type, markType, typeCast, Point_$type } from "igniteui-react-core/ES2015/type";
import { isNaN_ } from "igniteui-react-core/ES2015/number";
import { CategorySeries } from "./CategorySeries";
import { IIsCategoryBased_$type } from "./IIsCategoryBased";
import { IHasHighLowValueCategory_$type } from "./IHasHighLowValueCategory";
import { RangeCategoryFramePreparer } from "./RangeCategoryFramePreparer";
import { DependencyProperty } from "igniteui-react-core/ES2015/DependencyProperty";
import { Series } from "./Series";
import { CategoryAxisBase } from "./CategoryAxisBase";
import { ICategoryScaler_$type } from "./ICategoryScaler";
import { IScaler_$type } from "./IScaler";
import { CategorySeriesView } from "./CategorySeriesView";
import { CategoryFrame } from "./CategoryFrame";
import { CategoryMarkerManager } from "./CategoryMarkerManager";
import { Rect } from "igniteui-react-core/ES2015/Rect";
import { ScalerParams } from "./ScalerParams";
import { IFastItemsSource_$type } from "igniteui-react-core/ES2015/IFastItemsSource";
import { AxisRange } from "./AxisRange";
import { ISortingAxis_$type } from "./ISortingAxis";
import { CollisionAvoider } from "./CollisionAvoider";
import { ISupportsMarkers_$type } from "./ISupportsMarkers";
import { PropertyMetadata } from "igniteui-react-core/ES2015/PropertyMetadata";
import { FastFlattener } from "igniteui-react-core/ES2015/FastFlattener";
/**
 * @hidden
 */
export class RangeCategoryBucketCalculator extends CategoryBucketCalculator {
    constructor(a) {
        super(a);
        this.j = null;
        this.l = 0;
        this.k = 0;
        this.i = null;
        this.h = null;
        this.j = a;
    }
    getBucketWithoutUnknowns(a) {
        let b = false;
        let c = this.i;
        let d = this.h;
        let e = this.l;
        let f = this.k;
        let g = Math.min(e, f);
        let h = a * this.d;
        let i = Math.min(h + this.d - 1, g - 1);
        let j = 1.7976931348623157E+308;
        let k = -1.7976931348623157E+308;
        let l = true;
        let m = 0;
        let n = 0;
        let o;
        let p;
        for (let q = h; q <= i; ++q) {
            m = c[q];
            n = d[q];
            if (m < n) {
                o = m;
                p = n;
            }
            else {
                p = m;
                o = n;
            }
            if (!l) {
                j = j < o ? j : o;
                k = k > o ? k : o;
                j = j < p ? j : p;
                k = k > p ? k : p;
            }
            else {
                j = Math.min(j, o);
                k = Math.max(k, o);
                k = Math.max(k, p);
                j = Math.min(j, p);
                l = false;
            }
        }
        if (b && n < m) {
            let r = j;
            j = k;
            k = r;
        }
        if (!l) {
            let s = new Array(3);
            s[0] = 0.5 * (h + i);
            s[1] = j;
            s[2] = k;
            return s;
        }
        let t = new Array(3);
        t[0] = NaN;
        t[1] = NaN;
        t[2] = NaN;
        return t;
    }
    getBucket(a) {
        let b = false;
        let c = this.i;
        let d = this.h;
        let e = this.l;
        let f = this.k;
        let g = Math.min(e, f);
        let h = a * this.d;
        let i = Math.min(h + this.d - 1, g - 1);
        let j = NaN;
        let k = NaN;
        let l = true;
        let m = 0;
        let n = 0;
        let o;
        let p;
        for (let q = h; q <= i; ++q) {
            m = c[q];
            n = d[q];
            if (m < n) {
                o = m;
                p = n;
            }
            else {
                p = m;
                o = n;
            }
            if (!l) {
                if (!isNaN_(o)) {
                    j = j < o ? j : o;
                    k = k > o ? k : o;
                }
                if (!isNaN_(p)) {
                    j = j < p ? j : p;
                    k = k > p ? k : p;
                }
            }
            else {
                if (!isNaN_(o)) {
                    if (isNaN_(j)) {
                        j = o;
                    }
                    else {
                        j = Math.min(j, o);
                    }
                    if (!isNaN_(k)) {
                        k = Math.max(k, o);
                    }
                }
                if (!isNaN_(p)) {
                    if (isNaN_(k)) {
                        k = p;
                    }
                    else {
                        k = Math.max(k, p);
                    }
                    if (!isNaN_(j)) {
                        j = Math.min(j, p);
                    }
                }
                if (!isNaN_(j) && !isNaN_(k)) {
                    l = false;
                }
            }
        }
        if (n < m && b) {
            let r = j;
            j = k;
            k = r;
        }
        if (!l) {
            let s = new Array(3);
            s[0] = 0.5 * (h + i);
            s[1] = j;
            s[2] = k;
            return s;
        }
        let t = new Array(3);
        t[0] = NaN;
        t[1] = NaN;
        t[2] = NaN;
        return t;
    }
    cacheValues() {
        this.l = this.j.cw.lowColumn.count;
        this.k = this.j.cw.highColumn.count;
        this.i = this.j.cw.lowColumn.asArray();
        this.h = this.j.cw.highColumn.asArray();
    }
    unCacheValues() {
        this.i = null;
        this.h = null;
    }
}
RangeCategoryBucketCalculator.$t = markType(RangeCategoryBucketCalculator, 'RangeCategoryBucketCalculator', CategoryBucketCalculator.$);
/**
 * @hidden
 */
export class RangeCategorySeries extends CategorySeries {
    constructor() {
        super();
        this._RangeFramePreparer = null;
        this.ot = null;
        this.or = null;
        this.oo = null;
        this.RangeFramePreparer = new RangeCategoryFramePreparer(1, this, this.oq, this, this, this.oq.cn);
    }
    bf() {
        return new RangeCategorySeriesView(this);
    }
    getHostReferenceValue() {
        return this.ee();
    }
    im(a) {
        super.im(a);
        this.oq = a;
    }
    get RangeFramePreparer() {
        return this._RangeFramePreparer;
    }
    set RangeFramePreparer(a) {
        this._RangeFramePreparer = a;
    }
    get lowColumn() {
        return this.ot;
    }
    set lowColumn(a) {
        if (this.ot != a) {
            let b = this.ot;
            this.ot = a;
            this.raisePropertyChanged("LowColumn", b, this.ot);
        }
    }
    get highColumn() {
        return this.or;
    }
    set highColumn(a) {
        if (this.or != a) {
            let b = this.or;
            this.or = a;
            this.raisePropertyChanged("HighColumn", b, this.or);
        }
    }
    m9() {
        return 11;
    }
    oh(a, b) {
        super.oh(a, b);
        b.b0 = true;
        CategoryMarkerManager.b(this, a.m, b.cq, this.ly);
        this.ob(b, a);
    }
    o1(a, b, c, d, e, f) {
        this.oq.cx(a, b, c, d, e, f);
    }
    c8(a) {
        let b = new Rect(0, 0, 0, 1, 1);
        let c = this.bi != null ? this.bi.bs : Rect.empty;
        c = c.copy();
        let d = this.bi != null ? this.bi.br : Rect.empty;
        let e = !c.isEmpty && !d.isEmpty && this.bz != null ? this.bz.indexOf(a) : -1;
        let f = this.fetchXAxis();
        let g = this.fetchYAxis();
        let h = this.ll(this.bi);
        let i;
        if (f != null) {
            let j = new ScalerParams(0, b, b, f.b8, h);
            i = f.dt(e, j);
        }
        else {
            i = NaN;
        }
        let k = f != null ? this.RangeFramePreparer.r(typeCast(ICategoryScaler_$type, f), b, b, h) : 0;
        i += k;
        if (e >= 0 && Rect.l_op_Inequality(c, null) && Rect.l_op_Inequality(d, null)) {
            if (!isNaN_(i)) {
                if (i < c.left + 0.1 * c.width) {
                    i = i + 0.4 * c.width;
                }
                if (i > c.right - 0.1 * c.width) {
                    i = i - 0.4 * c.width;
                }
                c.x = i - 0.5 * c.width;
            }
            if (g != null && this.highColumn != null && e < this.highColumn.count) {
                let l = new ScalerParams(0, b, b, g.b8, h);
                l.b = this.ee();
                let m = g.dt(this.highColumn.item(e), l);
                let n = g.dt(this.lowColumn.item(e), l);
                if (!isNaN_(m) && !isNaN_(n)) {
                    let o = Math.abs(n - m);
                    if (c.height < o) {
                        c.height = o;
                        c.y = Math.min(n, m);
                    }
                    else {
                        if (n < c.top + 0.1 * c.height) {
                            n = n + 0.4 * c.height;
                        }
                        if (n > c.bottom - 0.1 * c.height) {
                            n = n - 0.4 * c.height;
                        }
                        c.y = n - 0.5 * c.height;
                    }
                }
            }
            if (this.bn != null) {
                this.bn.ap(this.bs, c, true);
            }
        }
        return e >= 0;
    }
    is(a, b, c, d) {
        super.is(a, b, c, d);
        switch (b) {
            case "FastItemsSource":
                if (typeCast(IFastItemsSource_$type, c) != null) {
                    c.deregisterColumn(this.lowColumn);
                    c.deregisterColumn(this.highColumn);
                    this.lowColumn = null;
                    this.highColumn = null;
                }
                if (typeCast(IFastItemsSource_$type, d) != null) {
                    this.lowColumn = this.bw(this.oz);
                    this.highColumn = this.bw(this.ow);
                }
                if (!this.nu()) {
                    this.m8.cn.g(this.er);
                    this.i6(false);
                }
                break;
            case RangeCategorySeries.$$p[1]:
                if (this.bz != null) {
                    this.bz.deregisterColumn(this.lowColumn);
                    this.lowColumn = this.bw(this.oz);
                }
                break;
            case "LowColumn":
                if (!this.nu()) {
                    this.m8.cn.g(this.er);
                    this.i6(false);
                }
                break;
            case RangeCategorySeries.$$p[0]:
                if (this.bz != null) {
                    this.bz.deregisterColumn(this.highColumn);
                    this.highColumn = this.bw(this.ow);
                }
                break;
            case "HighColumn":
                if (!this.nu()) {
                    this.m8.cn.g(this.er);
                    this.i6(false);
                }
                break;
        }
    }
    an(a) {
        if (this.lowColumn == null || this.lowColumn.count == 0 || this.highColumn == null || this.highColumn.count == 0) {
            return null;
        }
        if (a == this.fetchXAxis()) {
            let b = Math.min(this.lowColumn.count, this.highColumn.count);
            return new AxisRange(0, b - 1);
        }
        if (a == this.fetchYAxis()) {
            let c = Math.min(this.lowColumn.minimum, this.highColumn.minimum);
            let d = Math.max(this.lowColumn.maximum, this.highColumn.maximum);
            return new AxisRange(Math.min(c, d), Math.max(c, d));
        }
        return null;
    }
    hs(a, b, c, d) {
        if (this.fetchXAxis() != null && typeCast(ISortingAxis_$type, this.fetchXAxis()) !== null) {
            this.fetchXAxis().i$i();
        }
        let e = this.fetchXAxis();
        switch (a) {
            case 3:
                if (d == this.oz || d == this.ow) {
                    if (e != null) {
                        e.ck();
                    }
                    if (!this.nu()) {
                        this.i6(true);
                    }
                }
                break;
            case 1:
                if (e != null) {
                    e.ck();
                }
                this.m8.cn.g(this.er);
                if (!this.nu()) {
                    this.i6(true);
                }
                break;
            case 0:
                if (e != null) {
                    e.ck();
                }
                this.m8.cn.g(this.er);
                if (!this.nu()) {
                    this.i6(true);
                }
                break;
            case 2:
                if (e != null) {
                    e.ck();
                }
                if (this.oz != null && this.ow != null && this.m8.cn.d > 0 && !this.nu()) {
                    this.i6(true);
                }
                break;
            case 4:
                if (e != null) {
                    e.ck();
                }
                this.m8.cn.g(this.er);
                if (!this.nu()) {
                    this.i6(true);
                }
                break;
        }
    }
    dv(a, b, c) {
        let d = super.dv(a, b, c);
        if (this.lowColumn == null || this.lowColumn.count == 0 || this.highColumn == null || this.highColumn.count == 0) {
            d = false;
        }
        return d;
    }
    oe(a, b) {
        super.oe(a, b);
        this.RangeFramePreparer.d(a, b);
    }
    get currentCategoryMode() {
        return this.preferredCategoryMode(typeCast(CategoryAxisBase.$, this.fetchXAxis()));
    }
    get scaler() {
        return typeCast(ICategoryScaler_$type, this.fetchXAxis());
    }
    get yScaler() {
        return typeCast(IScaler_$type, this.fetchYAxis());
    }
    get bucketizer() {
        return this.m8.cn;
    }
    get currentMode2Index() {
        return this.n2();
    }
    provideCollisionDetector() {
        return new CollisionAvoider();
    }
    get mayContainUnknowns() {
        return this.lowColumn == null || this.lowColumn.mayContainUnknowns || this.highColumn == null || this.highColumn.mayContainUnknowns;
    }
    i8(a, b) {
        let c = this.dk;
        super.i8(a, b);
        if (!c) {
            this.bi.az(b);
            return;
        }
        this.bi.az(b);
        if (this.cc(this.bh)) {
            return;
        }
        let d = new RangeCategoryFramePreparer(1, this, typeCast(ISupportsMarkers_$type, this.bh), this.bs.bn.m, this, this.bh.cn);
        if (!this.de) {
            this.m2 = new CategoryFrame(3);
            this.m2.u();
            d.d(this.m2, this.bh);
        }
        this.de = false;
        this.oh(this.m2, this.bh);
        this.dk = false;
    }
    i5(a, b, c, d, e) {
        super.i5(a, b, c, d, e);
        let f = this.a0.a$h.item(d);
        let g = f;
        g.cn.g(this.er);
        f.ay(c);
        if (this.cc(g)) {
            return;
        }
        let h = new RangeCategoryFramePreparer(1, this, typeCast(ISupportsMarkers_$type, f), f, this, f.cn);
        if (this.oo == null) {
            this.oo = new CategoryFrame(3);
        }
        this.oo.u();
        h.d(this.oo, g);
        this.oh(this.oo, g);
    }
    ee() {
        return Series.ef(this.lowColumn, typeCast(ISortingAxis_$type, this.fetchXAxis()));
    }
    get useHighMarkerFidelity() {
        return this.nv;
    }
}
RangeCategorySeries.$t = markType(RangeCategorySeries, 'RangeCategorySeries', CategorySeries.$, [IIsCategoryBased_$type, IHasHighLowValueCategory_$type]);
Type.dep(DependencyProperty, PropertyMetadata, RangeCategorySeries, 'raisePropertyChanged', ['HighMemberPath:ow:o2', [2, null], 'LowMemberPath:oz:o3', [2, null]]);
/**
 * @hidden
 */
export class RangeCategorySeriesView extends CategorySeriesView {
    constructor(a) {
        super(a);
        this.cw = null;
        this.cw = a;
    }
    cx(a, b, c, d, e, f) {
        a.aj.clear();
        b.aj.clear();
        c.aj.clear();
        let g = FastFlattener.b(d, e, true, f, this.e.er);
        let h = FastFlattener.b(d, e, false, f, this.e.er);
        let i = g.count;
        let j = h.count;
        let k;
        let l;
        let m;
        let n;
        for (let o = 0; o < i; o++) {
            k = g.item(o);
            l = e._inner[k];
            m = l[0];
            n = l[1];
            a.aj.add({ $type: Point_$type, x: m, y: n });
            b.aj.add({ $type: Point_$type, x: m, y: n });
        }
        let p;
        let q;
        for (let r = 0; r < j; r++) {
            k = h.item(r);
            l = e._inner[k];
            if (f) {
                p = l[0];
                q = l[2];
            }
            else {
                p = l[2];
                q = l[3];
            }
            c.aj.add({ $type: Point_$type, x: p, y: q });
            b.aj.add({ $type: Point_$type, x: p, y: q });
        }
        a.ab = a.aj.count > 0;
        b.ab = b.aj.count > 0;
        c.ab = c.aj.count > 0;
    }
    co() {
        return new RangeCategoryBucketCalculator(this);
    }
}
RangeCategorySeriesView.$t = markType(RangeCategorySeriesView, 'RangeCategorySeriesView', CategorySeriesView.$);
