/*
 * Copyright 2017-19 IBM Corporation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
import Debug from 'debug';
import { inBrowser, inElectron, KeyCodes, eventChannelUnsafe, doCancel } from '@kui-shell/core';
import startTabCompletion from './TabCompletion';
const debug = Debug('Terminal/Block/OnKeyDown');
function isMSIEControl(ctrl) {
    return Object.prototype.hasOwnProperty.call(ctrl, 'createTextRange');
}
/**
 * Update the caret position in an html INPUT field
 *
 */
const setCaretPosition = (ctrl, pos) => {
    if (ctrl.setSelectionRange) {
        ctrl.focus();
        ctrl.setSelectionRange(pos, pos);
    }
    else if (isMSIEControl(ctrl)) {
        const range = ctrl.createTextRange();
        range.collapse(true);
        range.moveEnd('character', pos);
        range.moveStart('character', pos);
        range.select();
    }
};
const setCaretPositionToEnd = (input) => setCaretPosition(input, input.value.length);
const updateInputAndMoveCaretToEOL = (input, newValue) => {
    input.value = newValue;
    setTimeout(() => setCaretPositionToEnd(input), 0);
};
export default function onKeyDown(event) {
    return __awaiter(this, void 0, void 0, function* () {
        const tab = this.props.tab;
        const block = this.props._block;
        const prompt = this.state.prompt;
        const char = event.keyCode;
        if (this.state.tabCompletion) {
            this.state.tabCompletion.key(event);
            return;
        }
        else if (event.key === 'Tab') {
            startTabCompletion(this, event);
        }
        if (char === KeyCodes.UP || (char === KeyCodes.P && event.ctrlKey)) {
            // go to previous command in history
            const historyModel = yield (yield import('@kui-shell/core')).History(tab);
            const newValue = (historyModel.previous() || { raw: '' }).raw;
            if (newValue) {
                updateInputAndMoveCaretToEOL(prompt, newValue);
            }
        }
        else if (char === KeyCodes.D && event.ctrlKey) {
            if (prompt.value === '') {
                // <-- only if the line is blank
                debug('exit via ctrl+D');
                tab.REPL.pexec('exit', { tab });
            }
        }
        else if (char === KeyCodes.PAGEUP) {
            if (inBrowser()) {
                debug('pageup');
                const { height } = document.body.getBoundingClientRect();
                document.querySelector('.kui--tab-content.visible .repl-inner').scrollBy(0, -height);
            }
        }
        else if (char === KeyCodes.PAGEDOWN) {
            if (inBrowser()) {
                debug('pagedown');
                const { height } = document.body.getBoundingClientRect();
                document.querySelector('.kui--tab-content.visible .repl-inner').scrollBy(0, +height);
            }
        }
        else if (char === KeyCodes.C && event.ctrlKey) {
            // Ctrl+C, cancel
            doCancel(tab, block); // eslint-disable-line @typescript-eslint/no-use-before-define
        }
        else if (char === KeyCodes.U && event.ctrlKey) {
            // clear line
            prompt.value = '';
        }
        else if ((char === KeyCodes.L && (event.ctrlKey || (inElectron() && event.metaKey))) ||
            (process.platform === 'darwin' && char === KeyCodes.K && event.metaKey)) {
            // clear screen; capture and restore the current
            // prompt value, in keeping with unix terminal
            // behavior
            eventChannelUnsafe.emit(`/terminal/clear/${this.props.uuid}`);
            eventChannelUnsafe.emit(`/close/views/${this.props.uuid}`);
            // restore the prompt cursor position
            // debug('restoring cursor position', currentCursorPosition)
            // getCurrentPrompt().setSelectionRange(currentCursorPosition, currentCursorPosition)
        }
        else if (char === KeyCodes.HOME) {
            // go to first command in history
            const historyModel = yield (yield import('@kui-shell/core')).History(tab);
            const newValue = historyModel.first().raw;
            if (newValue) {
                updateInputAndMoveCaretToEOL(prompt, newValue);
            }
        }
        else if (char === KeyCodes.END) {
            // go to last command in history
            const historyModel = yield (yield import('@kui-shell/core')).History(tab);
            const newValue = (historyModel.last() || { raw: '' }).raw;
            updateInputAndMoveCaretToEOL(prompt, newValue);
        }
        else if (char === KeyCodes.DOWN || (char === KeyCodes.N && event.ctrlKey)) {
            // going DOWN past the last history item will result in '', i.e. a blank line
            const historyModel = yield (yield import('@kui-shell/core')).History(tab);
            const newValue = (historyModel.next() || { raw: '' }).raw;
            updateInputAndMoveCaretToEOL(prompt, newValue);
        }
        else if (event.key === 'w' && event.ctrlKey) {
            const { prompt } = this.state;
            const idx = prompt.value.lastIndexOf(' ', prompt.value.charAt(prompt.value.length - 1) === ' ' ? prompt.value.length - 2 : prompt.value.length - 1);
            this.state.prompt.value = this.state.prompt.value.slice(0, idx + 1);
        }
    });
}
//# sourceMappingURL=OnKeyDown.js.map