"use strict";
var __extends = (this && this.__extends) || function (d, b) {
    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
    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);
};
var __param = (this && this.__param) || function (paramIndex, decorator) {
    return function (target, key) { decorator(target, key, paramIndex); }
};
var core_1 = require("@angular/core");
var rxjs_1 = require("rxjs");
var lodash_1 = require("lodash");
var typescript_angular_utilities_1 = require("typescript-angular-utilities");
var __object = typescript_angular_utilities_1.services.object;
var __array = typescript_angular_utilities_1.services.array;
var __guid = typescript_angular_utilities_1.services.guid;
var __transform = typescript_angular_utilities_1.services.transform;
var __search = typescript_angular_utilities_1.services.search;
var validationInput_1 = require("../validationInput");
var componentValidator_service_1 = require("../../../services/componentValidator/componentValidator.service");
var form_1 = require("../../form/form");
var busy_1 = require("../../busy/busy");
var index_1 = require("../../popoutList/index");
var input_1 = require("../input");
exports.DEFAULT_SERVER_SEARCH_DEBOUNCE = 500;
exports.DEFAULT_CLIENT_SEARCH_DEBOUNCE = 100;
var TypeaheadComponent = (function (_super) {
    __extends(TypeaheadComponent, _super);
    function TypeaheadComponent(transformService, rlForm, componentValidator, object, array, guid, searchService, changeDetector) {
        var _this = _super.call(this, rlForm, componentValidator, object, array, guid) || this;
        _this.selector = new core_1.EventEmitter();
        _this.searchStream = new rxjs_1.Subject();
        _this.loading = false;
        _this.collapsed = false;
        _this.cacheDisplayList = [];
        _this.transformService = transformService;
        _this.searchUtility = searchService;
        _this.changeDetector = changeDetector;
        _this.inputType = 'typeahead';
        _this.search = '';
        _this._visibleItems = new rxjs_1.BehaviorSubject(null);
        _this.caseSensitiveSearching = false;
        return _this;
    }
    Object.defineProperty(TypeaheadComponent.prototype, "visibleItems$", {
        get: function () {
            return this._visibleItems.asObservable();
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(TypeaheadComponent.prototype, "canShowOptions", {
        get: function () {
            return !(this.busy.loading || !this.search);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(TypeaheadComponent.prototype, "hideFlowerup", {
        get: function () {
            return !((this.search || this.value) && this.label);
        },
        enumerable: true,
        configurable: true
    });
    TypeaheadComponent.prototype.focus = function () {
        this.input.nativeElement.focus();
    };
    TypeaheadComponent.prototype.add = function (item) {
        if (this.cachedItems != null) {
            this.cachedItems.push(item);
        }
    };
    TypeaheadComponent.prototype.remove = function (item) {
        if (this.cachedItems != null) {
            this.array.remove(this.cachedItems, item);
        }
    };
    TypeaheadComponent.prototype.clear = function () {
        this.setValue(null);
        this.collapsed = false;
        this.searchStream.next('');
    };
    TypeaheadComponent.prototype.selectItem = function (item) {
        this.search = '';
        this.selector.emit(item);
        if (this.allowCollapse) {
            this.collapsed = true;
            this.setValue(item);
        }
    };
    TypeaheadComponent.prototype.selectCustom = function () {
        var newItem = this.create(this.search);
        this.selectItem(newItem);
    };
    TypeaheadComponent.prototype.refresh = function (search) {
        var _this = this;
        this.search = search;
        if (this.object.isNullOrEmpty(search)) {
            this.cacheDisplayList = [];
            return this._visibleItems.next(this.cacheDisplayList);
        }
        else {
            var loadRequest = this.loadItems(search);
            // triggers the subscription
            this.busy.waitOnObservableNext(loadRequest).subscribe(function (data) {
                if (!lodash_1.isEqual(data, _this.cacheDisplayList)) {
                    _this.list.open();
                    _this.cacheDisplayList = lodash_1.cloneDeep(data);
                    _this.changeDetector.detectChanges();
                    return _this._visibleItems.next(_this.cacheDisplayList);
                }
            });
        }
    };
    TypeaheadComponent.prototype.ngOnInit = function () {
        var _this = this;
        _super.prototype.ngOnInit.call(this);
        this.loadDelay = this.clientSearch ? exports.DEFAULT_CLIENT_SEARCH_DEBOUNCE : exports.DEFAULT_SERVER_SEARCH_DEBOUNCE;
        this.prefix = this.prefix || 'Search for';
        this.placeholder = this.label != null ? this.prefix + ' ' + this.label.toLowerCase() : 'Search';
        this.allowCustomOption = !!this.create;
        if (this.allowCollapse && !!this.value) {
            this.collapsed = true;
        }
        this.searchStream
            .do(function (search) {
            _this.busy.setBusy(!!search);
            _this.search = search;
        })
            .debounceTime(this.loadDelay)
            .do(function () { return _this.busy.setBusy(false); })
            .distinctUntilChanged()
            .subscribe(function (search) { return _this.refresh(search); });
    };
    TypeaheadComponent.prototype.ngOnChanges = function (changes) {
        _super.prototype.ngOnChanges.call(this, changes);
        if (changes.value) {
            if (changes.value.currentValue && this.allowCollapse) {
                this.collapsed = true;
            }
            else {
                this.collapsed = false;
            }
        }
    };
    TypeaheadComponent.prototype.getDisplayName = function (item) {
        return this.transformService.getValue(item, this.transform);
    };
    TypeaheadComponent.prototype.loadItems = function (search) {
        var _this = this;
        var itemsStream;
        if (!this.clientSearch) {
            itemsStream = rxjs_1.Observable.from(this.getItems(search));
        }
        else {
            itemsStream = this.getItemsClient()
                .map(function (items) {
                return _this.filter(items, search);
            });
        }
        return itemsStream;
    };
    TypeaheadComponent.prototype.getItemsClient = function () {
        var _this = this;
        if (this.cachedItems != null) {
            return new rxjs_1.BehaviorSubject(this.cachedItems);
        }
        else if (this.getItemsRequest == null) {
            this.getItemsRequest = rxjs_1.Observable.from(this.getItems());
            this.getItemsRequest.subscribe(function (items) {
                return _this.cachedItems = items;
            });
        }
        return this.getItemsRequest;
    };
    TypeaheadComponent.prototype.showCustomSearch = function (search) {
        var _this = this;
        return this.allowCustomOption
            && !lodash_1.find(this._visibleItems.getValue(), function (item) {
                return _this.getDisplayName(item) === search;
            });
    };
    TypeaheadComponent.prototype.filter = function (list, search) {
        var _this = this;
        return lodash_1.filter(list, function (item) { return _this.searchUtility.tokenizedSearch(item, search, _this.caseSensitiveSearching); });
    };
    return TypeaheadComponent;
}(validationInput_1.ValidatedInputComponent));
__decorate([
    core_1.Input(),
    __metadata("design:type", Object)
], TypeaheadComponent.prototype, "transform", void 0);
__decorate([
    core_1.Input(),
    __metadata("design:type", Object)
], TypeaheadComponent.prototype, "getItems", void 0);
__decorate([
    core_1.Input(),
    __metadata("design:type", String)
], TypeaheadComponent.prototype, "prefix", void 0);
__decorate([
    core_1.Input(),
    __metadata("design:type", Boolean)
], TypeaheadComponent.prototype, "clientSearch", void 0);
__decorate([
    core_1.Input(),
    __metadata("design:type", Boolean)
], TypeaheadComponent.prototype, "allowCollapse", void 0);
__decorate([
    core_1.Input(),
    __metadata("design:type", Object)
], TypeaheadComponent.prototype, "create", void 0);
__decorate([
    core_1.Input(),
    __metadata("design:type", Boolean)
], TypeaheadComponent.prototype, "caseSensitiveSearching", void 0);
__decorate([
    core_1.Output(),
    __metadata("design:type", core_1.EventEmitter)
], TypeaheadComponent.prototype, "selector", void 0);
__decorate([
    core_1.ViewChild('input'),
    __metadata("design:type", core_1.ElementRef)
], TypeaheadComponent.prototype, "input", void 0);
__decorate([
    core_1.ViewChild(busy_1.BusyComponent),
    __metadata("design:type", busy_1.BusyComponent)
], TypeaheadComponent.prototype, "busy", void 0);
__decorate([
    core_1.ViewChild(index_1.PopoutListComponent),
    __metadata("design:type", index_1.PopoutListComponent)
], TypeaheadComponent.prototype, "list", void 0);
__decorate([
    core_1.ContentChild(core_1.TemplateRef),
    __metadata("design:type", core_1.TemplateRef)
], TypeaheadComponent.prototype, "template", void 0);
TypeaheadComponent = __decorate([
    core_1.Component({
        selector: 'rlTypeahead',
        template: require('./typeahead.html'),
        inputs: validationInput_1.validationInputs,
        outputs: validationInput_1.baseOutputs,
        providers: [componentValidator_service_1.ComponentValidator, index_1.POPOUT_LIST_PROVIDERS],
        animations: input_1.baseAnimations,
    }),
    __param(1, core_1.Optional()),
    __metadata("design:paramtypes", [__transform.TransformService, form_1.FormComponent,
        componentValidator_service_1.ComponentValidator, __object.ObjectUtility, __array.ArrayUtility, __guid.GuidService, __search.SearchUtility, core_1.ChangeDetectorRef])
], TypeaheadComponent);
exports.TypeaheadComponent = TypeaheadComponent;
//# sourceMappingURL=data:application/json;base64, 