import "choerodon-ui/pro/lib/button/style";
import _Button from "choerodon-ui/pro/lib/button";

function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }

function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }

function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }

function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }

function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }

function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }

function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }

function _possibleConstructorReturn(self, call) { if (call && (typeof call === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }

function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }

function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }

function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }

import React from 'react';
import { FormattedMessage } from 'react-intl';
import _ from 'lodash';
import "./Codemirror.less";

function normalizeLineEndings(str) {
  if (!str) return str;
  return str.replace(/\r\n|\r/g, '\n');
}

var CodeMirror = /*#__PURE__*/function (_React$Component) {
  _inherits(CodeMirror, _React$Component);

  var _super = _createSuper(CodeMirror);

  function CodeMirror(props) {
    var _this;

    _classCallCheck(this, CodeMirror);

    _this = _super.call(this, props);

    _this.handleChangeView = function () {
      _this.initUI(_this.state.viewMode === 'normal' ? 'diff' : 'normal');

      _this.setState({
        viewMode: _this.state.viewMode === 'normal' ? 'diff' : 'normal'
      });
    };

    _this.getCodeMirror = function () {
      return _this.codeMirror;
    };

    _this.codemirrorValueChanged = function (doc, change) {
      if (_this.props.onChange && change.origin !== 'setValue') {
        _this.props.onChange(doc.getValue(), change);
      }
    };

    _this.state = {
      viewMode: 'normal'
    }; // 多个编辑器同时存在时，生成不同的id，以便点击切换编辑模式查找对应的id

    _this.codeMirrorId = Date.now();
    return _this;
  }

  _createClass(CodeMirror, [{
    key: "getCodeMirrorInstance",
    value: function getCodeMirrorInstance() {
      return this.props.codeMirrorInstance || require('codemirror');
    }
  }, {
    key: "componentDidMount",
    value: function componentDidMount() {
      this.initUI();
    }
  }, {
    key: "componentDidUpdate",
    value: function componentDidUpdate(prevProps, prevState) {
      if (this.codeMirror && this.props.value !== undefined && this.props.value !== prevProps.value && normalizeLineEndings(this.codeMirror.getValue()) !== normalizeLineEndings(this.props.value)) {
        this.codeMirror.setValue(this.props.value);
      }

      if (typeof this.props.options === 'object') {
        for (var optionName in this.props.options) {
          if (this.props.options.hasOwnProperty(optionName)) {
            this.setOptionIfChanged(optionName, this.props.options[optionName]);
          }
        }
      }
    }
  }, {
    key: "componentWillUnmount",
    value: function componentWillUnmount() {
      var viewMode = this.state.viewMode;

      if (this.codeMirror && viewMode === 'normal') {
        this.codeMirror.toTextArea();
      }
    }
  }, {
    key: "initUI",
    value: function initUI() {
      var viewMode = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.state.viewMode;
      var _this$props = this.props,
          options = _this$props.options,
          value = _this$props.value,
          originValue = _this$props.originValue;
      var view = document.getElementById(this.codeMirrorId);
      var codeMirrorInstance = this.getCodeMirrorInstance();

      if (viewMode === 'diff') {
        if (this.codeMirror) {
          this.codeMirror.toTextArea();
          this.codeMirror = null;
        }

        var mergeViewOptions = _objectSpread({
          value: value || '',
          origRight: originValue || '',
          connect: 'align',
          // 对比编辑器是否可编辑
          allowEditingOriginals: false,
          showDifferences: true,
          highlightDifferences: true,
          collapseIdentical: false
        }, options);

        this.mergeView = codeMirrorInstance.MergeView(view, mergeViewOptions);
        this.codeMirror = this.mergeView.edit;
      } else {
        view.innerHTML = '';
        this.mergeView = null;
        this.codeMirror = codeMirrorInstance.fromTextArea(this.textareaNode, options);
      }

      this.codeMirror.on('change', this.codemirrorValueChanged);
      this.codeMirror.setValue(value || '');
    }
  }, {
    key: "setOptionIfChanged",
    value: function setOptionIfChanged(optionName, newValue) {
      var oldValue = this.codeMirror.getOption(optionName);

      if (!_.isEqual(oldValue, newValue)) {
        this.codeMirror.setOption(optionName, newValue);
      }
    }
  }, {
    key: "getLegends",
    get: function get() {
      var LEGEND_TYPE = ['new', 'delete', 'modify', 'error'];
      return _.map(LEGEND_TYPE, function (item) {
        return /*#__PURE__*/React.createElement("span", {
          key: item,
          className: "c7ncd-editor-legend-item c7ncd-editor-legend_".concat(item)
        }, /*#__PURE__*/React.createElement(FormattedMessage, {
          id: "editor.legend.".concat(item)
        }));
      });
    }
  }, {
    key: "render",
    value: function render() {
      var _this2 = this;

      var _this$props2 = this.props,
          options = _this$props2.options,
          modeChange = _this$props2.modeChange;
      var canChangeMode = !options.readOnly && modeChange;
      var editor = null;

      if (canChangeMode) {
        var viewMode = this.state.viewMode;
        editor = /*#__PURE__*/React.createElement("div", {
          className: "c7ncd-editor-tools"
        }, /*#__PURE__*/React.createElement(_Button, {
          funcType: "flat",
          onClick: this.handleChangeView
        }, /*#__PURE__*/React.createElement(FormattedMessage, {
          id: "editor.mode.changer"
        })), viewMode === 'diff' ? /*#__PURE__*/React.createElement("div", {
          className: "c7ncd-editor-legend"
        }, this.getLegends) : null);
      }

      return /*#__PURE__*/React.createElement("div", {
        className: "c7ncd-codemirror"
      }, editor, /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("textarea", {
        className: "hidden-textarea",
        ref: function ref(_ref) {
          return _this2.textareaNode = _ref;
        },
        defaultValue: this.props.value,
        autoComplete: "off"
      }), /*#__PURE__*/React.createElement("div", {
        id: this.codeMirrorId
      })));
    }
  }]);

  return CodeMirror;
}(React.Component);

CodeMirror.defaultProps = {
  viewMode: 'normal'
};
export default CodeMirror;