"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");

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

var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties"));

var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));

var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));

var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized"));

var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));

var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn"));

var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));

var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));

var _grey = _interopRequireDefault(require("@material-ui/core/colors/grey"));

var _react = _interopRequireDefault(require("react"));

var _reactDom = _interopRequireDefault(require("react-dom"));

var _propTypes = _interopRequireDefault(require("prop-types"));

var _mathRendering = require("../../math-rendering");

var _debug = _interopRequireDefault(require("debug"));

var _drag = require("../../drag");

var _styles = require("@material-ui/core/styles");

var _Chip = _interopRequireDefault(require("@material-ui/core/Chip"));

var _classnames3 = _interopRequireDefault(require("classnames"));

var _renderUi = require("../../render-ui");

var _excluded = ["connectDragSource", "connectDropTarget"];

function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); 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 = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { (0, _defineProperty2["default"])(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }

function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2["default"])(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2["default"])(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2["default"])(this, result); }; }

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; } }

var log = (0, _debug["default"])('pie-lib:mask-markup:blank');
var DRAG_TYPE = 'MaskBlank';
exports.DRAG_TYPE = DRAG_TYPE;
var useStyles = (0, _styles.withStyles)(function () {
  return {
    content: {
      border: "solid 0px ".concat(_renderUi.color.primary()),
      minWidth: '200px',
      touchAction: 'none',
      overflow: 'hidden',
      whiteSpace: 'nowrap' // Prevent line wrapping

    },
    chip: {
      backgroundColor: _renderUi.color.background(),
      border: "2px dashed ".concat(_renderUi.color.text()),
      color: _renderUi.color.text(),
      fontSize: 'inherit',
      maxWidth: '374px',
      position: 'relative',
      borderRadius: '3px'
    },
    chipLabel: {
      whiteSpace: 'normal',
      // Added for touch devices, for image content.
      // This will prevent the context menu from appearing and not allowing other interactions with the image.
      // If interactions with the image in the token will be requested we should handle only the context Menu.
      pointerEvents: 'none',
      '& img': {
        display: 'block',
        padding: '2px 0'
      },
      // Remove default <p> margins to ensure consistent spacing across all wrapped content (p, span, div, math)
      // Padding for top and bottom will instead be controlled by the container for consistent layout
      // Ensures consistent behavior with pie-api-browser, where marginTop is already removed by a Bootstrap stylesheet
      '& p': {
        marginTop: '0',
        marginBottom: '0'
      },
      '& mjx-frac': {
        fontSize: '120% !important'
      }
    },
    hidden: {
      color: 'transparent',
      opacity: 0
    },
    dragged: {
      position: 'absolute',
      left: 16,
      maxWidth: '60px'
    },
    correct: {
      border: "solid 1px ".concat(_renderUi.color.correct())
    },
    incorrect: {
      border: "solid 1px ".concat(_renderUi.color.incorrect())
    },
    over: {
      whiteSpace: 'nowrap',
      overflow: 'hidden'
    },
    parentOver: {
      border: "1px solid ".concat(_grey["default"][500]),
      backgroundColor: "".concat(_grey["default"][300])
    }
  };
});

var BlankContent = /*#__PURE__*/function (_React$Component) {
  (0, _inherits2["default"])(BlankContent, _React$Component);

  var _super = _createSuper(BlankContent);

  function BlankContent() {
    var _this;

    (0, _classCallCheck2["default"])(this, BlankContent);
    _this = _super.call(this);
    (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "handleImageLoad", function () {
      _this.updateDimensions();
    });
    (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "handleTouchStart", function (e) {
      e.preventDefault();
      _this.touchStartTimer = setTimeout(function () {
        _this.startDrag();
      }, 300); // Start drag after 300ms (touch and hold duration)
    });
    (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "startDrag", function () {
      var _this$props = _this.props,
          connectDragSource = _this$props.connectDragSource,
          disabled = _this$props.disabled;

      if (!disabled) {
        connectDragSource(_this.rootRef);
      }
    });
    _this.state = {
      height: 0,
      width: 0
    };
    return _this;
  }

  (0, _createClass2["default"])(BlankContent, [{
    key: "handleElements",
    value: function handleElements() {
      var _this$spanRef,
          _this2 = this;

      var imageElement = (_this$spanRef = this.spanRef) === null || _this$spanRef === void 0 ? void 0 : _this$spanRef.querySelector('img');

      if (imageElement) {
        imageElement.onload = this.handleImageLoad;
      } else {
        setTimeout(function () {
          _this2.updateDimensions();
        }, 300);
      }
    }
  }, {
    key: "componentDidMount",
    value: function componentDidMount() {
      this.handleElements();

      if (this.rootRef) {
        this.rootRef.addEventListener('touchstart', this.handleTouchStart, {
          passive: false
        });
      }
    }
  }, {
    key: "componentDidUpdate",
    value: function componentDidUpdate(prevProps) {
      (0, _mathRendering.renderMath)(this.rootRef);
      var currentChoice = this.props.choice;
      var prevChoice = prevProps.choice;

      if (JSON.stringify(currentChoice) !== JSON.stringify(prevChoice)) {
        if (!currentChoice) {
          this.setState({
            height: 0,
            width: 0
          });
          return;
        }

        this.handleElements();
      }
    }
  }, {
    key: "componentWillUnmount",
    value: function componentWillUnmount() {
      if (this.rootRef) {
        this.rootRef.removeEventListener('touchstart', this.handleTouchStart);
      }
    }
  }, {
    key: "updateDimensions",
    value: function updateDimensions() {
      if (this.spanRef && this.rootRef) {
        // Temporarily set rootRef width to 'auto' for natural measurement
        this.rootRef.style.width = 'auto'; // Get the natural dimensions of the content

        var width = this.spanRef.offsetWidth || 0;
        var height = this.spanRef.offsetHeight || 0;
        var widthWithPadding = width + 24; // 12px padding on each side

        var heightWithPadding = height + 24; // 12px padding on top and bottom

        var responseAreaWidth = parseFloat(this.props.emptyResponseAreaWidth) || 0;
        var responseAreaHeight = parseFloat(this.props.emptyResponseAreaHeight) || 0;
        var adjustedWidth = widthWithPadding <= responseAreaWidth ? responseAreaWidth : widthWithPadding;
        var adjustedHeight = heightWithPadding <= responseAreaHeight ? responseAreaHeight : heightWithPadding;
        this.setState(function (prevState) {
          return {
            width: adjustedWidth > responseAreaWidth ? adjustedWidth : prevState.width,
            height: adjustedHeight > responseAreaHeight ? adjustedHeight : prevState.height
          };
        });
        this.rootRef.style.width = "".concat(adjustedWidth, "px");
        this.rootRef.style.height = "".concat(adjustedHeight, "px");
      }
    }
  }, {
    key: "addDraggableFalseAttributes",
    value: function addDraggableFalseAttributes(parent) {
      parent.childNodes.forEach(function (elem) {
        if (elem instanceof Element || elem instanceof HTMLDocument) {
          elem.setAttribute('draggable', false);
        }
      });
    }
  }, {
    key: "getRootDimensions",
    value: function getRootDimensions() {
      // Handle potential non-numeric values
      var responseAreaWidth = !isNaN(parseFloat(this.props.emptyResponseAreaWidth)) ? parseFloat(this.props.emptyResponseAreaWidth) : 0;
      var responseAreaHeight = !isNaN(parseFloat(this.props.emptyResponseAreaHeight)) ? parseFloat(this.props.emptyResponseAreaHeight) : 0;
      var rootStyle = {
        height: this.state.height || responseAreaHeight,
        width: this.state.width || responseAreaWidth
      }; // add minWidth, minHeight if width and height are not defined
      // minWidth, minHeight will be also in model in the future

      return _objectSpread(_objectSpread(_objectSpread({}, rootStyle), responseAreaWidth ? {} : {
        minWidth: 90
      }), responseAreaHeight ? {} : {
        minHeight: 32
      });
    }
  }, {
    key: "render",
    value: function render() {
      var _this3 = this,
          _classnames2;

      var _this$props2 = this.props,
          disabled = _this$props2.disabled,
          choice = _this$props2.choice,
          classes = _this$props2.classes,
          isOver = _this$props2.isOver,
          dragItem = _this$props2.dragItem,
          correct = _this$props2.correct;
      var draggedLabel = dragItem && isOver && dragItem.choice.value;
      var label = choice && choice.value;
      return (
        /*#__PURE__*/
        // TODO the Chip element is causing drag problems on touch devices. Avoid using Chip and consider refactoring the code. Keep in mind that Chip is a span with a button role, which interferes with seamless touch device dragging.
        _react["default"].createElement(_Chip["default"], {
          clickable: false,
          disabled: true,
          ref: function ref(_ref3) {
            //eslint-disable-next-line
            _this3.rootRef = _reactDom["default"].findDOMNode(_ref3);
          },
          component: "span",
          label: /*#__PURE__*/_react["default"].createElement(_react["default"].Fragment, null, /*#__PURE__*/_react["default"].createElement("span", {
            className: (0, _classnames3["default"])(classes.chipLabel, isOver && classes.over, (0, _defineProperty2["default"])({}, classes.hidden, draggedLabel)),
            ref: function ref(_ref) {
              if (_ref) {
                //eslint-disable-next-line
                _this3.spanRef = _reactDom["default"].findDOMNode(_ref);
                _ref.innerHTML = label || '';

                _this3.addDraggableFalseAttributes(_ref);
              }
            }
          }, ' '), draggedLabel && /*#__PURE__*/_react["default"].createElement("span", {
            className: (0, _classnames3["default"])(classes.chipLabel, isOver && classes.over, classes.dragged),
            ref: function ref(_ref2) {
              if (_ref2) {
                //eslint-disable-next-line
                _this3.spanRef = _reactDom["default"].findDOMNode(_ref2);
                _ref2.innerHTML = draggedLabel || '';

                _this3.addDraggableFalseAttributes(_ref2);
              }
            }
          }, ' ')),
          className: (0, _classnames3["default"])(classes.chip, isOver && classes.over, isOver && classes.parentOver, (_classnames2 = {}, (0, _defineProperty2["default"])(_classnames2, classes.correct, correct !== undefined && correct), (0, _defineProperty2["default"])(_classnames2, classes.incorrect, correct !== undefined && !correct), _classnames2)),
          variant: disabled ? 'outlined' : undefined,
          style: _objectSpread({}, this.getRootDimensions())
        })
      );
    }
  }]);
  return BlankContent;
}(_react["default"].Component);

exports.BlankContent = BlankContent;
BlankContent.defaultProps = {
  emptyResponseAreaWidth: 0,
  emptyResponseAreaHeight: 0
};
BlankContent.propTypes = {
  id: _propTypes["default"].oneOfType([_propTypes["default"].string, _propTypes["default"].number]),
  disabled: _propTypes["default"].bool,
  duplicates: _propTypes["default"].bool,
  choice: _propTypes["default"].object,
  classes: _propTypes["default"].object,
  isOver: _propTypes["default"].bool,
  dragItem: _propTypes["default"].object,
  correct: _propTypes["default"].bool,
  onChange: _propTypes["default"].func,
  emptyResponseAreaWidth: _propTypes["default"].oneOfType([_propTypes["default"].string, _propTypes["default"].number]),
  emptyResponseAreaHeight: _propTypes["default"].oneOfType([_propTypes["default"].string, _propTypes["default"].number])
};
var StyledBlankContent = useStyles(BlankContent);
var connectedBlankContent = useStyles(function (_ref4) {
  var connectDragSource = _ref4.connectDragSource,
      connectDropTarget = _ref4.connectDropTarget,
      props = (0, _objectWithoutProperties2["default"])(_ref4, _excluded);
  var classes = props.classes,
      isOver = props.isOver;
  return connectDropTarget(connectDragSource( /*#__PURE__*/_react["default"].createElement("span", {
    className: (0, _classnames3["default"])(classes.content, isOver && classes.over)
  }, /*#__PURE__*/_react["default"].createElement(StyledBlankContent, props))));
});
var tileTarget = {
  drop: function drop(props, monitor) {
    var draggedItem = monitor.getItem();
    log('props.instanceId', props.instanceId, 'draggedItem.instanceId:', draggedItem.instanceId);

    if (draggedItem.id !== props.id) {
      props.onChange(props.id, draggedItem.choice.id);
    }

    return {
      dropped: draggedItem.id !== props.id
    };
  },
  canDrop: function canDrop(props, monitor) {
    var draggedItem = monitor.getItem();
    return draggedItem.instanceId === props.instanceId;
  }
};
var DropTile = (0, _drag.DropTarget)(DRAG_TYPE, tileTarget, function (connect, monitor) {
  return {
    connectDropTarget: connect.dropTarget(),
    isOver: monitor.isOver(),
    dragItem: monitor.getItem()
  };
})(connectedBlankContent);
var tileSource = {
  canDrag: function canDrag(props) {
    return !props.disabled && !!props.choice;
  },
  beginDrag: function beginDrag(props) {
    return {
      id: props.id,
      choice: props.choice,
      instanceId: props.instanceId,
      fromChoice: true
    };
  },
  endDrag: function endDrag(props, monitor) {
    // this will be null if it did not drop
    var dropResult = monitor.getDropResult();

    if (!dropResult || dropResult.dropped) {
      var draggedItem = monitor.getItem();

      if (draggedItem.fromChoice) {
        props.onChange(props.id, undefined);
      }
    }
  }
};
var DragDropTile = (0, _drag.DragSource)(DRAG_TYPE, tileSource, function (connect, monitor) {
  return {
    connectDragSource: connect.dragSource(),
    isDragging: monitor.isDragging()
  };
})(DropTile);
var _default = DragDropTile;
exports["default"] = _default;
//# sourceMappingURL=blank.js.map