import { EventEmitter, ElementRef, Renderer2, ViewChild, Output, Input, Component, forwardRef, NgModule } from '@angular/core';
import { NG_VALUE_ACCESSOR, NG_VALIDATORS, FormsModule, ReactiveFormsModule } from '@angular/forms';
import { MultiLingualData } from '@rxweb/localization';
import { CommonModule } from '@angular/common';
import { RxHttp } from '@rxweb/http';

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 RxSelectComponent_1;
class SelectModel {
    constructor(key, value, active) {
        this.key = key;
        this.value = value;
        this.active = active;
    }
}
let RxSelectComponent = RxSelectComponent_1 = class RxSelectComponent extends RxHttp {
    constructor(elementRef, renderer) {
        super();
        this.elementRef = elementRef;
        this.renderer = renderer;
        this.propagateChange = () => { };
        this.inputDisabled = false;
        this.isInValid = false;
        this.dropIndex = 0;
        this.isSpinner = false;
        this.selectActive = false;
        this.blur = new EventEmitter();
        this.changed = new EventEmitter();
        this.maxLength = 500;
        this.selectPlaceholder = "";
        this.showSelectItem = true;
        this.focus = false;
        this.autoComplete = false;
        this.isObjectChanged = false;
        this.mainSource = new Array();
        this.dropSource = new Array();
        this.element = elementRef.nativeElement;
        let placeholderText = MultiLingualData.get("control.rx-select.placeholder");
        if (this.selectPlaceholder == "" && placeholderText)
            this.selectPlaceholder = this.selectConfiguration.placeholder;
    }
    set source(value) {
        if (value) {
            this.userSource = value;
            if (this.keyValueProps)
                this.setMainSource(this.userSource);
        }
    }
    set text(value) {
        if (value) {
            if (this.selectSearch && this.selectSearch.nativeElement)
                this.selectSearch.nativeElement.value = value;
            this.controlText = value;
        }
    }
    ;
    ngAfterContentInit() {
        this.checkValid(true);
        if (this.userSource && this.mainSource.length === 0)
            this.setMainSource(this.userSource);
        this.setValue();
        //if (this.focus && this.selectSearch)
        //  this.renderer.invokeElementMethod(this.selectSearch.nativeElement, "focus", []);
        if (this.maxLength && this.selectSearch)
            this.selectSearch.nativeElement.maxLength = this.maxLength;
    }
    setValue(isBlur = false, columnName = "key") {
        if (!this.autoComplete && this.currentValue && this.mainSource.length > 0) {
            var text = this.mainSource.filter(t => String(t[columnName]).toLowerCase() == this.currentValue.toLowerCase())[0];
            if (text) {
                this.writeValue(text.value);
                if (isBlur) {
                    this.updateFormValue(text.key);
                    this.selectSearch.nativeElement.value = text.value;
                }
                return true;
            }
            else {
                this.updateFormValue(undefined);
            }
            return false;
        }
        return true;
    }
    ngOnChanges(source) {
        if (source.params || source.queryParams) {
            this.isObjectChanged = true;
            this.clear();
        }
    }
    checkValid(isValid) {
        if (isValid)
            this.validTimeOutId = window.setTimeout(() => {
                for (var i = 0; i < this.element.classList.length; i++) {
                    this.isInValid = this.element.classList[i] == "ng-invalid";
                }
                window.clearTimeout(this.validTimeOutId);
                this.validTimeOutId = undefined;
            }, 500);
        else
            this.isInValid = isValid;
    }
    setMainSource(source) {
        this.mainSource = this.getTagModelSource(source);
        this.mainSource.forEach(t => this.dropSource.push(t));
        this.clearActiveTabClass();
    }
    setDropSource(source) {
        this.dropSource = new Array();
        source.forEach(t => this.dropSource.push(t));
    }
    getTagModelSource(source) {
        var textPattern = this.keyValueProps[0].split(/#/g);
        var tags = new Array();
        source.forEach(t => {
            var text = '';
            textPattern.forEach(x => {
                if (x != "")
                    if (t[x] != undefined)
                        text += t[x];
                    else
                        text += x;
            });
            tags.push(new SelectModel(t[this.keyValueProps[1]], text, false));
        });
        return tags;
    }
    resetSource(source) {
        this.userSource = source;
        this.mainSource = [];
        this.dropSource = [];
        this.setMainSource(source);
        this.currentValue = "";
        this.selectSearch.nativeElement.value = "";
        this.updateFormValue(undefined);
    }
    showItems(tags, clearExisting) {
    }
    clear(event) {
        this.selectSearch.nativeElement.value = '';
        this.onBlur(event, this.selectSearch.nativeElement.value);
        this.changed.emit({ item: this.selectedTag, text: this.currentValue });
    }
    registerOnChange(fn) {
        this.propagateChange = fn;
    }
    registerOnTouched() { }
    writeValue(value) {
        if (value) {
            this.currentValue = value;
            if (this.selectSearch && this.selectSearch.nativeElement)
                if (this.controlText)
                    this.selectSearch.nativeElement.value = this.controlText;
                else
                    this.selectSearch.nativeElement.value = value;
        }
        else {
            this.currentValue = undefined;
            if (this.selectSearch && this.selectSearch.nativeElement)
                this.selectSearch.nativeElement.value = "";
        }
    }
    caretClick(event) {
        if (this.activeTag == undefined || this.activeTag == "") {
            var t = setTimeout(() => {
                this.selectSearch.nativeElement.focus();
                this.onFocus(event);
            }, 200);
        }
    }
    onFocus(event) {
        if ((!this.userSource && this.mainSource.length === 0 && this.lookup) || (this.autoComplete) || this.isObjectChanged) {
            if ((this.currentValue && this.currentValue.length >= this.minimumCharacterSearchLength) || (!this.autoComplete)) {
                let params = [];
                if (this.params)
                    this.params.forEach(t => params.push(t));
                if (this.autoComplete && this.currentValue)
                    params.push(this.currentValue);
                this.isSpinner = true;
                this.get({ path: this.path, params: params, queryParams: this.queryParams }).subscribe((t) => {
                    this.userSource = t;
                    this.mainSource = [];
                    this.dropSource = [];
                    this.setMainSource(t);
                    this.showItemBox();
                    this.isSpinner = false;
                    this.isObjectChanged = false;
                });
            }
        }
        else if (!this.autoComplete)
            this.showItemBox();
        return false;
    }
    showItemBox() {
        this.setActiveTabClass();
        var selectedItem = this.dropSource.filter(t => t.value == this.currentValue)[0];
        if (selectedItem)
            selectedItem.active = true;
    }
    onBlur(event, value) {
        if (this.timeOutId)
            window.clearTimeout(this.timeOutId);
        this.timeOutId = window.setTimeout(() => {
            this.clearActiveTabClass();
        }, 200);
        this.currentValue = value;
        if (!this.setValue(true, "value") || value == "") {
            if (value != "" && !this.enableFreeText) {
                this.currentValue = "";
                this.selectSearch.nativeElement.value = "";
                this.updateFormValue(undefined);
                this.selectedTag = undefined;
                this.blur.emit({ item: this.selectedTag, text: this.currentValue });
            }
            else {
                this.updateFormValue(value);
                this.blur.emit({ item: undefined, text: value });
            }
        }
    }
    onKeyup(event, scroller) {
        if (event.key == "Tab") {
            this.onFocus(event);
            return;
        }
        var value = event.target.value;
        if (value !== null && event.key !== "ArrowUp" && event.key !== "ArrowDown" && event.key !== "Enter" && event.key !== "ArrowLeft" && event.key !== "ArrowRight") {
            if (this.autoComplete) {
                this.currentValue = value;
                this.onFocus(event);
            }
            else {
                var regex = new RegExp(value.toLowerCase());
                this.dropSource = this.mainSource.filter(t => regex.test(t.value.toLowerCase()));
                this.setActiveTabClass();
            }
            if (this.enableFreeText)
                this.updateFormValue(value);
        }
    }
    onKeydown(event, scroller) {
        if (event.key === "ArrowDown") {
            event.preventDefault();
            if (this.dropSource.length !== this.dropIndex) {
                if (this.dropIndex !== 0) {
                    this.dropSource[this.dropIndex - 1].active = false;
                    this.dropSource[this.dropIndex].active = true;
                    if (this.dropIndex !== this.dropSource.length - 1)
                        this.dropIndex++;
                }
                else {
                    this.dropSource[this.dropIndex].active = true;
                    this.dropIndex++;
                }
            }
            this.changeScroll();
            if (this.openDrop === "")
                this.setActiveTabClass();
        }
        else if (event.key === "ArrowUp") {
            event.preventDefault();
            if ((this.dropSource.length - 1) === this.dropIndex) {
                this.dropSource[this.dropIndex].active = false;
                this.dropIndex--;
                this.dropSource[this.dropIndex].active = true;
            }
            else {
                this.dropSource[this.dropIndex].active = false;
                if (this.dropIndex !== 0)
                    this.dropIndex--;
                this.dropSource[this.dropIndex].active = true;
            }
            this.changeScroll();
            if (this.openDrop === "")
                this.setActiveTabClass();
        }
        else if (event.key === "Enter") {
            event.preventDefault();
            const selectedTag = this.dropSource.filter(t => t.active);
            if (selectedTag.length > 0) {
                this.selectedTag = selectedTag[0];
                this.selectSearch.nativeElement.value = selectedTag[0].value;
                this.writeValue(selectedTag[0].value);
                this.clearActiveTabClass();
            }
        }
    }
    setActiveTabClass() {
        this.activeTag = "chosen-container-active";
        this.openDrop = "chosen-with-drop";
    }
    changeScroll() {
        var scrollerElement = document.getElementById(String(this.selectId));
        let childElement = scrollerElement.getElementsByClassName("activeTag")[0];
        if (childElement != undefined)
            scrollerElement.scrollTop = childElement.offsetTop - 50;
    }
    onChange(targetElement) {
        let selectModel = this.dropSource[targetElement.selectedIndex];
        this.selectTag(selectModel);
    }
    enter(targetElement) {
        this.onClick(this.selectedTag, targetElement);
    }
    onClick(tag, tagSearchElement) {
        this.selectTag(tag);
        this.clearValue(tagSearchElement);
        tagSearchElement.value = tag.value;
        this.currentValue = tag.value;
        this.changed.emit({ item: this.selectedTag, text: this.currentValue, sourceItem: this.getSourceItem(tag) });
    }
    getSourceItem(tag) {
        var sourceItem = this.userSource.filter(t => t[this.keyValueProps[1]] == tag.key)[0];
        return sourceItem;
    }
    selectTag(tag) {
        tag.active = false;
        this.selectedTag = tag;
        this.clearActiveTabClass();
        this.updateFormValue(this.selectedTag.key);
    }
    updateFormValue(value) {
        this.propagateChange(value);
    }
    onMouseover(tag, i) {
        this.dropSource.forEach(t => t.active = false);
        if (tag && (i != undefined)) {
            this.dropIndex = i;
            this.selectActive = false;
            tag.active = true;
        }
        else
            this.selectActive = true;
    }
    clearValue(element) {
        element.value = "";
        //this.renderer.invokeElementMethod(element, "focus", []);
    }
    clearActiveTabClass() {
        this.activeTag = "";
        this.openDrop = "";
        this.dropSource.forEach(tag => tag.active = false);
    }
    subscribeFormControl() {
        this.currentFormControl.statusChanges.subscribe(t => {
            this.isInValid = t === "INVALID";
        });
    }
    validate(formControl) {
        if (!this.currentFormControl) {
            this.currentFormControl = formControl;
            this.subscribeFormControl();
        }
        return null;
    }
    ngOnDestroy() {
        let tString = '';
        this.mainSource = [];
    }
};
RxSelectComponent.ctorParameters = () => [
    { type: ElementRef },
    { type: Renderer2 }
];
__decorate([
    ViewChild("selectSearch", { static: false })
], RxSelectComponent.prototype, "selectSearch", void 0);
__decorate([
    Output()
], RxSelectComponent.prototype, "blur", void 0);
__decorate([
    Output()
], RxSelectComponent.prototype, "changed", void 0);
__decorate([
    Input()
], RxSelectComponent.prototype, "mainClass", void 0);
__decorate([
    Input()
], RxSelectComponent.prototype, "maxLength", void 0);
__decorate([
    Input()
], RxSelectComponent.prototype, "selectPlaceholder", void 0);
__decorate([
    Input()
], RxSelectComponent.prototype, "showSelectItem", void 0);
__decorate([
    Input()
], RxSelectComponent.prototype, "controlTabIndex", void 0);
__decorate([
    Input()
], RxSelectComponent.prototype, "source", null);
__decorate([
    Input()
], RxSelectComponent.prototype, "disabled", void 0);
__decorate([
    Input()
], RxSelectComponent.prototype, "keyValueProps", void 0);
__decorate([
    Input()
], RxSelectComponent.prototype, "focus", void 0);
__decorate([
    Input()
], RxSelectComponent.prototype, "path", void 0);
__decorate([
    Input()
], RxSelectComponent.prototype, "params", void 0);
__decorate([
    Input()
], RxSelectComponent.prototype, "queryParams", void 0);
__decorate([
    Input()
], RxSelectComponent.prototype, "autoComplete", void 0);
__decorate([
    Input()
], RxSelectComponent.prototype, "minimumCharacterSearchLength", void 0);
__decorate([
    Input()
], RxSelectComponent.prototype, "enableFreeText", void 0);
__decorate([
    Input()
], RxSelectComponent.prototype, "text", null);
RxSelectComponent = RxSelectComponent_1 = __decorate([
    Component({
        selector: 'rx-select',
        template: "\n<div class=\"chosen-container {{openDrop}} {{activeTag}} \" [class.rxMessage-control-element]=\"!isInValid\" title=\"\">\n    <ul class=\"chosen-choices\">\n        <li class=\"search-field\">\n            <span class=\"input-group\">\n                <input [class]=\"mainClass\" [tabindex]=\"controlTabIndex\" type=\"text\" [placeholder]=\"selectPlaceholder\" #selectSearch (click)=\"onFocus($event)\" (blur)=\"onBlur($event,$event.target.value)\" (keydown)=\"onKeydown($event,scroller)\" (keydown.enter)=\"enter($event.target)\" (keyup)=\"onKeyup($event,scroller)\" class=\"form-control\" autocomplete=\"off\">\n                <span class=\"input-group-append\">\n                  <span class=\"input-group-text\">\n                    <i class=\"fa fa-spinner fa-pulse\" [class.d-none]=\"!isSpinner\"></i>\n                    <i class=\"fa fa-caret-down\"  (click)=\"caretClick($event)\" [class.d-none]=\"!(!isSpinner && !autoComplete)\"></i>\n                  </span>\n                </span>\n            </span>\n        </li>\n    </ul>\n    <div class=\"chosen-drop\"  #scroller>\n        <ul class=\"chosen-results\" [id]=\"selectId\">\n          <li class=\"active-result\" *ngIf=\"showSelectItem\" (mouseover)=\"onMouseover()\" (click)=\"clear($event)\" [class.highlighted]=\"selectActive\">{{selectPlaceholder}}</li>\n            <li class=\"active-result\" *ngFor=\"let tag of dropSource;let i = index\"  (click)=\"onClick(tag,selectSearch)\" (mouseover)=\"onMouseover(tag,i)\" [class.highlighted]=\"tag.active\" [class.activeTag]=\"tag.active\">{{tag.value}}</li>\n        </ul>\n    </div>\n</div>\n",
        providers: [
            { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => RxSelectComponent_1), multi: true },
            { provide: NG_VALIDATORS, useExisting: forwardRef(() => RxSelectComponent_1), multi: true }
        ],
        exportAs: 'select'
    })
], RxSelectComponent);
let RxSelectModule = class RxSelectModule {
};
RxSelectModule = __decorate([
    NgModule({
        imports: [CommonModule, FormsModule, ReactiveFormsModule],
        exports: [RxSelectComponent],
        declarations: [RxSelectComponent]
    })
], RxSelectModule);

/**
 * Generated bundle index. Do not edit.
 */

export { RxSelectComponent, RxSelectModule, SelectModel };
//# sourceMappingURL=rxweb-angular-select.js.map
