"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ColumnScopeApiImpl = void 0;
const tslib_1 = require("tslib");
const ApiBase_1 = require("./ApiBase");
const ArrayExtensions_1 = tslib_1.__importDefault(require("../../Utilities/Extensions/ArrayExtensions"));
const UIHelper_1 = require("../../View/UIHelper");
class ColumnScopeApiImpl extends ApiBase_1.ApiBase {
    isColumnInScope(column, scope) {
        if (!column) {
            return false;
        }
        if ('All' in scope) {
            // do we need a true check here?
            return true;
        }
        if ('DataTypes' in scope && scope.DataTypes.includes(column.dataType)) {
            return true;
        }
        if ('ColumnTypes' in scope &&
            scope.ColumnTypes.some((columnType) => column.columnTypes?.includes(columnType))) {
            return true;
        }
        if ('ColumnIds' in scope && scope.ColumnIds.includes(column.columnId)) {
            return true;
        }
        return false;
    }
    getColumnsInScope(scope) {
        if (scope == undefined) {
            return [];
        }
        const columns = this.getColumnApi().getUIAvailableColumns();
        if ('All' in scope) {
            return columns;
        }
        return columns.filter((c) => {
            return this.isColumnInScope(c, scope);
        });
    }
    getScopeDescription(scope) {
        if (scope === undefined) {
            return 'Nothing';
        }
        if ('All' in scope) {
            // do we need a true check here?
            return 'Columns: All';
        }
        if ('ColumnTypes' in scope) {
            return ((scope.ColumnTypes.length > 0 ? 'ColumnTypes' : 'ColumnType') +
                ': ' +
                scope.ColumnTypes.join(', '));
        }
        if ('DataTypes' in scope) {
            return ((scope.DataTypes.length > 0 ? 'DataTypes' : 'DataType') + ': ' + scope.DataTypes.join(', '));
        }
        if ('ColumnIds' in scope) {
            return ((scope.ColumnIds.length > 1 ? 'Columns' : 'Column') +
                ': ' +
                this.getColumnApi()
                    .getFriendlyNamesForColumnIds(scope.ColumnIds)
                    .map((c) => {
                    return '"' + c + '"';
                })
                    .join(', '));
        }
    }
    scopeIsEmpty(scope) {
        return scope === undefined;
    }
    scopeIsAll(scope) {
        return scope !== undefined && 'All' in scope;
    }
    scopeHasDataType(scope) {
        return scope !== undefined && 'DataTypes' in scope;
    }
    scopeHasColumnType(scope) {
        return scope !== undefined && 'ColumnTypes' in scope;
    }
    scopeHasOnlyBooleanDataType(scope) {
        return 'DataTypes' in scope && scope.DataTypes?.length == 1 && scope.DataTypes[0] == 'boolean';
    }
    scopeHasColumns(scope) {
        return scope !== undefined && 'ColumnIds' in scope;
    }
    isSingleColumnScope(scope) {
        return (this.scopeHasColumns(scope) &&
            !this.scopeHasDataType(scope) &&
            !this.scopeIsAll(scope) &&
            'ColumnIds' in scope &&
            scope.ColumnIds.length == 1);
    }
    getSingleColumnInScope(scope) {
        return this.isSingleColumnScope(scope) && 'ColumnIds' in scope ? scope.ColumnIds[0] : undefined;
    }
    isSingleNumericColumnScope(scope) {
        return (this.scopeHasColumns(scope) &&
            !this.scopeHasDataType(scope) &&
            !this.scopeIsAll(scope) &&
            'ColumnIds' in scope &&
            scope.ColumnIds.length == 1 &&
            this.getColumnApi().hasNumberDataType(scope.ColumnIds[0]));
    }
    isSingleBooleanColumnScope(scope) {
        return (this.scopeHasColumns(scope) &&
            !this.scopeHasDataType(scope) &&
            !this.scopeIsAll(scope) &&
            'ColumnIds' in scope &&
            scope.ColumnIds.length == 1 &&
            this.getColumnApi().hasBooleanDataType(scope.ColumnIds[0]));
    }
    areAllBooleanColumnsInScope(scope) {
        return (this.scopeHasColumns(scope) &&
            !this.scopeHasDataType(scope) &&
            !this.scopeIsAll(scope) &&
            'ColumnIds' in scope &&
            scope.ColumnIds.length &&
            scope.ColumnIds.every((columnId) => this.getColumnApi().hasBooleanDataType(columnId)));
    }
    isColumnInScopeColumns(column, scope) {
        return this.scopeHasColumns(scope) && this.isColumnInScope(column, scope);
    }
    isPrimaryKeyColumnInScopeColumns(scope) {
        return ('ColumnIds' in scope &&
            scope.ColumnIds.length == 1 &&
            scope.ColumnIds.find((c) => c == this.getOptions().primaryKey) != null);
    }
    getScopeToString(scope) {
        if ('All' in scope) {
            return 'Columns: All';
        }
        if ('ColumnTypes' in scope) {
            return 'ColumnTypes: ' + scope.ColumnTypes.join(',');
        }
        if ('DataTypes' in scope) {
            return 'DataTypes: ' + scope.DataTypes.join(',');
        }
        if ('ColumnIds' in scope) {
            let text = scope.ColumnIds.length == 1 ? 'Column: ' : 'Columns: ';
            return (text +
                this.getAdaptableApi()
                    .columnApi.getFriendlyNamesForColumnIds(scope.ColumnIds)
                    .map((c) => {
                    return '"' + c + '"';
                })
                    .join(', '));
        }
    }
    getColumnIdsInScope(scope) {
        if (scope !== undefined && 'ColumnIds' in scope) {
            return scope.ColumnIds;
        }
        return undefined;
    }
    getColumnTypesInScope(scope) {
        if (scope !== undefined && 'ColumnTypes' in scope) {
            return scope.ColumnTypes;
        }
        return undefined;
    }
    getDataTypesInScope(scope) {
        if (scope !== undefined && 'DataTypes' in scope) {
            return scope.DataTypes;
        }
        return undefined;
    }
    isColumnInNumericScope(column, scope) {
        // if column is not even numeric then return false
        if (column == null || column == undefined || column.dataType !== 'number') {
            return false;
        }
        // if no scope then return false
        if (scope == undefined) {
            return false;
        }
        // check if the scope has ColumnIds and whether this column is contained
        if ('ColumnIds' in scope && scope.ColumnIds.includes(column.columnId)) {
            return true;
        }
        // check if the scope has ColumnIds and whether this column is contained
        if ('DataTypes' in scope && scope.DataTypes.includes('number')) {
            return true;
        }
        if ('ColumnTypes' in scope &&
            scope.ColumnTypes?.some?.((scopeColumnType) => column.columnTypes?.includes?.(scopeColumnType))) {
            return true;
        }
        return false;
    }
    isColumnInTextScope(column, scope) {
        // if column is not even string then return false
        if (column == null || column == undefined || column.dataType !== 'text') {
            return false;
        }
        // if no scope then return false
        if (scope == undefined) {
            return false;
        }
        // check if the scope has ColumnIds and whether this column is contained
        if ('ColumnIds' in scope && scope.ColumnIds.includes(column.columnId)) {
            return true;
        }
        // check if the scope has ColumnIds and whether this column is contained
        if ('DataTypes' in scope && scope.DataTypes.includes('text')) {
            return true;
        }
        if ('ColumnTypes' in scope &&
            scope.ColumnTypes?.some?.((scopeColumnType) => column.columnTypes?.includes?.(scopeColumnType))) {
            return true;
        }
        return false;
    }
    isColumnInDateScope(column, scope) {
        // if column is not even numeric then return false
        if (column == null || column == undefined || column.dataType !== 'date') {
            return false;
        }
        // if no scope then return false
        if (scope == undefined) {
            return false;
        }
        // check if the scope has ColumnIds and whether this column is contained
        if ('ColumnIds' in scope && scope.ColumnIds.includes(column.columnId)) {
            return true;
        }
        // check if the scope has ColumnIds and whether this column is contained
        if ('DataTypes' in scope && scope.DataTypes.includes('date')) {
            return true;
        }
        if ('ColumnTypes' in scope &&
            scope.ColumnTypes?.some?.((scopeColumnType) => column.columnTypes?.includes?.(scopeColumnType))) {
            return true;
        }
        return false;
    }
    isScopeInScope(a, b) {
        // AFL: Scope:'All' for object 'a' is NOT handled
        // this is probably wrong, but we will touch it when a bug is filed
        if ('All' in b) {
            return true;
        }
        if ('DataTypes' in a &&
            'DataTypes' in b &&
            a.DataTypes.every((type) => b.DataTypes.includes(type))) {
            return true;
        }
        if ('ColumnIds' in a &&
            'ColumnIds' in b &&
            a.ColumnIds.every((columnId) => b.ColumnIds.includes(columnId))) {
            return true;
        }
        if ('ColumnIds' in a &&
            'DataTypes' in b &&
            a.ColumnIds.every((columnId) => {
                return b.DataTypes.includes(this.getColumnApi().getColumnWithColumnId(columnId)?.dataType);
            })) {
            return true;
        }
        if ('ColumnTypes' in a &&
            'ColumnTypes' in b &&
            a.ColumnTypes.every((columnType) => b.ColumnTypes.includes(columnType))) {
            return true;
        }
        // check if each colum in a has column types in b
        if ('ColumnIds' in a && 'ColumnTypes' in b) {
            const inScope = a.ColumnIds.every((columnId) => {
                const column = this.getColumnApi().getColumnWithColumnId(columnId);
                // check if at least one column-type is in scope
                return column.columnTypes.some((columnColumnType) => b.ColumnTypes.includes(columnColumnType));
            });
            if (inScope) {
                return true;
            }
        }
        return false;
    }
    createCellColorRangesForScope(scope) {
        let distinctColumnsValues = this.getGridApi().internalApi.getDistinctRawValuesForColumn(this.getSingleColumnInScope(scope));
        let minValue = Math.min(...distinctColumnsValues);
        let maxValue = Math.max(...distinctColumnsValues);
        const ranges = [];
        if (this.distinctColumnValuesAreEmpty(distinctColumnsValues)) {
            ranges.push({
                Min: 0,
                Max: 0,
                Color: (0, UIHelper_1.getHexForName)(UIHelper_1.GRAY),
            });
        }
        if (minValue < 0) {
            ranges.push({
                Min: minValue,
                Max: 0,
                Color: (0, UIHelper_1.getHexForName)(UIHelper_1.RED),
            });
        }
        if (maxValue > 0) {
            ranges.push({
                Min: 0,
                Max: maxValue,
                Color: (0, UIHelper_1.getHexForName)(UIHelper_1.DARK_GREEN),
            });
        }
        return ranges;
    }
    distinctColumnValuesAreEmpty(distinctColumnsValues) {
        if (ArrayExtensions_1.default.IsNullOrEmpty(distinctColumnsValues)) {
            return true;
        }
        if (distinctColumnsValues.length === 1 && String(distinctColumnsValues[0]) == '') {
            return true;
        }
        return false;
    }
}
exports.ColumnScopeApiImpl = ColumnScopeApiImpl;
