"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 __assign = (this && this.__assign) || Object.assign || function(t) {
    for (var s, i = 1, n = arguments.length; i < n; i++) {
        s = arguments[i];
        for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
            t[p] = s[p];
    }
    return t;
};
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 React = require('react');
var FocusZone_1 = require('../../FocusZone');
var Callout_1 = require('../../Callout');
var KeyCodes_1 = require('../../utilities/KeyCodes');
var index_1 = require('../../utilities/selection/index');
var index_2 = require('./Suggestions/index');
var BaseComponent_1 = require('../../common/BaseComponent');
var css_1 = require('../../utilities/css');
var autobind_1 = require('../../utilities/autobind');
require('./BasePicker.scss');
var BasePicker = (function (_super) {
    __extends(BasePicker, _super);
    function BasePicker(basePickerProps) {
        var _this = this;
        _super.call(this, basePickerProps);
        this._SuggestionOfProperType = index_2.Suggestions;
        var items = basePickerProps.defaultSelectedItems || [];
        this._suggestionStore = new index_2.SuggestionsController();
        this._selection = new index_1.Selection({ onSelectionChanged: function () { return _this._onSelectionChange(); } });
        this._selection.setItems(items);
        this.state = {
            items: items,
            displayValue: '',
            value: '',
            moreSuggestionsAvailable: false
        };
    }
    BasePicker.prototype.componentWillReceiveProps = function (newProps, newState) {
        if (newState.items && newState.items !== this.state.items) {
            this._selection.setItems(newState.items);
        }
    };
    BasePicker.prototype.componentDidMount = function () {
        this._selection.setItems(this.state.items);
    };
    BasePicker.prototype.focus = function () {
        this._focusZone.focus();
    };
    BasePicker.prototype.dismissSuggestions = function () {
        this.setState({ suggestionsVisible: false });
    };
    BasePicker.prototype.completeSuggestion = function () {
        if (this._suggestionStore.hasSelectedSuggestion()) {
            this._addItem(this._suggestionStore.currentSuggestion.item);
            this._updateValue('');
        }
    };
    BasePicker.prototype.render = function () {
        var displayValue = this.state.displayValue;
        return (React.createElement("div", {ref: this._resolveRef('_root'), className: css_1.css('ms-BasePicker', this.props.className ? this.props.className : ''), onKeyDown: this._onKeyDown}, React.createElement(index_1.SelectionZone, {selection: this._selection, selectionMode: index_1.SelectionMode.multiple}, React.createElement(FocusZone_1.FocusZone, {ref: this._resolveRef('_focusZone'), className: 'ms-BasePicker-text'}, this._renderItems(), React.createElement("input", {ref: this._resolveRef('_input'), className: 'ms-BasePicker-input', onFocus: this._onInputFocus, onChange: this._onInputChange, value: displayValue, "aria-activedescendant": 'sug-' + this._suggestionStore.currentIndex, "aria-owns": 'suggestion-list', "aria-expanded": 'true', "aria-haspopup": 'true', autoCapitalize: 'off', autoComplete: 'off'}))), this._renderSuggestions()));
    };
    BasePicker.prototype._renderSuggestions = function () {
        var TypedSuggestion = this._SuggestionOfProperType;
        return this.state.suggestionsVisible ? (React.createElement(Callout_1.Callout, {isBeakVisible: false, gapSpace: 0, targetElement: this._root, onDismiss: this.dismissSuggestions}, React.createElement(TypedSuggestion, __assign({onRenderSuggestion: this.props.onRenderSuggestionsItem, onSuggestionClick: this._onSuggestionClick, suggestions: this._suggestionStore.getSuggestions(), ref: this._resolveRef('_suggestionElement'), onGetMoreResults: this._onGetMoreResults, moreSuggestionsAvailable: this.state.moreSuggestionsAvailable}, this.props.pickerSuggestionsProps)))) : (null);
    };
    BasePicker.prototype._renderItems = function () {
        var _this = this;
        var _a = this.props.onRenderItem, onRenderItem = _a === void 0 ? function () { return undefined; } : _a;
        var items = this.state.items;
        return items.map(function (item, index) { return onRenderItem({
            item: item,
            index: index,
            isSelected: _this._selection.isIndexSelected(index),
            onRemoveItem: function () { return _this._removeItem(item); }
        }); });
    };
    BasePicker.prototype._resetFocus = function (index) {
        var items = this.state.items;
        if (items.length) {
            var newEl = this._root.querySelectorAll('[data-selection-index]')[Math.min(index, items.length - 1)];
            if (newEl) {
                this._focusZone.focusElement(newEl);
            }
        }
        else {
            this._input.focus();
        }
    };
    BasePicker.prototype._onSuggestionSelect = function () {
        var _this = this;
        if (this._suggestionStore.currentSuggestion) {
            var currentValue = this.state.value;
            var itemValue = this.props.getTextFromItem(this._suggestionStore.currentSuggestion.item);
            this._updateDisplayValue(currentValue, itemValue);
            this.setState({ displayValue: itemValue }, function () { return _this._suggestionElement.scrollSelected(); });
        }
    };
    BasePicker.prototype._onSelectionChange = function () {
        this.forceUpdate();
    };
    BasePicker.prototype._updateSuggestions = function (suggestions) {
        this._suggestionStore.updateSuggestions(suggestions);
        this.forceUpdate();
    };
    BasePicker.prototype._updateValue = function (updatedValue) {
        var value = this.state.value;
        if (!this._suggestionStore.currentIndex || updatedValue !== value) {
            var newSuggestions = this.props.onResolveSuggestions(updatedValue, this.state.items);
            this._suggestionStore.updateSuggestions(newSuggestions);
            var itemValue = undefined;
            if (this._suggestionStore.currentSuggestion) {
                itemValue = this.props.getTextFromItem(this._suggestionStore.currentSuggestion.item);
            }
            this._updateDisplayValue(updatedValue, itemValue);
        }
    };
    BasePicker.prototype._updateDisplayValue = function (updatedValue, itemValue) {
        var _this = this;
        var differenceIndex = 0;
        if (updatedValue) {
            while (differenceIndex < updatedValue.length && updatedValue[differenceIndex].toLocaleLowerCase() === updatedValue[differenceIndex].toLocaleLowerCase()) {
                differenceIndex++;
            }
        }
        this.setState({
            displayValue: itemValue || updatedValue,
            value: updatedValue,
            suggestionsVisible: updatedValue && updatedValue !== ''
        }, function () {
            if (itemValue && differenceIndex < itemValue.length) {
                _this._input.setSelectionRange(differenceIndex, itemValue.length, 'backward');
            }
        });
    };
    BasePicker.prototype._onChange = function () {
        if (this.props.onChange) {
            this.props.onChange(this.state.items);
        }
    };
    BasePicker.prototype._onInputChange = function (ev) {
        var value = ev.target.value;
        this._updateValue(value);
        this.setState({ moreSuggestionsAvailable: true });
    };
    BasePicker.prototype._onSuggestionClick = function (ev, item, index) {
        this._addItemByIndex(index);
    };
    BasePicker.prototype._onInputFocus = function (ev) {
        this._selection.setAllSelected(false);
        if (this.state.value) {
            this.setState({ suggestionsVisible: true });
        }
    };
    BasePicker.prototype._onKeyDown = function (ev) {
        var value = this.state.value;
        switch (ev.which) {
            case KeyCodes_1.KeyCodes.escape:
                this.dismissSuggestions();
                break;
            case KeyCodes_1.KeyCodes.tab:
            case KeyCodes_1.KeyCodes.enter:
                if (value && this._suggestionStore.hasSelectedSuggestion()) {
                    this.completeSuggestion();
                    ev.preventDefault();
                    ev.stopPropagation();
                }
                break;
            case KeyCodes_1.KeyCodes.backspace:
                this._onBackspace(ev);
                break;
            case KeyCodes_1.KeyCodes.up:
                if (ev.target === this._input && this._suggestionStore.previousSuggestion()) {
                    ev.preventDefault();
                    ev.stopPropagation();
                    this._onSuggestionSelect();
                }
                break;
            case KeyCodes_1.KeyCodes.down:
                if (ev.target === this._input) {
                    if (this._suggestionStore.nextSuggestion()) {
                        ev.preventDefault();
                        ev.stopPropagation();
                        this._onSuggestionSelect();
                    }
                }
                break;
        }
    };
    BasePicker.prototype._onGetMoreResults = function () {
        if (this.props.onGetMoreResults) {
            this._updateSuggestions(this.props.onGetMoreResults(this.state.value, this.state.items));
        }
        this._input.focus();
        this.setState({ moreSuggestionsAvailable: false });
    };
    BasePicker.prototype._addItemByIndex = function (index) {
        this._addItem(this._suggestionStore.getSuggestionAtIndex(index).item);
        this._updateValue('');
    };
    BasePicker.prototype._addItem = function (item) {
        var _this = this;
        var newItems = this.state.items.concat([item]);
        this._selection.setItems(newItems);
        this.setState({ items: newItems }, function () { return _this._onChange(); });
    };
    BasePicker.prototype._removeItem = function (item) {
        var _this = this;
        var items = this.state.items;
        var index = items.indexOf(item);
        if (index >= 0) {
            var newItems = items.slice(0, index).concat(items.slice(index + 1));
            this._selection.setItems(newItems);
            this.setState({ items: newItems }, function () { return _this._onChange(); });
        }
    };
    BasePicker.prototype._removeItems = function (itemsToRemove) {
        var _this = this;
        var items = this.state.items;
        var newItems = items.filter(function (item) { return itemsToRemove.indexOf(item) === -1; });
        var firstItemToRemove = this._selection.getSelection()[0];
        var index = items.indexOf(firstItemToRemove);
        this._selection.setItems(newItems);
        this.setState({ items: newItems }, function () { return _this._resetFocus(index); });
    };
    BasePicker.prototype._onBackspace = function (ev) {
        var displayValue = this.state.displayValue;
        if (ev.target === this._input) {
            if (displayValue && this._suggestionStore.hasSelectedSuggestion() && this._input.selectionStart !== this._input.selectionEnd) {
                this._updateValue(displayValue.substr(0, this._input.selectionStart - 1));
            }
            else if (!displayValue && this.state.items.length) {
                this._removeItem(this.state.items[this.state.items.length - 1]);
            }
        }
        else if (this._selection.getSelectedCount() > 0) {
            this._removeItems(this._selection.getSelection());
        }
    };
    __decorate([
        autobind_1.autobind
    ], BasePicker.prototype, "dismissSuggestions", null);
    __decorate([
        autobind_1.autobind
    ], BasePicker.prototype, "_onInputChange", null);
    __decorate([
        autobind_1.autobind
    ], BasePicker.prototype, "_onSuggestionClick", null);
    __decorate([
        autobind_1.autobind
    ], BasePicker.prototype, "_onInputFocus", null);
    __decorate([
        autobind_1.autobind
    ], BasePicker.prototype, "_onKeyDown", null);
    __decorate([
        autobind_1.autobind
    ], BasePicker.prototype, "_onGetMoreResults", null);
    __decorate([
        autobind_1.autobind
    ], BasePicker.prototype, "_addItemByIndex", null);
    __decorate([
        autobind_1.autobind
    ], BasePicker.prototype, "_addItem", null);
    __decorate([
        autobind_1.autobind
    ], BasePicker.prototype, "_removeItem", null);
    __decorate([
        autobind_1.autobind
    ], BasePicker.prototype, "_removeItems", null);
    return BasePicker;
}(BaseComponent_1.BaseComponent));
exports.BasePicker = BasePicker;

//# sourceMappingURL=BasePicker.js.map
