'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _propTypes = require('prop-types');

var _propTypes2 = _interopRequireDefault(_propTypes);

var _reactDom = require('react-dom');

var _reactDnd = require('react-dnd');

var _omit = require('lodash/omit');

var _omit2 = _interopRequireDefault(_omit);

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

function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; }

var itemSource = {
  beginDrag: function beginDrag(props) {
    return {
      index: props.index
    };
  },
  endDrag: function endDrag(props) {
    props.endDrag(props);
  }
};

var itemTarget = {
  hover: function hover(props, monitor, component) {
    var dragIndex = monitor.getItem().index;
    var hoverIndex = props.index;

    // Don't replace items with themselves
    if (dragIndex === hoverIndex) {
      return;
    }

    // Determine rectangle on screen
    var hoverBoundingRect = (0, _reactDom.findDOMNode)(component).getBoundingClientRect(); // eslint-disable-line react/no-find-dom-node

    // Get vertical middle
    var hoverMiddleY = (hoverBoundingRect.bottom - hoverBoundingRect.top) / 2;

    // Determine mouse position
    var clientOffset = monitor.getClientOffset();

    // Get pixels to the top
    var hoverClientY = clientOffset.y - hoverBoundingRect.top;

    // Only perform the move when the mouse has crossed half of the items height
    // When dragging downwards, only move when the cursor is below 50%
    // When dragging upwards, only move when the cursor is above 50%

    // Dragging downwards
    if (dragIndex < hoverIndex && hoverClientY < hoverMiddleY) {
      return;
    }

    // Dragging upwards
    if (dragIndex > hoverIndex && hoverClientY > hoverMiddleY) {
      return;
    }

    // Time to actually perform the action
    props.moveItem(dragIndex, hoverIndex);

    // Note: we're mutating the monitor item here!
    // Generally it's better to avoid mutations,
    // but it's good here for the sake of performance
    // to avoid expensive index searches.
    monitor.getItem().index = hoverIndex; // eslint-disable-line no-param-reassign
  }
};

var propTypes = {
  connectDragSource: _propTypes2.default.func.isRequired,
  connectDropTarget: _propTypes2.default.func.isRequired,
  isDragging: _propTypes2.default.bool,
  className: _propTypes2.default.string
};

var defaultProps = {
  isDragging: false,
  listName: 'list-item',
  className: undefined
};

var SortableItem = function SortableItem(_ref) {
  var isDragging = _ref.isDragging,
      connectDragSource = _ref.connectDragSource,
      connectDropTarget = _ref.connectDropTarget,
      className = _ref.className,
      rest = _objectWithoutProperties(_ref, ['isDragging', 'connectDragSource', 'connectDropTarget', 'className']);

  return connectDragSource(connectDropTarget(_react2.default.createElement('div', _extends({
    style: { opacity: isDragging ? '0' : '1' },
    className: className
  }, (0, _omit2.default)(rest, ['listName', 'index', 'moveItem', 'endDrag'])))));
};

SortableItem.propTypes = propTypes;
SortableItem.defaultProps = defaultProps;

exports.default = (0, _reactDnd.DropTarget)(function (props) {
  return props.listName;
}, itemTarget, function (connect) {
  return {
    connectDropTarget: connect.dropTarget()
  };
})((0, _reactDnd.DragSource)(function (props) {
  return props.listName;
}, itemSource, function (connect, monitor) {
  return {
    connectDragSource: connect.dragSource(),
    isDragging: monitor.isDragging()
  };
})(SortableItem));
module.exports = exports['default'];