/*
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 { SortCondition } from "./SortCondition";
import { Base, String_$type, fromEnum, typeCast, Boolean_$type, markType } from "igniteui-angular-core";
import { ReadOnlyCollection$1 } from "igniteui-angular-core";
import { List$1 } from "igniteui-angular-core";
import { ArgumentNullException } from "igniteui-angular-core";
import { ExcelUtils } from "./ExcelUtils";
import { ArgumentException } from "igniteui-angular-core";
import { WorksheetRow } from "./WorksheetRow";
import { GetCellTextParameters } from "./GetCellTextParameters";
import { OrderedSortCondition } from "./OrderedSortCondition";
import { StringBuilder } from "igniteui-angular-core";
import { StringUtilities } from "./StringUtilities";
import { boolCompare } from "igniteui-angular-core";
/**
 * Represents a sort condition which will sort cells based on a custom, ordered list of values.
 * <p class="body">
 * When the sort direction is ascending, the data range is sorted with the cells in the custom list appearing first, in the order they
 * appear in the list, followed by the other cells in the same relative order they had to each other before the sort. When the sort direction
 * is descending, the cells not in the list will appear first in the data region and they will appear in the same relative order they
 * had before the sort. They will be followed by the other cells in the reverse order of the list.
 * </p>
 * <p class="body">
 * The list of values specified on this sort condition are string values. If a cell being sorted has a string value, that value is used to
 * sort the cell. Otherwise, the cell text is used. For example, if the cell's value is 0.01, but it is formatted as a percentage cell,
 * the text used to sort it with this sort condition will be "1%" and not "0.01". When using the cell text, if the format string for the
 * cell includes padding characters which are repeated across the cells, they will not be included in the cell text used for comparison.
 * </p>
 * <p class="body">
 * When matching values from a cell to values in the custom list, strings are compared case-sensitively or case-insensitively based
 * on the [[SortSettings`1.caseSensitive]] setting.
 * </p>
 * <p class="body">
 * If the cell text contains any repeated padding characters, they are ignored when comparing strings.
 * </p>
 * @see [[SortSettings`1.caseSensitive]]
 * @see [[SortSettings`1.sortConditions]]
 * @see [[SortCondition.sortDirection]]
 * @see [[WorksheetCell.getText]]
 * @see [[WorksheetRow.getCellText]]
 */
export let CustomListSortCondition = /*@__PURE__*/ (() => {
    class CustomListSortCondition extends SortCondition {
        constructor(sortDirection, ...list) {
            super(1, sortDirection);
            this._j = null;
            this._m(list);
        }
        /**
         * @hidden
         */
        _m(a) {
            if (a == null) {
                throw new ArgumentNullException(0, "list");
            }
            let b = new List$1(String_$type, 0);
            for (let c of fromEnum(a)) {
                if (c == null) {
                    continue;
                }
                let d = c.trim();
                if (d.length == 0) {
                    continue;
                }
                b.add(d);
            }
            if (b.count == 0) {
                throw new ArgumentException(2, ExcelUtils.eh("LE_ArgumentException_EmptyCustomList"), "list");
            }
            this._j = new ReadOnlyCollection$1(String_$type, 1, b);
        }
        /**
         * @hidden
         */
        _a() {
            let a = new List$1(String_$type, 0);
            a.o(this._j);
            let b = new CustomListSortCondition(this.sortDirection, ...a.toArray());
            return b;
        }
        /**
         * @hidden
         */
        _g($t, a, b, c, d, e) {
            let f = a.c;
            let g = f._rows$i._aj(b);
            let h = b == c ? g : f._rows$i._aj(c);
            let i = WorksheetRow._c2(g, d);
            let j = WorksheetRow._c2(h, e);
            if (i == null) {
                if (j == null) {
                    return 0;
                }
                return 1;
            }
            else if (j == null) {
                return -1;
            }
            let k;
            if (typeCast(Boolean_$type, i) !== null) {
                if (typeCast(Boolean_$type, j) !== null) {
                    k = boolCompare(i, j);
                }
                else {
                    k = 1;
                }
            }
            else if (typeCast(Boolean_$type, j) !== null) {
                k = -1;
            }
            else {
                let l = new GetCellTextParameters(d);
                let m = d == e ? l : new GetCellTextParameters(e);
                l.c = 1;
                l.b = 1;
                if (d != e) {
                    m.c = 1;
                    m.b = 1;
                }
                let n = a.b;
                let o = g._av(l).j;
                let p = h._av(m).j;
                let q = this._k(f, o, n.caseSensitive);
                let r = this._k(f, p, n.caseSensitive);
                if (q == -1) {
                    if (r == -1) {
                        k = OrderedSortCondition._i($t, n, f, i, j);
                    }
                    else {
                        k = 1;
                    }
                }
                else if (r == -1) {
                    k = -1;
                }
                else {
                    k = Base.compareSimple(q, r);
                }
            }
            if (this.sortDirection == 1) {
                return -k;
            }
            return k;
        }
        /**
         * Determines whether the [[CustomListSortCondition]] is equal to the specified object.
         * @param obj The object to test for equality.
         * @return True if the object is equal to this instance; False otherwise.
         */
        equals(obj) {
            if (Base.referenceEquals(this, obj)) {
                return true;
            }
            let a = typeCast(CustomListSortCondition.$, obj);
            if (a == null || super.equals(a) == false) {
                return false;
            }
            if (this._j.count != a._j.count) {
                return false;
            }
            for (let b = 0; b < this._j.count; b++) {
                if (this._j.item(b) != a._j.item(b)) {
                    return false;
                }
            }
            return true;
        }
        /**
         * Gets the hash code for the [[CustomListSortCondition]].
         * @return A number which can be used to hash this instance.
         */
        getHashCode() {
            let a = this._j.count;
            if (this._j.count != 0) {
                a ^= Base.getHashCodeStatic(this._j.item(0)) ^ Base.getHashCodeStatic(this._j.item(this._j.count - 1));
            }
            return a ^ super.getHashCode();
        }
        /**
         * @hidden
         */
        _f(a) {
            return a == null || a._d != 0;
        }
        /**
         * @hidden
         */
        get__d() {
            return 0;
        }
        /**
         * @hidden
         */
        get _d() {
            return this.get__d();
        }
        /**
         * @hidden
         */
        _l() {
            let a = new StringBuilder(1, this._j.count * 2);
            for (let b = 0; b < this._j.count; b++) {
                a.l(this._j.item(b));
                a.l(",");
            }
            a.c--;
            return a.toString();
        }
        /**
         * @hidden
         */
        _k(a, b, c) {
            let d = c ? 0 : 1;
            let e = a._y;
            for (let f = 0; f < this._j.count; f++) {
                if (StringUtilities.d(this._j.item(f), b, e, d) == 0) {
                    return f;
                }
            }
            return -1;
        }
        /**
         * Gets the ordered list of values by which to sort.
         * <p class="body">
         * The list of values specified on this sort condition are string values. If a cell being sorted has a string value, that value is used to
         * sort the cell. Otherwise, the cell text is used. For example, if the cell's value is 0.01, but it is formatted as a percentage cell,
         * the text used to sort it with this sort condition will be "1%" and not "0.01". When using the cell text, if the format string for the
         * cell includes padding characters which are repeated across the cells, they will not be included in the cell text used for comparison.
         * </p>
         * <p class="body">
         * When matching values from a cell to values in the custom list, strings are compared case-sensitively or case-insensitively based
         * on the [[SortSettings`1.caseSensitive]] setting.
         * </p>
         * <p class="body">
         * If the cell text contains any repeated padding characters, they are ignored when comparing strings.
         * </p>
         * @see [[SortSettings`1.caseSensitive]]
         * @see [[WorksheetCell.getText]]
         * @see [[WorksheetRow.getCellText]]
         */
        get list() {
            return this._j;
        }
    }
    CustomListSortCondition.$t = markType(CustomListSortCondition, 'CustomListSortCondition', SortCondition.$);
    return CustomListSortCondition;
})();
