import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
import _createClass from "@babel/runtime/helpers/createClass";
import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstructorReturn";
import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf";
import _inherits from "@babel/runtime/helpers/inherits";
import _assertThisInitialized from "@babel/runtime/helpers/assertThisInitialized";
import _defineProperty from "@babel/runtime/helpers/defineProperty";

var _dec, _class, _class2, _temp;

import React from 'react';
import PropTypes from 'prop-types';
import ReactDOM from 'react-dom';
import { style } from 'typestyle';
import { withTheme, Button } from '@material-ui/core';
import Backspace from '@material-ui/icons/Backspace';
import { Pos } from 'codemirror';
import includes from 'lodash/includes';
import Cancel from '@material-ui/icons/Cancel';
import SubdirectoryArrowRight from '@material-ui/icons/SubdirectoryArrowRight';
import { fade } from '@material-ui/core/styles/colorManipulator';
import isNotDeletableLine from './isNotDeletableLine';
var dummyNode = document.createElement('div');
var cn = {
  background: style({
    backgroundColor: 'rgba(0, 0, 0, 0.04)'
  }),
  blank: style({
    flex: 1
  }),
  parent: style({
    display: 'flex',
    alignItems: 'center',
    position: 'relative',
    width: '100%'
  })
};

var getCn = function getCn(_ref, state) {
  var theme = _ref.theme;
  var backgroundColor = theme.palette.type === 'light' ? theme.palette.grey[300] : theme.palette.grey[700];
  var deleteIconColor = fade(theme.palette.text.primary, 0.26);
  return {
    button: style({
      margin: theme.spacing.unit,
      flexShrink: 0
    }),
    copy: style({
      transform: "rotateX(".concat(state.above ? 180 : 0, "deg)") // copy してくる方向

    }),
    paste: style({
      transform: "rotateZ(90deg) rotateY(".concat(state.above ? 180 : 0, "deg)") // paste する方向

    }),
    clipboard: style({
      textOverflow: 'ellipsis',
      whiteSpace: 'nowrap',
      overflow: 'hidden',
      height: 20,
      padding: 4,
      paddingBottom: 0,
      // buggy
      borderRadius: 14,
      fontSize: 10,
      flexGrow: 0,
      flexShrink: 1,
      transition: theme.transitions.create(['background-color', 'color']),
      backgroundColor: state.clipboard ? backgroundColor : 'transparent',
      color: state.clipboard ? theme.palette.text.primary : theme.palette.text.disabled
    }),
    cancel: style({
      fontSize: 16,
      color: deleteIconColor,
      verticalAlign: 'middle',
      cursor: 'pointer',
      $nest: {
        '&:hover': {
          color: fade(deleteIconColor, 0.4)
        }
      }
    })
  };
};

var LineWidget = (_dec = withTheme(), _dec(_class = (_temp = _class2 =
/*#__PURE__*/
function (_React$Component) {
  _inherits(LineWidget, _React$Component);

  function LineWidget() {
    var _getPrototypeOf2;

    var _this;

    _classCallCheck(this, LineWidget);

    for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
      args[_key] = arguments[_key];
    }

    _this = _possibleConstructorReturn(this, (_getPrototypeOf2 = _getPrototypeOf(LineWidget)).call.apply(_getPrototypeOf2, [this].concat(args)));

    _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "state", {
      line: -1,
      above: false,
      widget: null,
      notDeletable: false,
      text: '',
      clipboard: null
    });

    _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "handleLineWidget", function (cm) {
      if (includes(cm.getSelection(), '\n')) return; // 複数行選択されている場合は omit
      // Delete line button

      var cursor = cm.getCursor();

      if (!cursor.line && !cursor.ch && cursor.sticky === null) {
        // runApp した時に0行目に line widget が移るのを防ぐ
        // setValue すると LineWidget が消えるみたいなので作り直す
        _this.setLineWidget(cm, _this.state.line);

        return;
      }

      if (_this.state.line !== cursor.line) {
        // 行が変わっていたら LineWidget も作り直す必要がある
        _this.setLineWidget(cm, cursor.line);
      }
    });

    _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "handleDone", function () {
      // 現在の LineWidget を消す
      var _this$state = _this.state,
          line = _this$state.line,
          widget = _this$state.widget;

      if (line > -1) {
        _this.props.codemirror.removeLineClass(line, 'wrap', cn.background); // 背景色を戻す

      }

      if (widget) {
        widget.clear();
      }

      _this.setState({
        widget: null,
        line: -1
      });
    });

    _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "handleLineDeleteClick", function () {
      var cm = _this.props.codemirror;
      var line = _this.state.line;
      var cursor = cm.getCursor();
      var from = new Pos(line, 0);
      var to = new Pos(line + 1, 0);
      cm.replaceRange('', from, to, 'change'); // 1行削除

      cm.focus(); // ボタンを押したのでフォーカスが外れている. それを戻す

      cm.setCursor(new Pos(line, cursor.ch)); // カーソルを新しい位置に

      _this.setLineWidget(cm, line); // 次の行(消したのでlineは同じ)に移動

    });

    _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "handleBlur", function (cm) {
      // 背景色だけが残らないようにする
      if (!_this.props.show && _this.state.line > -1) {
        cm.removeLineClass(_this.state.line, 'wrap', cn.background); // 背景色を戻す
      }
    });

    _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "handleLineCopyClick", function () {
      var cm = _this.props.codemirror;
      var line = _this.state.line;
      var text = cm.getLine(line);

      _this.setState({
        clipboard: text
      });

      cm.focus();
    });

    _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "handleLinePasteClick", function () {
      var cm = _this.props.codemirror;
      var _this$state2 = _this.state,
          line = _this$state2.line,
          above = _this$state2.above,
          clipboard = _this$state2.clipboard;
      if (!clipboard) return;
      var pos = new Pos(above ? line : line + 1, 0);
      cm.replaceRange(clipboard + '\n', pos, pos);

      _this.setState({
        clipboard: null
      });

      _this.props.runApp();
    });

    _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "clearClipboard", function () {
      _this.setState({
        clipboard: null
      });
    });

    return _this;
  }

  _createClass(LineWidget, [{
    key: "componentDidMount",
    value: function componentDidMount() {
      var codemirror = this.props.codemirror;
      codemirror.on('cursorActivity', this.handleLineWidget);
      codemirror.on('blur', this.handleBlur);
    }
  }, {
    key: "componentDidUpdate",
    value: function componentDidUpdate(prevProps) {
      var line = this.state.line;

      if (!prevProps.show && this.props.show && line > -1) {
        this.setLineWidget(this.props.codemirror, line);
      }

      if (prevProps.show && !this.props.show && line > -1) {
        this.handleDone();
      }
    }
  }, {
    key: "setLineWidget",
    value: function setLineWidget(cm, line) {
      if (!this.props.show) return; // 前回の Widget を消す

      if (this.state.line > -1) {
        cm.removeLineClass(this.state.line, 'wrap', cn.background); // 背景色を戻す
      }

      if (this.state.widget) {
        this.state.widget.clear();
      }

      if (line === -1) return; // カーソルが定まっていない
      // Widget を作って出す

      cm.addLineClass(line, 'wrap', cn.background); // 背景色をつける

      var parent = document.createElement('div');
      parent.classList.add(cn.parent);
      var above = this.state.line > -1 ? line === this.state.line ? this.state.above : line > this.state.line : false;
      var widget = cm.addLineWidget(line, parent, {
        noHScroll: true,
        above: above
      });
      this.setState({
        widget: widget,
        line: line,
        above: above,
        text: widget.line.text,
        notDeletable: isNotDeletableLine(cm.getLine(line)) // 削除できるかどうか

      });
    }
  }, {
    key: "render",
    value: function render() {
      var _this$state3 = this.state,
          widget = _this$state3.widget,
          clipboard = _this$state3.clipboard,
          text = _this$state3.text;
      if (!this.props.show) return null;
      var node = widget ? widget.node : dummyNode;
      var dcn = getCn(this.props, this.state);
      var chipText = clipboard || text;
      return ReactDOM.createPortal(React.createElement(React.Fragment, null, !clipboard ? React.createElement(Button, {
        variant: "text",
        size: "small",
        className: dcn.button,
        onClick: this.handleLineCopyClick,
        disabled: !text || this.state.notDeletable
      }, React.createElement(SubdirectoryArrowRight, {
        className: dcn.copy,
        fontSize: "small"
      }), this.props.localization.editorCard.copyLine) : React.createElement(Button, {
        variant: "text",
        size: "small",
        className: dcn.button,
        onClick: this.handleLinePasteClick
      }, React.createElement(SubdirectoryArrowRight, {
        className: dcn.paste,
        fontSize: "small"
      }), this.props.localization.editorCard.pasteLine), chipText && React.createElement("div", {
        className: dcn.clipboard
      }, clipboard ? React.createElement(Cancel, {
        className: dcn.cancel,
        onClick: this.clearClipboard
      }) : null, chipText), React.createElement("div", {
        className: cn.blank
      }), React.createElement(Button, {
        variant: "text",
        size: "small",
        className: dcn.button,
        onClick: this.handleLineDeleteClick,
        disabled: this.state.notDeletable
      }, React.createElement(Backspace, {
        fontSize: "small"
      }), this.props.localization.editorCard.deleteLine)), node);
    }
  }]);

  return LineWidget;
}(React.Component), _defineProperty(_class2, "propTypes", {
  show: PropTypes.bool.isRequired,
  codemirror: PropTypes.object.isRequired,
  runApp: PropTypes.func.isRequired,
  localization: PropTypes.object.isRequired
}), _temp)) || _class);
export { LineWidget as default };