var __extends = (this && this.__extends) || (function () {
    var extendStatics = function (d, b) {
        extendStatics = Object.setPrototypeOf ||
            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
            function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
        return extendStatics(d, b);
    };
    return function (d, b) {
        if (typeof b !== "function" && b !== null)
            throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
    if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
import { Component, Input, Output } from "@angular/core";
import { PageElement } from "../page-element";
import { KeyUtility } from "../../../utility/key-utility";
import { Button } from "../button/button.component";
import { FocusUtility } from "../../../form/focus-utility";
import { Subject } from "rxjs";
import { debounceTime } from "rxjs/operators";
var ListComponent = /** @class */ (function () {
    function ListComponent() {
    }
    ListComponent.prototype.ngAfterViewInit = function () {
        FocusUtility.focusFirstField(null);
    };
    __decorate([
        Input("list"),
        Output("list"),
        __metadata("design:type", List)
    ], ListComponent.prototype, "list", void 0);
    ListComponent = __decorate([
        Component({
            selector: "path-list",
            templateUrl: "list.component.html"
        })
    ], ListComponent);
    return ListComponent;
}());
export { ListComponent };
var List = /** @class */ (function (_super) {
    __extends(List, _super);
    function List(app, pathService, translationService) {
        var _this = _super.call(this, app) || this;
        _this.pathService = pathService;
        _this.translationService = translationService;
        _this._buttonGroups = [];
        _this._searchTextChanged = new Subject();
        _this._searchLabel = translationService.getText("Search");
        _this._searchInputLabel = translationService.getText("SearchInputLabel");
        _this._searchButton = new Button(app, pathService, translationService);
        return _this;
    }
    List.prototype.getContent = function () {
        var buttons = [];
        for (var _i = 0, _a = this.buttonGroups; _i < _a.length; _i++) {
            var buttonGroup = _a[_i];
            buttons.push.apply(buttons, buttonGroup.buttons);
        }
        return buttons;
    };
    List.prototype.refresh = function (searchText, afterRefreshHandler) {
        var _this = this;
        // callback function for data
        console.log("refresh list (searchText: " + searchText + ")");
        var dataHandler = function (data) {
            _this.buttonGroups = [];
            for (var _i = 0, data_1 = data; _i < data_1.length; _i++) {
                var item = data_1[_i];
                // create button group and buttons
                // set default types if server does not set type (button or buttonGroup)
                var itemIsButtonGroup = item.hasOwnProperty("buttons");
                if (itemIsButtonGroup) {
                    item["type"] = "buttonGroup";
                    for (var _a = 0, _b = item.buttons; _a < _b.length; _a++) {
                        var button = _b[_a];
                        if (button["type"] == null) {
                            button["type"] = "button";
                        }
                    }
                }
                else {
                    if (item["type"] == null) {
                        item["type"] = "button";
                    }
                }
                var pageElements = _this.app.createPageElement(item, _this.parentPageElement, null);
                if (pageElements.length !== 1) {
                    console.log("error creating button group from: ");
                    console.log(item);
                }
                else {
                    var buttonGroup = pageElements[0];
                    var buttonCounter = 0;
                    for (var _c = 0, _d = buttonGroup.buttons; _c < _d.length; _c++) {
                        var button = _d[_c];
                        button.listElement = true;
                        // model is either simple button or button of a group
                        var buttonModel = item;
                        if (itemIsButtonGroup) {
                            buttonModel = item.buttons[buttonCounter];
                        }
                        // build button from json
                        // use list defaults if button does not specify model
                        if (buttonModel["icon"] == null) {
                            buttonModel["icon"] = _this.icon;
                        }
                        if (buttonModel["color"] == null) {
                            buttonModel["color"] = _this.color;
                        }
                        if (buttonModel["page"] == null && (buttonModel["form"] == null || buttonModel["form"]["form"] == null)) {
                            // service does not return page or form, use static model
                            if (_this.page != null) {
                                buttonModel["page"] = _this.page;
                            }
                            if (_this.form != null) {
                                buttonModel["form"] = {};
                                buttonModel.form["form"] = _this.form;
                                buttonModel.form["handler"] = _this.formHandler;
                            }
                        }
                        // special default width (2 instead of 1) for buttons in list
                        if (buttonModel["width"] == null) {
                            buttonModel["width"] = _this.width;
                        }
                        button.fromJson(buttonModel);
                        // special values for list buttons
                        button.handler = _this._buttonHandler;
                        button.name = buttonModel.name; // no translation
                        button.tooltip = buttonModel.tooltip; // no translation
                        buttonCounter++;
                    }
                    _this.buttonGroups.push(buttonGroup);
                }
            }
            if (_this.handler != null) {
                _this.handler.doLoad(_this); // TODO useful?
            }
            // refresh search
            _this.filterVisibleButtonGroups();
            if (_this.limit) {
                _this.setSearchResultsCountMessage();
            }
            if (afterRefreshHandler != null) {
                window.setTimeout(function () {
                    afterRefreshHandler();
                }, 1);
            }
        };
        var listHandlerDoLoad = function (list) { return function (data) { return dataHandler(data); }; };
        // backend data
        if (this._url != null) {
            var urlParameters = "";
            if (this.searchRequest || this.limit) {
                urlParameters = "?search=" + (searchText == null ? "" : encodeURI(searchText)) + "&limit=" + this.limit;
            }
            this.pathService.serverGet(this.app.getBackendUrl(), this.url + urlParameters, listHandlerDoLoad(this), null);
        }
        // mock data
        if (this._mockData != null) {
            var count = 0;
            // fake a key for mock data
            for (var _i = 0, _a = this.mockData; _i < _a.length; _i++) {
                var mock = _a[_i];
                count++;
                if (mock["key"] == null) {
                    mock["key"] = count;
                }
            }
            dataHandler(this.mockData);
        }
    };
    List.prototype.filterChanged = function (text) {
        this._searchTextChanged.next(text);
    };
    List.prototype.filter = function () {
        this._searchLabel = this.translationService.getText("Search");
        if (this._searchText && this._searchText === "*") {
            this.refresh(null, null);
        }
        else if (this.searchRequest) {
            // call server to filter data
            if (!this._searchText && this.searchRequired) {
                this._buttonGroups = [];
            }
            else if (this._searchText === "*" || (!this._searchText && !this.searchRequired)) {
                this.refresh(null, null);
            }
            else if (this._searchText && this._searchText.length >= 2) {
                this.refresh(this._searchText, null);
            }
            else {
                this._searchLabel = this.translationService.getText("SearchTextTooShort");
                this._buttonGroups = [];
            }
        }
        else {
            // filter loaded data only
            this.filterVisibleButtonGroups();
        }
    };
    List.prototype.filterVisibleButtonGroups = function () {
        var searchText = this._searchText ? this._searchText.toLowerCase() : "";
        for (var _i = 0, _a = this._buttonGroups; _i < _a.length; _i++) {
            var buttonGroup = _a[_i];
            if (searchText.length <= 0) {
                buttonGroup.visible = true;
            }
            else {
                buttonGroup.visible = false;
                for (var _b = 0, _c = buttonGroup.buttons; _b < _c.length; _b++) {
                    var button = _c[_b];
                    if (!buttonGroup.visible) {
                        buttonGroup.visible = button.name.toLowerCase().indexOf(searchText) !== -1;
                        if (!buttonGroup.visible) {
                            for (var _d = 0, _e = button.details; _d < _e.length; _d++) {
                                var detail = _e[_d];
                                if (detail.text.toLowerCase().indexOf(searchText) !== -1) {
                                    buttonGroup.visible = true;
                                    break;
                                }
                            }
                        }
                    }
                }
            }
        }
        if (this.visibleItemSize() !== this.buttonGroups.length) {
            this.setSearchResultsCountMessage();
        }
    };
    List.prototype.setSearchResultsCountMessage = function () {
        this._searchLabel = this.visibleItemSize() + " " +
            (this.visibleItemSize() === 1 ? this.translationService.getText("Result") : this.translationService.getText("Results"));
    };
    List.prototype.visibleItemSize = function () {
        var result = 0;
        for (var _i = 0, _a = this.buttonGroups; _i < _a.length; _i++) {
            var buttonGroup = _a[_i];
            if (buttonGroup.visible) {
                for (var _b = 0, _c = buttonGroup.buttons; _b < _c.length; _b++) {
                    var button = _c[_b];
                    if (button.visible) {
                        result++;
                        break;
                    }
                }
            }
        }
        return result;
    };
    Object.defineProperty(List.prototype, "buttonGroups", {
        get: function () {
            return this._buttonGroups;
        },
        set: function (value) {
            this._buttonGroups = value;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(List.prototype, "search", {
        get: function () {
            return this._search;
        },
        set: function (value) {
            this._search = value;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(List.prototype, "handler", {
        get: function () {
            return this._handler;
        },
        set: function (value) {
            this._handler = value;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(List.prototype, "buttonHandler", {
        get: function () {
            return this._buttonHandler;
        },
        set: function (value) {
            this._buttonHandler = value;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(List.prototype, "icon", {
        get: function () {
            return this._icon;
        },
        set: function (value) {
            this._icon = value;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(List.prototype, "color", {
        get: function () {
            return this._color;
        },
        set: function (value) {
            this._color = value;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(List.prototype, "form", {
        get: function () {
            return this._form;
        },
        set: function (value) {
            this._form = value;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(List.prototype, "formHandler", {
        get: function () {
            return this._formHandler;
        },
        set: function (value) {
            this._formHandler = value;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(List.prototype, "page", {
        get: function () {
            return this._page;
        },
        set: function (value) {
            this._page = value;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(List.prototype, "mockData", {
        get: function () {
            return this._mockData;
        },
        set: function (value) {
            this._mockData = value;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(List.prototype, "url", {
        get: function () {
            return this._url;
        },
        set: function (value) {
            this._url = value;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(List.prototype, "limit", {
        get: function () {
            return this._limit;
        },
        set: function (value) {
            this._limit = value;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(List.prototype, "searchRequired", {
        get: function () {
            return this._searchRequired;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(List.prototype, "searchRequest", {
        get: function () {
            return this._searchRequest;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(List.prototype, "searchText", {
        get: function () {
            return this._searchText;
        },
        set: function (value) {
            this._searchText = value;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(List.prototype, "searchLabel", {
        get: function () {
            return this._searchLabel;
        },
        set: function (value) {
            this._searchLabel = value;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(List.prototype, "searchInputLabel", {
        get: function () {
            return this._searchInputLabel;
        },
        set: function (value) {
            this._searchInputLabel = value;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(List.prototype, "searchButton", {
        get: function () {
            return this._searchButton;
        },
        enumerable: false,
        configurable: true
    });
    List.prototype.fromJson = function (modelElement) {
        var _this = this;
        _super.prototype.fromJson.call(this, modelElement);
        if (modelElement["search"] != null) {
            this.search = modelElement["search"];
        }
        if (modelElement["searchRequired"] != null) {
            this._searchRequired = modelElement["searchRequired"];
        }
        if (modelElement["searchRequest"] != null) {
            this._searchRequest = modelElement["searchRequest"];
        }
        if (modelElement["limit"] != null) {
            this.limit = modelElement["limit"];
        }
        // verify valid search combinations
        if (!this.search && this.searchRequired) {
            console.log("Configuration Error: search=false requires searchRequired=false");
            this._searchRequired = false;
        }
        if (this.searchRequired && !this.searchRequest) {
            console.log("Configuration Error: searchRequired=true requires searchRequest=true");
            this._searchRequest = true;
        }
        // other model attributes
        if (modelElement["color"] != null) {
            this.color = modelElement["color"];
        }
        if (modelElement["form"] != null) {
            this.form = modelElement["form"]["form"];
            this.formHandler = modelElement["form"]["handler"];
        }
        if (modelElement["page"] != null) {
            this.page = modelElement["page"];
        }
        if (modelElement["icon"] != null) {
            this.icon = modelElement["icon"];
        }
        if (modelElement["data"] != null) {
            this.mockData = modelElement["data"];
        }
        if (modelElement["name"] != null) {
            this.name = this.translationService.getText(modelElement["name"]);
        }
        if (modelElement["url"] != null) {
            var urlString = modelElement["url"];
            this.url = KeyUtility.translateUrl(urlString, null, false, this);
        }
        // override from PageElement
        if (modelElement["width"] != null) {
            this.width = modelElement["width"];
        }
        else {
            this.width = 2; // special default for list
        }
        // search button
        var searchButtonModel = {};
        searchButtonModel["color"] = modelElement["searchColor"] != null ? modelElement["searchColor"] : "tile-search";
        searchButtonModel["width"] = modelElement["searchWidth"] != null ? modelElement["searchWidth"] : this.width;
        this._searchButton.fromJson(searchButtonModel);
        // delay for search field
        var debounceTimeValue = this.searchRequest ? 300 : 30;
        this._searchTextChanged.pipe(debounceTime(debounceTimeValue)) // wait after the last event before emitting last event
            .subscribe(function (_searchText) {
            _this._searchText = _searchText;
            _this.filter();
        });
    };
    return List;
}(PageElement));
export { List };
//# sourceMappingURL=list.component.js.map