"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
var Utils_1 = __importDefault(require("../Utils"));
var Helpers_1 = __importDefault(require("../Helpers"));
var Types;
(function (Types) {
    Types["String"] = "string";
    Types["Number"] = "number";
    Types["Date"] = "date";
})(Types || (Types = {}));
var Parser = /** @class */ (function () {
    function Parser() {
        this.grouped = false;
        this.filters = [];
        this.sorting = null;
        this.content = [[]];
        this.groupedContent = [[]];
        this.columnDefinitions = [];
        this.visibleGroups = [];
        this.groupTagged = false;
        this.helpers = new Helpers_1.default();
        this.utils = new Utils_1.default();
        this.defaultCellStyle = this.utils.getDefaultCellStyle();
    }
    Parser.prototype.toggleGroup = function (index) {
        if (this.visibleGroups.indexOf(index) > -1) {
            this.visibleGroups.splice(this.visibleGroups.indexOf(index), 1);
        }
        else {
            this.visibleGroups.push(index);
        }
    };
    Parser.prototype.parse = function () {
        var _this = this;
        if (!this.columnDefinitions.length) {
            throw new Error('No column definitions found');
        }
        var content = [];
        var rowIndex = 0;
        // TODO table header
        var row = [];
        this.columnDefinitions.forEach(function (definition, colIndex) {
            var data = {};
            data[definition.field] = definition.name;
            var cell = _this.createCell({
                definition: definition,
                data: data,
                col: colIndex,
                row: rowIndex,
                header: true,
                expanded: _this.visibleGroups.indexOf(-1) > -1,
                group: -1,
                groupIndex: -1,
                value: definition.name,
            });
            row.push(cell);
        });
        content.push(row);
        rowIndex++;
        // sort?
        var tmpContent = this.applyFilters();
        if (tmpContent.length)
            tmpContent = this.applySorting(tmpContent);
        // table rows
        tmpContent.forEach(function (group, groupIndex) {
            group.forEach(function (data, index) {
                // row
                var row = [];
                // check if group is expanded
                var expanded = _this.groupTagged ? _this.visibleGroups.indexOf(data._group) > -1 : _this.visibleGroups.indexOf(groupIndex) > -1;
                if (index > 0 && !expanded)
                    return;
                // check if parents visible. ergh!
                if (_this.groupTagged && data._group && _this.visibleGroups.indexOf(data._group) > -1) {
                    var indexes_1 = data._group_index.split('-');
                    indexes_1.pop();
                    var group_1 = '';
                    var visible_1 = true;
                    indexes_1.forEach(function (index, i) {
                        group_1 = indexes_1.slice(0, i + 1).join('-');
                        if (_this.visibleGroups.indexOf(group_1) < 0)
                            visible_1 = false;
                    });
                    if (!visible_1)
                        return;
                }
                _this.columnDefinitions.forEach(function (definition, colIndex) {
                    if (_this.groupTagged) {
                        expanded = _this.visibleGroups.indexOf(data._group_index) > -1;
                    }
                    var cell = _this.createCell({
                        data: data,
                        definition: definition,
                        row: rowIndex,
                        col: colIndex,
                        group: groupIndex,
                        groupIndex: index,
                        expanded: expanded,
                        header: false,
                        value: '',
                    });
                    row.push(cell);
                });
                content.push(row);
                rowIndex++;
            });
        });
        // headers
        // content
        return content;
    };
    Parser.prototype.setDefaultCellStyleProperties = function (style) {
        this.defaultCellStyle = Object.assign(this.defaultCellStyle, style);
    };
    Parser.prototype.setColumnDefinitions = function (definitions) {
        var _this = this;
        if (definitions === void 0) { definitions = []; }
        this.columnDefinitions = [];
        definitions.forEach(function (definition) {
            if (definition.disabled)
                return;
            _this.columnDefinitions.push(definition instanceof ParserColumnDefinition ? definition : new ParserColumnDefinition(definition, _this.defaultCellStyle));
        });
    };
    Parser.prototype.headerRenderer = function (params) {
        return null;
    };
    Parser.prototype.cellRenderer = function (params) {
        return null;
    };
    Parser.prototype.createCell = function (params) {
        var value = params.data[params.definition.field] === undefined ? params.definition.getDefaultValue() : params.data[params.definition.field];
        params.value = value;
        var cell = {
            data: params.data,
            id: params.definition.id,
            value: value,
            style: Object.assign({}, params.definition.cellStyle),
            index: {
                row: params.row,
                col: params.col,
            },
            button: undefined,
            group: params.group,
            groupIndex: params.groupIndex,
            definition: params.definition,
        };
        // updated value
        params.value = cell.value;
        // custom cell renderer
        if (params.header) {
            cell = this.mergeCells(cell, this.headerRenderer(params));
        }
        else if (!params.definition.ignoreCellRenderer) {
            cell = this.mergeCells(cell, this.cellRenderer(params));
        }
        // custom column renderer
        if (!params.header) {
            cell = this.mergeCells(cell, params.definition.render(params));
        }
        // value
        cell.formatted_value = cell.value;
        return cell;
    };
    Parser.prototype.applySorting = function (content) {
        if (!this.sorting || !this.sorting.enabled) {
            return content;
        }
        var sorting = this.sorting;
        var exp = sorting.direction.toUpperCase() === 'DESC' ? '>' : '<';
        var opp = sorting.direction.toUpperCase() === 'DESC' ? '<' : '>';
        return content.concat().sort(function (a, b) {
            var aData = a[0];
            var bData = b[0];
            if (!sorting || !aData[sorting.field] || !bData[sorting.field]) {
                return 1;
            }
            var aValue = aData[sorting.field];
            var bValue = bData[sorting.field];
            var aVal = sorting.type === 'number' ? parseFloat(aValue) || 0 : "\"" + aValue + "\"";
            var bVal = sorting.type === 'number' ? parseFloat(bValue) || 0 : "\"" + bValue + "\"";
            if (eval(aVal + " " + exp + " " + bVal)) {
                return -1;
            }
            if (eval(aVal + " " + opp + " " + bVal)) {
                return 1;
            }
            return 0;
        });
    };
    Parser.prototype.applyFilters = function () {
        // let originalData = JSON.parse(JSON.stringify(content));
        if (!this.groupedContent.length || !Object.keys(this.filters).length) {
            return this.groupedContent;
        }
        // let data = [];
        var groupsToRemove = [];
        var content = this.groupedContent.concat();
        // let rowOffset = this.Grid.Settings.headings ? 1 : 0;
        for (var rowIndex = 0; rowIndex < this.groupedContent.length; rowIndex++) {
            var _loop_1 = function (f) {
                var filter = this_1.filters[f];
                var data = this_1.groupedContent[rowIndex][0];
                // if (!col || rowsToRemove.indexOf(rowIndex) > -1) continue;
                if (data[filter.field] === undefined) {
                    groupsToRemove.push(rowIndex);
                    return "continue";
                }
                var colValue = filter.type === 'number' ? parseFloat(data[filter.field]) : "" + data[filter.field];
                var filterValue = filter.type === 'number' ? parseFloat(filter.value) : "" + filter.value;
                var validValue = false;
                switch (filter.type) {
                    case 'number':
                        validValue = eval(colValue + " " + filter.exp + " " + filterValue);
                        break;
                    case 'date':
                        var dates = filterValue.split(',');
                        var fromDate = new Date(dates[0]).toISOString();
                        var toDate = new Date(dates[1]).toISOString();
                        var date = new Date(this_1.helpers.parseDateExcel(colValue)).toISOString();
                        validValue = date >= fromDate && date <= toDate;
                        break;
                    default:
                        filterValue.split(',').forEach(function (value) {
                            if (validValue) {
                                return;
                            }
                            switch (filter.exp) {
                                case 'contains':
                                    validValue = colValue.toLowerCase().indexOf(value.toLowerCase()) > -1;
                                    break;
                                case 'starts_with':
                                    validValue = colValue.toLowerCase().substring(0, value.length) === value.toLowerCase();
                                    break;
                                case '!=':
                                    validValue = colValue != value; // eval(`"${colValue}" == "${value}"`);
                                    break;
                                default:
                                    validValue = colValue == value; // eval(`"${colValue}" == "${value}"`);
                                    break;
                            }
                        });
                        break;
                }
                if (!validValue && groupsToRemove.indexOf(rowIndex) < 0)
                    groupsToRemove.push(rowIndex);
            };
            var this_1 = this;
            for (var f in this.filters) {
                _loop_1(f);
            }
        }
        for (var i = groupsToRemove.length - 1; i >= 0; i--)
            content.splice(groupsToRemove[i], 1);
        return content;
        // return data;
    };
    Parser.prototype.mergeCells = function (cell, overides) {
        if (!overides)
            return cell;
        if (overides.style) {
            cell.style = Object.assign({}, cell.style, overides.style);
            delete overides.style;
        }
        if (overides.button) {
            cell.button = Object.assign({}, cell.button, overides.button);
            delete overides.button;
        }
        return Object.assign({}, cell, overides);
    };
    return Parser;
}());
exports.Parser = Parser;
var ParserColumnDefinition = /** @class */ (function () {
    function ParserColumnDefinition(data, styleDefaults) {
        var _this = this;
        this.id = false;
        this.disabled = false;
        this.name = '';
        this.field = '';
        this.type = '';
        this.width = 64;
        this.columnStyle = {
            width: "64px",
        };
        this.cellStyle = {
            width: "64px",
        };
        this.defaultValue = null;
        this.enumValues = {};
        this.ignoreCellRenderer = false;
        if (!data)
            return;
        var styles = Utils_1.default.DEFAULT_CELL_STYLE;
        if (styleDefaults) {
            styles = Object.assign({}, styles, styleDefaults);
        }
        Object.keys(styles).forEach(function (key) {
            _this.columnStyle[key] = styles[key];
            _this.cellStyle[key] = styles[key];
        });
        ['id', 'name', 'field', 'type', 'width', 'enumValues', 'defaultValue', 'render', 'ignoreCellRenderer', 'disabled'].forEach(function (key) {
            if (data[key] === undefined)
                return;
            _this[key] = data[key];
        });
        if (data.columnStyle) {
            this.columnStyle = Object.assign({}, this.columnStyle, data.columnStyle);
        }
        this.columnStyle.width = this.width + "px";
        if (data.cellStyle) {
            this.cellStyle = Object.assign({}, this.cellStyle, data.cellStyle);
        }
        this.cellStyle.width = this.width + "px";
    }
    ParserColumnDefinition.prototype.render = function (params) {
        return null;
    };
    ParserColumnDefinition.prototype.getDefaultValue = function () {
        return this.defaultValue === null ? '#ERROR!' : this.defaultValue;
    };
    return ParserColumnDefinition;
}());
exports.ParserColumnDefinition = ParserColumnDefinition;
var ParserWrapper = /** @class */ (function () {
    function ParserWrapper() {
        return Parser;
    }
    return ParserWrapper;
}());
exports.ParserWrapper = ParserWrapper;
//# sourceMappingURL=Parser.js.map