'use strict';
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
var __importStar = (this && this.__importStar) || function (mod) {
    if (mod && mod.__esModule) return mod;
    var result = {};
    if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
    result["default"] = mod;
    return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
var react_dom_1 = __importDefault(require("react-dom"));
var react_dnd_1 = __importStar(require("react-dnd"));
exports.ReactDND = react_dnd_1.default;
var react_dnd_html5_backend_1 = __importDefault(require("react-dnd-html5-backend"));
exports.ReactHTML5Backend = react_dnd_html5_backend_1.default;
var keyboardSortableContext_1 = require("./keyboardSortableContext");
var keyboardSortableListItem_1 = require("./keyboardSortableListItem");
/**
 * @param {React.Component} Component
 * @return {function}
 */
var dndContext;
function DndSortableListContainer(Component) {
    Component = keyboardSortableContext_1.keyboardSortableContext(Component);
    dndContext = dndContext || react_dnd_1.DragDropContext(react_dnd_html5_backend_1.default);
    return dndContext(Component);
}
exports.DndSortableListContainer = DndSortableListContainer;
/**
 * @param {string} name
 * @return {function}
 */
function DndSortableListItem(name) {
    return function (Component) {
        var dropTarget = react_dnd_1.DropTarget(name, {
            hover: function (props, monitor, component) {
                var dragItem = monitor.getItem();
                var hoverItem = {
                    dndId: props.dndId,
                    index: props.index
                };
                // Don't replace items with themselves
                if (dragItem.dndId === hoverItem.dndId) {
                    return;
                }
                if (props.onHover) {
                    props.onHover(dragItem, hoverItem, isVerticalMiddleCrossed(dragItem, hoverItem, monitor, component));
                }
            },
            drop: function (props, monitor) {
                if (props.onMove) {
                    props.onMove(monitor.getItem().dndId, props.dndId);
                }
            }
        }, function (connect) {
            return {
                connectDropTarget: connect.dropTarget()
            };
        });
        var dragSource = react_dnd_1.DragSource(name, {
            beginDrag: function (props) {
                return {
                    dndId: props.dndId,
                    index: props.index
                };
            }
        }, function (connect, monitor) {
            return {
                connectDragSource: connect.dragSource(),
                connectDragPreview: connect.dragPreview(),
                isDragging: monitor.isDragging()
            };
        });
        return keyboardSortableListItem_1.keyboardSortableListItem(dropTarget(dragSource(Component)));
    };
}
exports.DndSortableListItem = DndSortableListItem;
function isVerticalMiddleCrossed(dragItem, hoverItem, monitor, component) {
    var result = true;
    // Determine rectangle on screen
    var hoverBoundingRect = react_dom_1.default.findDOMNode(component).getBoundingClientRect();
    // 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
    var dragIndex = dragItem.index;
    var hoverIndex = hoverItem.index;
    if (dragIndex < hoverIndex && hoverClientY < hoverMiddleY) {
        result = false;
    }
    // Dragging upwards
    if (dragIndex > hoverIndex && hoverClientY > hoverMiddleY) {
        result = false;
    }
    return result;
}
//# sourceMappingURL=index.js.map