import { EditableTextBase as EditableTextBaseCommon, autofillTypeProperty, keyboardTypeProperty, returnKeyTypeProperty, editableProperty, autocapitalizationTypeProperty, autocorrectProperty, hintProperty, placeholderColorProperty, maxLengthProperty } from './editable-text-base-common';
import { textTransformProperty, textProperty, resetSymbol } from '../text-base';
import { Color } from '../../color';
import { ad } from '../../utils';
import { SDK_VERSION } from '../../utils/constants';
import * as timer from '../../timer';
export * from './editable-text-base-common';
//https://github.com/NativeScript/NativeScript/issues/2942
export let dismissKeyboardTimeoutId;
let EditTextListeners;
function clearDismissTimer() {
    if (dismissKeyboardTimeoutId) {
        clearTimeout(dismissKeyboardTimeoutId);
        dismissKeyboardTimeoutId = null;
    }
}
function dismissSoftInput(view) {
    clearDismissTimer();
    if (!dismissKeyboardTimeoutId) {
        dismissKeyboardTimeoutId = timer.setTimeout(() => {
            const activity = view._context;
            dismissKeyboardTimeoutId = null;
            const focused = activity && activity.getCurrentFocus();
            if (focused && !(focused instanceof android.widget.EditText)) {
                // warning `ad.dismissSoftInput` will actually focus the next view
                // if we pass a null parameter!!!
                // => focus and show keyboard again
                // the fix was for where there were multiple TextField for which it would work!
                // with this it will still work without breaking for single TextField
                ad.dismissSoftInput(focused);
            }
        }, 10);
    }
}
function initializeEditTextListeners() {
    if (EditTextListeners) {
        return;
    }
    var EditTextListenersImpl = (function (_super) {
        __extends(EditTextListenersImpl, _super);
        function EditTextListenersImpl(owner) {
            var _this = _super.call(this) || this;
            _this.owner = owner;
            return global.__native(_this);
        }
        EditTextListenersImpl.prototype.beforeTextChanged = function (text, start, count, after) {
            var _a, _b;
            (_b = (_a = this.owner) === null || _a === void 0 ? void 0 : _a.get()) === null || _b === void 0 ? void 0 : _b.beforeTextChanged(text, start, count, after);
        };
        EditTextListenersImpl.prototype.onTextChanged = function (text, start, before, count) {
            var _a, _b;
            (_b = (_a = this.owner) === null || _a === void 0 ? void 0 : _a.get()) === null || _b === void 0 ? void 0 : _b.onTextChanged(text, start, before, count);
        };
        EditTextListenersImpl.prototype.afterTextChanged = function (editable) {
            var _a, _b;
            (_b = (_a = this.owner) === null || _a === void 0 ? void 0 : _a.get()) === null || _b === void 0 ? void 0 : _b.afterTextChanged(editable);
        };
        EditTextListenersImpl.prototype.onFocusChange = function (view, hasFocus) {
            var _a, _b;
            (_b = (_a = this.owner) === null || _a === void 0 ? void 0 : _a.get()) === null || _b === void 0 ? void 0 : _b.onFocusChange(view, hasFocus);
        };
        EditTextListenersImpl.prototype.onEditorAction = function (textView, actionId, event) {
            var _a, _b;
            return ((_b = (_a = this.owner) === null || _a === void 0 ? void 0 : _a.get()) === null || _b === void 0 ? void 0 : _b.onEditorAction(textView, actionId, event)) || false;
        };
        EditTextListenersImpl = __decorate([
            Interfaces([android.text.TextWatcher, android.view.View.OnFocusChangeListener, android.widget.TextView.OnEditorActionListener])
        ], EditTextListenersImpl);
        return EditTextListenersImpl;
    }(java.lang.Object));
    EditTextListeners = EditTextListenersImpl;
}
export class EditableTextBase extends EditableTextBaseCommon {
    _onReturnPress() {
        //
    }
    createNativeView() {
        return new android.widget.EditText(this._context);
    }
    initNativeView() {
        super.initNativeView();
        const editText = this.nativeTextViewProtected;
        this._configureEditText(editText);
        initializeEditTextListeners();
        const listeners = new EditTextListeners(new WeakRef(this));
        editText.addTextChangedListener(listeners);
        editText.setOnFocusChangeListener(listeners);
        editText.setOnEditorActionListener(listeners);
        editText.listener = listeners;
        this._inputType = editText.getInputType();
    }
    disposeNativeView() {
        const editText = this.nativeTextViewProtected;
        editText.removeTextChangedListener(editText.listener);
        editText.setOnFocusChangeListener(null);
        editText.setOnEditorActionListener(null);
        editText.listener.owner = null;
        editText.listener = null;
        this._keyListenerCache = null;
        this._dirtyTextAccumulator = undefined;
        this._inputType = 0;
        super.disposeNativeView();
    }
    resetNativeView() {
        super.resetNativeView();
        this.nativeTextViewProtected.setInputType(this._inputType);
    }
    onUnloaded() {
        this.dismissSoftInput();
        super.onUnloaded();
    }
    dismissSoftInput() {
        const nativeView = this.nativeTextViewProtected;
        if (!nativeView) {
            return;
        }
        ad.dismissSoftInput(nativeView);
    }
    focus() {
        const nativeView = this.nativeTextViewProtected;
        if (!nativeView) {
            return;
        }
        const result = super.focus();
        if (result) {
            ad.showSoftInput(this.nativeTextViewProtected);
        }
        return result;
    }
    _setInputType(inputType) {
        const nativeView = this.nativeTextViewProtected;
        try {
            this._changeFromCode = true;
            nativeView.setInputType(parseInt(inputType, 10));
        }
        finally {
            this._changeFromCode = false;
        }
        // setInputType will change the keyListener so we should cache it again
        const listener = nativeView.getKeyListener();
        if (listener) {
            this._keyListenerCache = listener;
        }
        // clear these fields instead of clearing listener.
        // this allows input Type to be changed even after editable is false.
        if (!this.editable) {
            nativeView.setFocusable(false);
            nativeView.setFocusableInTouchMode(false);
            nativeView.setLongClickable(false);
            nativeView.setClickable(false);
        }
    }
    [textProperty.getDefault]() {
        return resetSymbol;
    }
    [textProperty.setNative](value) {
        try {
            this._changeFromCode = true;
            this._setNativeText(value === resetSymbol);
        }
        finally {
            this._changeFromCode = false;
        }
    }
    [keyboardTypeProperty.getDefault]() {
        return this.nativeTextViewProtected.getInputType();
    }
    [keyboardTypeProperty.setNative](value) {
        let newInputType;
        switch (value) {
            case 'datetime':
                newInputType = android.text.InputType.TYPE_CLASS_DATETIME | android.text.InputType.TYPE_DATETIME_VARIATION_NORMAL;
                break;
            case 'phone':
                newInputType = android.text.InputType.TYPE_CLASS_PHONE;
                break;
            case 'number':
                newInputType = android.text.InputType.TYPE_CLASS_NUMBER | android.text.InputType.TYPE_NUMBER_VARIATION_NORMAL | android.text.InputType.TYPE_NUMBER_FLAG_SIGNED | android.text.InputType.TYPE_NUMBER_FLAG_DECIMAL;
                break;
            case 'decimal':
                newInputType = android.text.InputType.TYPE_CLASS_NUMBER | android.text.InputType.TYPE_NUMBER_FLAG_DECIMAL | android.text.InputType.TYPE_NUMBER_FLAG_SIGNED;
                break;
            case 'url':
                newInputType = android.text.InputType.TYPE_CLASS_TEXT | android.text.InputType.TYPE_TEXT_VARIATION_URI;
                break;
            case 'email':
                newInputType = android.text.InputType.TYPE_CLASS_TEXT | android.text.InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS;
                break;
            case 'integer':
                newInputType = android.text.InputType.TYPE_CLASS_NUMBER;
                break;
            default: {
                const inputType = +value;
                if (!isNaN(inputType)) {
                    newInputType = inputType;
                }
                else {
                    newInputType = android.text.InputType.TYPE_CLASS_TEXT;
                }
                break;
            }
        }
        this._setInputType(newInputType);
    }
    [autofillTypeProperty.setNative](value) {
        if (SDK_VERSION < 26) {
            return;
        }
        let newOptions;
        switch (value) {
            case 'phone':
                newOptions = 'phone'; // android.view.View.AUTOFILL_HINT_PHONE
                break;
            case 'postalCode':
                newOptions = 'postalCode'; // android.view.View.AUTOFILL_HINT_POSTAL_CODE
                break;
            case 'creditCardNumber':
                newOptions = 'creditCardNumber'; // android.view.View.AUTOFILL_HINT_CREDIT_CARD_NUMBER
                break;
            case 'email':
                newOptions = 'emailAddress'; // android.view.View.AUTOFILL_HINT_EMAIL_ADDRESS
                break;
            case 'name':
                newOptions = 'name'; // android.view.View.AUTOFILL_HINT_NAME
                break;
            case 'username':
                newOptions = 'username'; // android.view.View.AUTOFILL_HINT_USERNAME
                break;
            case 'password':
                newOptions = 'password'; // android.view.View.AUTOFILL_HINT_PASSWORD
                break;
            case 'newPassword':
                newOptions = 'newPassword'; // android.view.View.AUTOFILL_HINT_NEW_PASSWORD
                break;
            case 'newUsername':
                newOptions = 'newUsername'; // android.view.View.AUTOFILL_HINT_NEW_USERNAME
                break;
            case 'oneTimeCode':
                newOptions = '2faAppOTPCode'; // android.view.View.AUTOFILL_HINT_2FA_APP_OTP
                break;
            case 'none':
                newOptions = null;
                break;
            default: {
                newOptions = value;
                break;
            }
        }
        if (newOptions) {
            const array = Array.create(java.lang.String, 1);
            array[0] = newOptions;
            this.nativeTextViewProtected.setAutofillHints(array);
        }
        else {
            this.nativeTextViewProtected.setAutofillHints(null);
        }
    }
    [returnKeyTypeProperty.getDefault]() {
        const ime = this.nativeTextViewProtected.getImeOptions();
        switch (ime) {
            case android.view.inputmethod.EditorInfo.IME_ACTION_DONE:
                return 'done';
            case android.view.inputmethod.EditorInfo.IME_ACTION_GO:
                return 'go';
            case android.view.inputmethod.EditorInfo.IME_ACTION_NEXT:
                return 'next';
            case android.view.inputmethod.EditorInfo.IME_ACTION_SEARCH:
                return 'search';
            case android.view.inputmethod.EditorInfo.IME_ACTION_SEND:
                return 'send';
            default:
                return ime.toString();
        }
    }
    [returnKeyTypeProperty.setNative](value) {
        let newImeOptions;
        switch (value) {
            case 'done':
                newImeOptions = android.view.inputmethod.EditorInfo.IME_ACTION_DONE;
                break;
            case 'go':
                newImeOptions = android.view.inputmethod.EditorInfo.IME_ACTION_GO;
                break;
            case 'next':
                newImeOptions = android.view.inputmethod.EditorInfo.IME_ACTION_NEXT;
                break;
            case 'search':
                newImeOptions = android.view.inputmethod.EditorInfo.IME_ACTION_SEARCH;
                break;
            case 'send':
                newImeOptions = android.view.inputmethod.EditorInfo.IME_ACTION_SEND;
                break;
            default: {
                const ime = +value;
                if (!isNaN(ime)) {
                    newImeOptions = ime;
                }
                else {
                    newImeOptions = android.view.inputmethod.EditorInfo.IME_ACTION_UNSPECIFIED;
                }
                break;
            }
        }
        this.nativeTextViewProtected.setImeOptions(newImeOptions);
    }
    [editableProperty.setNative](value) {
        const nativeView = this.nativeTextViewProtected;
        if (value) {
            nativeView.setKeyListener(this._keyListenerCache);
        }
        else {
            if (!this._keyListenerCache) {
                this._keyListenerCache = nativeView.getKeyListener();
            }
            nativeView.setKeyListener(null);
        }
    }
    [autocapitalizationTypeProperty.getDefault]() {
        const inputType = this.nativeTextViewProtected.getInputType();
        if ((inputType & android.text.InputType.TYPE_TEXT_FLAG_CAP_WORDS) === android.text.InputType.TYPE_TEXT_FLAG_CAP_WORDS) {
            return 'words';
        }
        else if ((inputType & android.text.InputType.TYPE_TEXT_FLAG_CAP_SENTENCES) === android.text.InputType.TYPE_TEXT_FLAG_CAP_SENTENCES) {
            return 'sentences';
        }
        else if ((inputType & android.text.InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS) === android.text.InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS) {
            return 'allcharacters';
        }
        else {
            return inputType.toString();
        }
    }
    [autocapitalizationTypeProperty.setNative](value) {
        let inputType = this.nativeTextViewProtected.getInputType();
        inputType = inputType & ~28672; //28672 (0x00070000) 13,14,15bits (111 0000 0000 0000)
        switch (value) {
            case 'none':
                //Do nothing, we have lowered the three bits above.
                break;
            case 'words':
                inputType = inputType | android.text.InputType.TYPE_TEXT_FLAG_CAP_WORDS; //8192 (0x00020000) 14th bit
                break;
            case 'sentences':
                inputType = inputType | android.text.InputType.TYPE_TEXT_FLAG_CAP_SENTENCES; //16384(0x00040000) 15th bit
                break;
            case 'allcharacters':
                inputType = inputType | android.text.InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS; //4096 (0x00010000) 13th bit
                break;
            default: {
                const number = +value;
                // We set the default value.
                if (!isNaN(number)) {
                    inputType = number;
                }
                else {
                    inputType = inputType | android.text.InputType.TYPE_TEXT_FLAG_CAP_SENTENCES;
                }
                break;
            }
        }
        this._setInputType(inputType);
    }
    [autocorrectProperty.getDefault]() {
        const autocorrect = this.nativeTextViewProtected.getInputType();
        if ((autocorrect & android.text.InputType.TYPE_TEXT_FLAG_AUTO_CORRECT) === android.text.InputType.TYPE_TEXT_FLAG_AUTO_CORRECT) {
            return true;
        }
        return false;
    }
    [autocorrectProperty.setNative](value) {
        let inputType = this.nativeTextViewProtected.getInputType();
        switch (value) {
            case true:
                inputType = inputType | android.text.InputType.TYPE_TEXT_FLAG_AUTO_COMPLETE;
                inputType = inputType | android.text.InputType.TYPE_TEXT_FLAG_AUTO_CORRECT;
                inputType = inputType & ~android.text.InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS;
                break;
            case false:
                inputType = inputType & ~android.text.InputType.TYPE_TEXT_FLAG_AUTO_COMPLETE;
                inputType = inputType & ~android.text.InputType.TYPE_TEXT_FLAG_AUTO_CORRECT;
                inputType = inputType | android.text.InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS;
                break;
            default:
                // We can't do anything.
                break;
        }
        this._setInputType(inputType);
    }
    [hintProperty.getDefault]() {
        return this.nativeTextViewProtected.getHint();
    }
    [hintProperty.setNative](value) {
        const text = value === null || value === undefined ? null : value.toString();
        this.nativeTextViewProtected.setHint(text);
    }
    [placeholderColorProperty.getDefault]() {
        return this.nativeTextViewProtected.getHintTextColors();
    }
    [placeholderColorProperty.setNative](value) {
        const color = value instanceof Color ? value.android : value;
        this.nativeTextViewProtected.setHintTextColor(color);
    }
    [textTransformProperty.setNative](value) {
        //
    }
    [maxLengthProperty.setNative](value) {
        if (value === Number.POSITIVE_INFINITY) {
            this.nativeTextViewProtected.setFilters([]);
        }
        else {
            const lengthFilter = new android.text.InputFilter.LengthFilter(value);
            const filters = this.nativeTextViewProtected.getFilters();
            const newFilters = [];
            // retain existing filters
            for (let i = 0; i < filters.length; i++) {
                const filter = filters[i];
                if (!(filter instanceof android.text.InputFilter.LengthFilter)) {
                    newFilters.push(filter);
                }
            }
            newFilters.push(lengthFilter);
            this.nativeTextViewProtected.setFilters(newFilters);
        }
    }
    setSelection(start, stop) {
        const view = this.nativeTextViewProtected;
        if (view) {
            if (stop !== undefined) {
                view.setSelection(start, stop);
            }
            else {
                view.setSelection(start);
            }
        }
    }
    beforeTextChanged(text, start, count, after) {
        // called by android.text.TextWatcher
    }
    onTextChanged(text, start, before, count) {
        // called by android.text.TextWatcher
        if (this.valueFormatter) {
            this.text = this.valueFormatter(text.toString());
            this.android.setSelection((this.text || '').length);
        }
        // const owner = this.owner;
        // let selectionStart = owner.android.getSelectionStart();
        // owner.android.removeTextChangedListener(owner._editTextListeners);
        // owner.android.addTextChangedListener(owner._editTextListeners);
        // owner.android.setSelection(selectionStart);
    }
    afterTextChanged(editable) {
        // called by android.text.TextWatcher
        if (this._changeFromCode) {
            return;
        }
        switch (this.updateTextTrigger) {
            case 'focusLost':
                this._dirtyTextAccumulator = editable.toString();
                break;
            case 'textChanged':
                textProperty.nativeValueChange(this, editable.toString());
                break;
            default:
                throw new Error('Invalid updateTextTrigger: ' + this.updateTextTrigger);
        }
    }
    onFocusChange(view, hasFocus) {
        if (hasFocus) {
            clearDismissTimer();
            this.notify({ eventName: EditableTextBase.focusEvent });
        }
        else {
            if (this._dirtyTextAccumulator || this._dirtyTextAccumulator === '') {
                textProperty.nativeValueChange(this, this._dirtyTextAccumulator);
                this._dirtyTextAccumulator = undefined;
            }
            this.notify({ eventName: EditableTextBase.blurEvent });
            dismissSoftInput(this);
        }
    }
    onEditorAction(textView, actionId, event) {
        if (actionId === android.view.inputmethod.EditorInfo.IME_ACTION_DONE || actionId === android.view.inputmethod.EditorInfo.IME_ACTION_UNSPECIFIED || (event && event.getKeyCode() === android.view.KeyEvent.KEYCODE_ENTER)) {
            // If it is TextField, close the keyboard. If it is TextView, do not close it since the TextView is multiline
            // https://github.com/NativeScript/NativeScript/issues/3111
            if (textView.getMaxLines() === 1) {
                this.dismissSoftInput();
            }
            this._onReturnPress();
        }
        else if (actionId === android.view.inputmethod.EditorInfo.IME_ACTION_NEXT || actionId === android.view.inputmethod.EditorInfo.IME_ACTION_PREVIOUS) {
            // do not close keyboard for ACTION_NEXT or ACTION_PREVIOUS
            this._onReturnPress();
        }
        return false;
    }
}
//# sourceMappingURL=index.android.js.map