"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;
var _react = _interopRequireDefault(require("react"));
var _Events = require("@kui-shell/core/mdist/api/Events");
var _Block = _interopRequireDefault(require("../Views/Terminal/Block"));
var _BlockModel = require("../Views/Terminal/Block/BlockModel");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/*
 * Copyright 2020 The Kubernetes Authors
 *
 * 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.
 */

const blank = '\u00a0';
class InputStripe extends _react.default.PureComponent {
  constructor(props) {
    super(props);
    _Events.eventBus.onCommandComplete(this.props.uuid, this.onOutputRender.bind(this));
    this.state = {
      idx: 0,
      model: (0, _BlockModel.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 /* ParseState.Default */;
    for (let idx = 0; idx < inputCells.length; idx++) {
      const char = inputCells[idx];
      if (state === 1 /* ParseState.InWhitespace */ && char === '-') {
        // Default -> InDash
        state = 2 /* ParseState.InDash */;
        currentStyle = {
          style: 'kui--input-stripe-dash-region-key',
          text: char
        };
        inputRanges.push(currentStyle);
      } else if (state === 2 /* ParseState.InDash */ && char === '-') {
        // InDash -> InDoubleDash
        state = 3 /* ParseState.InDoubleDash */;
        currentStyle.text += char;
      } else if (state === 2 /* ParseState.InDash */ || state === 3 /* ParseState.InDoubleDash */ && char === '=') {
        // InDash -> InDashValue
        // InDoubleDash= -> InDashValue
        currentStyle.text += char;
        state = 4 /* ParseState.InDashValue */;
        currentStyle = {
          style: 'kui--input-stripe-dash-region-value',
          text: ''
        };
        inputRanges.push(currentStyle);
      } else if (char === blank && (state === 3 /* ParseState.InDoubleDash */ || state === 4 /* ParseState.InDashValue */)) {
        // InDoubleDash | InDashValue -> Default
        state = 0 /* ParseState.Default */;
        currentStyle = {
          style: '',
          text: char
        };
        inputRanges.push(currentStyle);
      } else {
        // stay
        currentStyle.text += char;
        if (state === 0 /* ParseState.Default */ && char === blank) {
          state = 1 /* ParseState.InWhitespace */;
        } else if (state === 1 /* ParseState.InWhitespace */ && char !== blank) {
          state = 0 /* ParseState.Default */;
        }
      }
    }

    return {
      inputCells,
      inputRanges
    };
  }
  /** Command has completed in our tab */
  onOutputRender() {
    this.setState(curState => ({
      idx: curState.idx + 1,
      model: (0, _BlockModel.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.default.createElement("div", {
      className: "kui--input-stripe-custom-input repl-input-like"
    }, this.state.inputRanges.map((_, idx) => {
      return _react.default.createElement("span", {
        key: idx,
        className: _.style
      }, _.text);
    }));
  }
  underlayFill() {
    const start = this.state.inputSelectionStart;
    return Array(start).fill(0).map((_, idx) => _react.default.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.default.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.default.createElement("span", {
      className: "kui--input-stripe-caret",
      ref: c => this.initCaret(c)
    }, "\u00A0");
  }
  underlay() {
    return _react.default.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.default.createElement("div", {
      className: "kui--input-stripe repl"
    }, _react.default.createElement(_Block.default, {
      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()));
  }
}
exports.default = InputStripe;