/**
 * DevExtreme (cjs/events/drag.js)
 * Version: 23.2.6 (build 24140-0112)
 * Build date: Sun May 19 2024
 *
 * Copyright (c) 2012 - 2024 Developer Express Inc. ALL RIGHTS RESERVED
 * Read about DevExtreme licensing here: https://js.devexpress.com/Licensing/
 */
"use strict";
exports.start = exports.move = exports.leave = exports.enter = exports.end = exports.drop = void 0;
var _renderer = _interopRequireDefault(require("../core/renderer"));
var _element_data = require("../core/element_data");
var _array = require("../core/utils/array");
var iteratorUtils = _interopRequireWildcard(require("../core/utils/iterator"));
var _dom = require("../core/utils/dom");
var _event_registrator = _interopRequireDefault(require("./core/event_registrator"));
var _index = require("./utils/index");
var _emitter = _interopRequireDefault(require("./gesture/emitter.gesture"));
var _emitter_registrator = _interopRequireDefault(require("./core/emitter_registrator"));

function _getRequireWildcardCache(nodeInterop) {
    if ("function" !== typeof WeakMap) {
        return null
    }
    var cacheBabelInterop = new WeakMap;
    var cacheNodeInterop = new WeakMap;
    return (_getRequireWildcardCache = function(nodeInterop) {
        return nodeInterop ? cacheNodeInterop : cacheBabelInterop
    })(nodeInterop)
}

function _interopRequireWildcard(obj, nodeInterop) {
    if (!nodeInterop && obj && obj.__esModule) {
        return obj
    }
    if (null === obj || "object" !== typeof obj && "function" !== typeof obj) {
        return {
            default: obj
        }
    }
    var cache = _getRequireWildcardCache(nodeInterop);
    if (cache && cache.has(obj)) {
        return cache.get(obj)
    }
    var newObj = {};
    var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
    for (var key in obj) {
        if ("default" !== key && Object.prototype.hasOwnProperty.call(obj, key)) {
            var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
            if (desc && (desc.get || desc.set)) {
                Object.defineProperty(newObj, key, desc)
            } else {
                newObj[key] = obj[key]
            }
        }
    }
    newObj.default = obj;
    if (cache) {
        cache.set(obj, newObj)
    }
    return newObj
}

function _interopRequireDefault(obj) {
    return obj && obj.__esModule ? obj : {
        default: obj
    }
}
const DRAG_START_EVENT = "dxdragstart";
exports.start = "dxdragstart";
const DRAG_EVENT = "dxdrag";
exports.move = "dxdrag";
const DRAG_END_EVENT = "dxdragend";
exports.end = "dxdragend";
const DRAG_ENTER_EVENT = "dxdragenter";
exports.enter = DRAG_ENTER_EVENT;
const DRAG_LEAVE_EVENT = "dxdragleave";
exports.leave = DRAG_LEAVE_EVENT;
const DROP_EVENT = "dxdrop";
exports.drop = DROP_EVENT;
const DX_DRAG_EVENTS_COUNT_KEY = "dxDragEventsCount";
const knownDropTargets = [];
const knownDropTargetSelectors = [];
const knownDropTargetConfigs = [];
const dropTargetRegistration = {
    setup: function(element, data) {
        const knownDropTarget = knownDropTargets.includes(element);
        if (!knownDropTarget) {
            knownDropTargets.push(element);
            knownDropTargetSelectors.push([]);
            knownDropTargetConfigs.push(data || {})
        }
    },
    add: function(element, handleObj) {
        const index = knownDropTargets.indexOf(element);
        this.updateEventsCounter(element, handleObj.type, 1);
        const selector = handleObj.selector;
        if (!knownDropTargetSelectors[index].includes(selector)) {
            knownDropTargetSelectors[index].push(selector)
        }
    },
    updateEventsCounter: function(element, event, value) {
        if ([DRAG_ENTER_EVENT, DRAG_LEAVE_EVENT, DROP_EVENT].indexOf(event) > -1) {
            const eventsCount = (0, _element_data.data)(element, "dxDragEventsCount") || 0;
            (0, _element_data.data)(element, "dxDragEventsCount", Math.max(0, eventsCount + value))
        }
    },
    remove: function(element, handleObj) {
        this.updateEventsCounter(element, handleObj.type, -1)
    },
    teardown: function(element) {
        const handlersCount = (0, _element_data.data)(element, "dxDragEventsCount");
        if (!handlersCount) {
            const index = knownDropTargets.indexOf(element);
            knownDropTargets.splice(index, 1);
            knownDropTargetSelectors.splice(index, 1);
            knownDropTargetConfigs.splice(index, 1);
            (0, _element_data.removeData)(element, "dxDragEventsCount")
        }
    }
};
(0, _event_registrator.default)(DRAG_ENTER_EVENT, dropTargetRegistration);
(0, _event_registrator.default)(DRAG_LEAVE_EVENT, dropTargetRegistration);
(0, _event_registrator.default)(DROP_EVENT, dropTargetRegistration);
const getItemDelegatedTargets = function($element) {
    const dropTargetIndex = knownDropTargets.indexOf($element.get(0));
    const dropTargetSelectors = knownDropTargetSelectors[dropTargetIndex].filter(selector => selector);
    let $delegatedTargets = $element.find(dropTargetSelectors.join(", "));
    if (knownDropTargetSelectors[dropTargetIndex].includes(void 0)) {
        $delegatedTargets = $delegatedTargets.add($element)
    }
    return $delegatedTargets
};
const getItemConfig = function($element) {
    const dropTargetIndex = knownDropTargets.indexOf($element.get(0));
    return knownDropTargetConfigs[dropTargetIndex]
};
const getItemPosition = function(dropTargetConfig, $element) {
    if (dropTargetConfig.itemPositionFunc) {
        return dropTargetConfig.itemPositionFunc($element)
    } else {
        return $element.offset()
    }
};
const getItemSize = function(dropTargetConfig, $element) {
    if (dropTargetConfig.itemSizeFunc) {
        return dropTargetConfig.itemSizeFunc($element)
    }
    return {
        width: $element.get(0).getBoundingClientRect().width,
        height: $element.get(0).getBoundingClientRect().height
    }
};
const DragEmitter = _emitter.default.inherit({
    ctor: function(element) {
        this.callBase(element);
        this.direction = "both"
    },
    _init: function(e) {
        this._initEvent = e
    },
    _start: function(e) {
        e = this._fireEvent("dxdragstart", this._initEvent);
        this._maxLeftOffset = e.maxLeftOffset;
        this._maxRightOffset = e.maxRightOffset;
        this._maxTopOffset = e.maxTopOffset;
        this._maxBottomOffset = e.maxBottomOffset;
        if (e.targetElements || null === e.targetElements) {
            const dropTargets = (0, _array.wrapToArray)(e.targetElements || []);
            this._dropTargets = iteratorUtils.map(dropTargets, (function(element) {
                return (0, _renderer.default)(element).get(0)
            }))
        } else {
            this._dropTargets = knownDropTargets
        }
    },
    _move: function(e) {
        const eventData = (0, _index.eventData)(e);
        const dragOffset = this._calculateOffset(eventData);
        e = this._fireEvent("dxdrag", e, {
            offset: dragOffset
        });
        this._processDropTargets(e);
        if (!e._cancelPreventDefault) {
            e.preventDefault()
        }
    },
    _calculateOffset: function(eventData) {
        return {
            x: this._calculateXOffset(eventData),
            y: this._calculateYOffset(eventData)
        }
    },
    _calculateXOffset: function(eventData) {
        if ("vertical" !== this.direction) {
            const offset = eventData.x - this._startEventData.x;
            return this._fitOffset(offset, this._maxLeftOffset, this._maxRightOffset)
        }
        return 0
    },
    _calculateYOffset: function(eventData) {
        if ("horizontal" !== this.direction) {
            const offset = eventData.y - this._startEventData.y;
            return this._fitOffset(offset, this._maxTopOffset, this._maxBottomOffset)
        }
        return 0
    },
    _fitOffset: function(offset, minOffset, maxOffset) {
        if (null != minOffset) {
            offset = Math.max(offset, -minOffset)
        }
        if (null != maxOffset) {
            offset = Math.min(offset, maxOffset)
        }
        return offset
    },
    _processDropTargets: function(e) {
        const target = this._findDropTarget(e);
        const sameTarget = target === this._currentDropTarget;
        if (!sameTarget) {
            this._fireDropTargetEvent(e, DRAG_LEAVE_EVENT);
            this._currentDropTarget = target;
            this._fireDropTargetEvent(e, DRAG_ENTER_EVENT)
        }
    },
    _fireDropTargetEvent: function(event, eventName) {
        if (!this._currentDropTarget) {
            return
        }
        const eventData = {
            type: eventName,
            originalEvent: event,
            draggingElement: this._$element.get(0),
            target: this._currentDropTarget
        };
        (0, _index.fireEvent)(eventData)
    },
    _findDropTarget: function(e) {
        const that = this;
        let result;
        iteratorUtils.each(knownDropTargets, (function(_, target) {
            if (!that._checkDropTargetActive(target)) {
                return
            }
            const $target = (0, _renderer.default)(target);
            iteratorUtils.each(getItemDelegatedTargets($target), (function(_, delegatedTarget) {
                const $delegatedTarget = (0, _renderer.default)(delegatedTarget);
                if (that._checkDropTarget(getItemConfig($target), $delegatedTarget, (0, _renderer.default)(result), e)) {
                    result = delegatedTarget
                }
            }))
        }));
        return result
    },
    _checkDropTargetActive: function(target) {
        let active = false;
        iteratorUtils.each(this._dropTargets, (function(_, activeTarget) {
            active = active || activeTarget === target || (0, _dom.contains)(activeTarget, target);
            return !active
        }));
        return active
    },
    _checkDropTarget: function(config, $target, $prevTarget, e) {
        const isDraggingElement = $target.get(0) === (0, _renderer.default)(e.target).get(0);
        if (isDraggingElement) {
            return false
        }
        const targetPosition = getItemPosition(config, $target);
        if (e.pageX < targetPosition.left) {
            return false
        }
        if (e.pageY < targetPosition.top) {
            return false
        }
        const targetSize = getItemSize(config, $target);
        if (e.pageX > targetPosition.left + targetSize.width) {
            return false
        }
        if (e.pageY > targetPosition.top + targetSize.height) {
            return false
        }
        if ($prevTarget.length && $prevTarget.closest($target).length) {
            return false
        }
        if (config.checkDropTarget && !config.checkDropTarget($target, e)) {
            return false
        }
        return $target
    },
    _end: function(e) {
        const eventData = (0, _index.eventData)(e);
        this._fireEvent("dxdragend", e, {
            offset: this._calculateOffset(eventData)
        });
        this._fireDropTargetEvent(e, DROP_EVENT);
        delete this._currentDropTarget
    }
});
(0, _emitter_registrator.default)({
    emitter: DragEmitter,
    events: ["dxdragstart", "dxdrag", "dxdragend"]
});
