"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

var React = _interopRequireWildcard(require("react"));

var _core = require("@kui-shell/core");

var _Block = _interopRequireDefault(require("../Views/Terminal/Block"));

var _BlockModel = require("../Views/Terminal/Block/BlockModel");

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }

/*
 * 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.
 */
const blank = '\u00a0';

class InputStripe extends React.PureComponent {
  constructor(props) {
    super(props);

    _core.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
    /* 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: (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.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.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;