/*
 * Copyright 2020 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.
 */
import * as React from 'react';
import { eventBus } from '@kui-shell/core';
import Block from '../Views/Terminal/Block';
import { Active } from '../Views/Terminal/Block/BlockModel';
import '../../../web/css/static/InputStripeExperimental.scss';
const blank = '\u00a0';
export default class InputStripe extends React.PureComponent {
    constructor(props) {
        super(props);
        eventBus.onCommandComplete(this.props.uuid, this.onOutputRender.bind(this));
        this.state = {
            idx: 0,
            model: Active(),
            inputCells: [],
            inputRanges: [],
            inputSelectionStart: 0,
            inputSelectionEnd: 0
        };
    }
    /** Parse out the given command line into StyleRanges */
    parse(line) {
        const inputCells = line.split('').map(_ => (_ === ' ' ? blank : _));
        const inputRanges = [];
        let currentStyle = { style: '', text: '' };
        inputRanges.push(currentStyle);
        let state = 0 /* Default */;
        for (let idx = 0; idx < inputCells.length; idx++) {
            const char = inputCells[idx];
            if (state === 1 /* InWhitespace */ && char === '-') {
                // Default -> InDash
                state = 2 /* InDash */;
                currentStyle = { style: 'kui--input-stripe-dash-region-key', text: char };
                inputRanges.push(currentStyle);
            }
            else if (state === 2 /* InDash */ && char === '-') {
                // InDash -> InDoubleDash
                state = 3 /* InDoubleDash */;
                currentStyle.text += char;
            }
            else if (state === 2 /* InDash */ || (state === 3 /* InDoubleDash */ && char === '=')) {
                // InDash -> InDashValue
                // InDoubleDash= -> InDashValue
                currentStyle.text += char;
                state = 4 /* InDashValue */;
                currentStyle = { style: 'kui--input-stripe-dash-region-value', text: '' };
                inputRanges.push(currentStyle);
            }
            else if (char === blank && (state === 3 /* InDoubleDash */ || state === 4 /* InDashValue */)) {
                // InDoubleDash | InDashValue -> Default
                state = 0 /* Default */;
                currentStyle = { style: '', text: char };
                inputRanges.push(currentStyle);
            }
            else {
                // stay
                currentStyle.text += char;
                if (state === 0 /* Default */ && char === blank) {
                    state = 1 /* InWhitespace */;
                }
                else if (state === 1 /* InWhitespace */ && char !== blank) {
                    state = 0 /* Default */;
                }
            }
        }
        return { inputCells, inputRanges };
    }
    /** Command has completed in our tab */
    onOutputRender() {
        this.setState(curState => ({
            idx: curState.idx + 1,
            model: Active(),
            inputCells: [],
            inputRanges: [],
            inputSelectionStart: 0,
            inputSelectionEnd: 0
        }));
    }
    /** Underlying Input element has changed content */
    onInputChange(event) {
        const { inputCells, inputRanges } = this.parse(event.currentTarget.value);
        this.setState({
            inputCells,
            inputRanges,
            inputSelectionStart: event.currentTarget.selectionStart,
            inputSelectionEnd: event.currentTarget.selectionEnd
        });
    }
    /** User has clicked on the underlying Input element */
    onInputClick(event) {
        this.setState({
            inputSelectionStart: event.currentTarget.selectionStart,
            inputSelectionEnd: event.currentTarget.selectionEnd
        });
    }
    /** onKeyUp in the underlying Input element */
    onInputKeyUp(event) {
        this.setState({
            inputSelectionStart: event.currentTarget.selectionStart,
            inputSelectionEnd: event.currentTarget.selectionEnd
        });
    }
    /** onMouseDown in the underlying Input element */
    onInputMouseDown(event) {
        this.setState({
            inputSelectionStart: event.currentTarget.selectionStart,
            inputSelectionEnd: event.currentTarget.selectionEnd
        });
    }
    /** onBlur in the underlying Input element */
    onInputBlur() {
        if (this._focusElement) {
            this._focusElement.removeAttribute('data-focused');
        }
    }
    /** onFocus in the underlying Input element */
    onInputFocus() {
        if (this._focusElement) {
            this._focusElement.setAttribute('data-focused', 'data-focused');
        }
    }
    /** Render the typed characters */
    typedCharacters() {
        return (React.createElement("div", { className: "kui--input-stripe-custom-input repl-input-like" }, this.state.inputRanges.map((_, idx) => {
            return (React.createElement("span", { key: idx, className: _.style }, _.text));
        })));
    }
    underlayFill() {
        const start = this.state.inputSelectionStart;
        return Array(start)
            .fill(0)
            .map((_, idx) => (React.createElement("span", { className: "kui--input-stripe-underlay-filler", key: idx }, this.state.inputCells[idx])));
    }
    underlaySelection() {
        const start = this.state.inputSelectionStart;
        const end = this.state.inputSelectionEnd;
        return Array(end - start)
            .fill(0)
            .map((_, idx) => (React.createElement("span", { key: start + idx, className: "kui--input-stripe-selection-range" }, "\u00A0")));
    }
    initCaret(c) {
        this._caret = c;
        if (this._caretBlinker) {
            clearInterval(this._caretBlinker);
        }
        this._caretBlinker = setInterval(() => {
            if (this._caret) {
                this._caret.classList.toggle('kui--input-stripe-caret-on');
            }
        }, 750);
    }
    underlayCaret() {
        return (React.createElement("span", { className: "kui--input-stripe-caret", ref: c => this.initCaret(c) }, "\u00A0"));
    }
    underlay() {
        return (React.createElement("div", { className: "kui--input-stripe-custom-underlay repl-input-like", ref: c => (this._focusElement = c) },
            this.underlayFill(),
            this.underlaySelection(),
            this.underlayCaret()));
    }
    render() {
        return (React.createElement("div", { className: "kui--input-stripe repl" },
            React.createElement(Block, { idx: this.state.idx, uuid: this.props.uuid, tab: this.props.tab, model: this.state.model, noOutput: true, noPromptContext: true, onInputBlur: this.onInputBlur.bind(this), onInputFocus: this.onInputFocus.bind(this), onInputClick: this.onInputClick.bind(this), onInputChange: this.onInputChange.bind(this), onInputKeyUp: this.onInputKeyUp.bind(this), onInputMouseDown: this.onInputMouseDown.bind(this), onInputMouseMove: this.onInputMouseDown.bind(this) },
                this.underlay(),
                this.typedCharacters())));
    }
}
//# sourceMappingURL=InputStripeExperimental.js.map