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, ElementRef } from "@angular/core";
import { ValueField } from "../value-field";
import { AutoCompleteFieldEntry } from "./auto-complete-field-entry";
import { Key } from "../../../page/element/page-element";
import { FormFunction } from "../../form-function";
import { KeyUtility } from "../../../utility/key-utility";
var AutoCompleteComponent = /** @class */ (function () {
    function AutoCompleteComponent(myElement) {
        this._elementRef = myElement;
    }
    AutoCompleteComponent.prototype.handleClick = function (event) {
        if (this.field.isReadonly()) {
            return;
        }
        var clickedComponent = event.target;
        var inside = false;
        do {
            if (clickedComponent === this._elementRef.nativeElement) {
                inside = true;
            }
            clickedComponent = clickedComponent.parentNode;
        } while (clickedComponent);
        if (!inside) {
            this.field.clearFilteredList();
        }
        if (!this.field.valueSet) {
            this.field.query = null;
            this.field.setValue(null);
        }
    };
    __decorate([
        Input("field"),
        Output("field"),
        __metadata("design:type", AutoCompleteField)
    ], AutoCompleteComponent.prototype, "field", void 0);
    AutoCompleteComponent = __decorate([
        Component({
            selector: "path-autocomplete",
            // tslint:disable-next-line
            host: {
                "(document:click)": "handleClick($event)",
            },
            templateUrl: "auto-complete-field.component.html"
        }),
        __metadata("design:paramtypes", [ElementRef])
    ], AutoCompleteComponent);
    return AutoCompleteComponent;
}());
export { AutoCompleteComponent };
var AutoCompleteField = /** @class */ (function (_super) {
    __extends(AutoCompleteField, _super);
    function AutoCompleteField(form, translationService, pathService) {
        var _this = _super.call(this, form, translationService) || this;
        _this.form = form;
        _this.translationService = translationService;
        _this.pathService = pathService;
        _this._filteredList = [];
        _this._data = [];
        _this._dataLoaded = false;
        _this._valueSet = false;
        return _this;
    }
    AutoCompleteField.prototype.isReadonly = function () {
        return _super.prototype.isReadonly.call(this) && this.isInitialValueSet;
    };
    AutoCompleteField.prototype.filter = function (query, event) {
        // do not filter readonly fields
        if (this.isReadonly()) {
            return;
        }
        // do not filter on simple tab focus change
        if (event.keyCode === 9) {
            return;
        }
        this._valueSet = false;
        if (query !== null && query.length > 0 && query.replace(/\s/g, "").length === 0) {
            /* space: all */
            this._filteredList = this._data.filter(function (entry) {
                return entry.active;
            }.bind(this));
        }
        else if (query !== null && query !== "") {
            /* search term: filter */
            query = query.trim();
            this._filteredList = this._data.filter(function (entry) {
                if (!entry.active) {
                    return false;
                }
                var entryName = entry.text;
                if (entryName.toLowerCase().indexOf(query.toLowerCase()) > -1) {
                    return true;
                }
                else if (this._wordSearchEnabled) {
                    var tokens = entryName.toLowerCase().split(" ");
                    for (var _i = 0, tokens_1 = tokens; _i < tokens_1.length; _i++) {
                        var token = tokens_1[_i];
                        if (token.startsWith(query.toLowerCase())) {
                            return true;
                        }
                    }
                }
                return false;
            }.bind(this));
        }
        else {
            /* empty: nothing */
            this.clearFilteredList();
        }
        this._filteredList.sort();
    };
    AutoCompleteField.prototype.select = function (item) {
        this.setValue(item.key);
    };
    AutoCompleteField.prototype.focusLost = function () {
        var _this = this;
        window.setTimeout(function () {
            if (!_this.valueSet) {
                // force angular to update query.text value
                if (_this.value == null) {
                    _this.resetDisplay(null);
                }
                else {
                    _this.resetDisplay(_this.value["key"]);
                }
            }
        }, 1);
    };
    AutoCompleteField.prototype.setValue = function (value) {
        var oldValue = this.value;
        // accept key values and complex objects
        if (value != null && value["key"] != null) {
            value = value["key"];
            this._keyType = value["name"];
        }
        this._valueSet = value != null;
        this.clearFilteredList();
        _super.prototype.setValue.call(this, value);
        this.query = null;
        this.resetDisplay(value);
        // reload dependent autocomplete fields
        if (oldValue !== this.value) {
            for (var _i = 0, _a = this.getForm().getFields(); _i < _a.length; _i++) {
                var field = _a[_i];
                if (field instanceof AutoCompleteField) {
                    if (field.id !== this.id) {
                        var autoCompleteField = field;
                        if (KeyUtility.variableExists(autoCompleteField.url, this.id)) {
                            autoCompleteField.load();
                        }
                    }
                }
            }
        }
    };
    AutoCompleteField.prototype.load = function () {
        var _this = this;
        this.dataLoaded = false;
        var url = this.url;
        for (var _i = 0, _a = this.getForm().getFields(); _i < _a.length; _i++) {
            var field = _a[_i];
            if (field instanceof ValueField) {
                var valueField = field;
                url = KeyUtility.replaceVariable(url, valueField.id, valueField.value);
                console.log(url);
            }
        }
        this.pathService.serverGet(this.getForm().getApp().getBackendUrl(), url, function (data) {
            var dynamicData = [];
            for (var _i = 0, data_1 = data; _i < data_1.length; _i++) {
                var item = data_1[_i];
                var entry = new AutoCompleteFieldEntry();
                entry.key = item["key"]["key"];
                entry.text = item["name"];
                if (item["active"] != null) {
                    entry.active = item["active"];
                }
                else {
                    entry.active = true;
                }
                dynamicData.push(entry);
            }
            _this.data = dynamicData;
            _this.dataLoaded = true;
            _this.setValue(_this.value); // force display refresh
        }, null);
    };
    AutoCompleteField.prototype.getDetailButtonName = function () {
        if (this.value == null) {
            return this.translationService.getText("New") + "...";
        }
        else {
            return this.translationService.getText("Detail") + "...";
        }
    };
    AutoCompleteField.prototype.showDetailForm = function () {
        var _this = this;
        var form = null;
        var formFunction = new FormFunction();
        formFunction.save = function (data) {
            _this.getForm().getApp().closeCurrentForm();
            if (data["key"] != null) {
                _this.setValue(data["key"]);
            }
            _this.load();
        };
        formFunction.cancel = function () {
            _this.getForm().getApp().closeCurrentForm();
        };
        formFunction.delete = function (data) {
            _this.getForm().getApp().closeCurrentForm();
            _this.setValue(null);
            _this.load();
        };
        if (this.value == null) {
            form = this.getForm().getApp().createForm(this.detailForm, null, null, formFunction, null);
        }
        else {
            form = this.getForm().getApp().createForm(this.detailForm, new Key(this.value, this._keyType), null, formFunction, null);
        }
        this.form.getApp()["_formStack"].push(form); // TODO
    };
    AutoCompleteField.prototype.clearFilteredList = function () {
        this._filteredList = [];
    };
    AutoCompleteField.prototype.resetDisplay = function (value) {
        var _this = this;
        // must wait with display update until data is loaded
        var displaySetter = function () {
            var keyValue = value;
            if (!_this.dataLoaded) {
                console.log("waiting...");
                window.setTimeout(function () {
                    displaySetter();
                }, 250);
            }
            else {
                if (keyValue == null) {
                    window.setTimeout(function () {
                        // check value again, may have changed since reset was triggered
                        if (_this.value == null) {
                            _this.query = new AutoCompleteFieldEntry();
                        }
                    }, 1);
                }
                else {
                    var _loop_1 = function (item) {
                        // tslint:disable:triple-equals
                        if (item.key == keyValue) {
                            window.setTimeout(function () {
                                _this.query = item;
                            }, 1);
                            return "break";
                        }
                    };
                    for (var _i = 0, _a = _this._data; _i < _a.length; _i++) {
                        var item = _a[_i];
                        var state_1 = _loop_1(item);
                        if (state_1 === "break")
                            break;
                    }
                }
            }
        };
        displaySetter();
    };
    Object.defineProperty(AutoCompleteField.prototype, "query", {
        get: function () {
            return this._query;
        },
        set: function (value) {
            this._query = value;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(AutoCompleteField.prototype, "data", {
        set: function (value) {
            this._data = value;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(AutoCompleteField.prototype, "filteredList", {
        get: function () {
            return this._filteredList;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(AutoCompleteField.prototype, "wordSearchEnabled", {
        set: function (value) {
            this._wordSearchEnabled = value;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(AutoCompleteField.prototype, "valueSet", {
        get: function () {
            return this._valueSet;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(AutoCompleteField.prototype, "dataLoaded", {
        get: function () {
            return this._dataLoaded;
        },
        set: function (value) {
            this._dataLoaded = value;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(AutoCompleteField.prototype, "detailForm", {
        get: function () {
            return this._detailForm;
        },
        set: function (value) {
            this._detailForm = value;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(AutoCompleteField.prototype, "url", {
        get: function () {
            return this._url;
        },
        set: function (value) {
            this._url = value;
        },
        enumerable: false,
        configurable: true
    });
    return AutoCompleteField;
}(ValueField));
export { AutoCompleteField };
//# sourceMappingURL=auto-complete-field.component.js.map