import { ref, watch, computed } from "vue";
import { usePointer } from "../pointer/index.mjs";
import { propsFactory, getCurrentInstance, isComponentInstance, SUPPORTS_TOUCH, convertToUnit, querySelector } from "../../utils/dist/index.mjs";
const makeDraggableProps = propsFactory({
  draggable: {
    type: Boolean,
    default: true
  },
  containment: [String, Object],
  disabled: Boolean,
  cursor: {
    type: Boolean,
    default: true
  },
  position: String
}, "draggable");
function useDraggable(props = {
  draggable: true,
  disabled: false,
  cursor: true
}, data) {
  const previous = ref();
  const previousBox = ref();
  const containmentBox = ref();
  const draggableEl = ref();
  const draggableRef = ref();
  const {
    isPointerMoving: isDragging,
    pointerDownEl,
    pointerMovement: draggableMovement,
    pointerEvents
  } = usePointer({
    pointerMovePreventDefault: true
  });
  const vm = getCurrentInstance("useDraggable");
  const updateContainmentBox = () => {
    var _a;
    containmentBox.value = props.containment ? (_a = querySelector(props.containment, vm)) == null ? void 0 : _a.getBoundingClientRect() : void 0;
  };
  watch(isDragging, (val) => {
    var _a;
    if (!val || !props.draggable || props.disabled)
      return;
    previous.value = {
      left: (data == null ? void 0 : data.value.left) || 0,
      top: (data == null ? void 0 : data.value.top) || 0
    };
    previousBox.value = (_a = draggableEl.value) == null ? void 0 : _a.getBoundingClientRect();
    updateContainmentBox();
  }, {
    immediate: true
  });
  watch(draggableMovement, (val) => {
    if (!props.draggable || !isDragging.value || !val || !data || !previous.value || props.disabled)
      return;
    const movement = {
      top: val.top,
      left: val.left
    };
    if (containmentBox.value && previousBox.value) {
      const minLeft = containmentBox.value.left - previousBox.value.left;
      const maxLeft = minLeft + containmentBox.value.width - previousBox.value.width;
      const minTop = containmentBox.value.top - previousBox.value.top;
      const maxTop = minTop + containmentBox.value.height - previousBox.value.height;
      movement.left = Math.min(Math.max(movement.left, minLeft), maxLeft);
      movement.top = Math.min(Math.max(movement.top, minTop), maxTop);
    }
    data.value = {
      top: previous.value.top + movement.top,
      left: previous.value.left + movement.left
    };
  });
  watch(pointerDownEl, (el) => {
    if (el && !draggableEl.value)
      draggableEl.value = el;
  });
  watch(draggableRef, (val) => {
    if (val)
      draggableEl.value = isComponentInstance(val) ? val.$el : val;
  });
  const availableEvents = {
    dragstart: (e) => e.preventDefault(),
    contextmenu: (e) => e.preventDefault()
  };
  const draggableEvents = computed(() => {
    const events = {};
    if (props.draggable) {
      events.dragstart = availableEvents.dragstart;
      if (SUPPORTS_TOUCH) {
        events.contextmenu = availableEvents.contextmenu;
      }
      Object.assign(events, pointerEvents.value);
    }
    return events;
  });
  const draggableStyles = computed(() => {
    if (props.draggable && !props.disabled && props.cursor) {
      return {
        cursor: "move"
      };
    }
    return null;
  });
  const contentStyles = computed(() => {
    if (props.draggable && data) {
      const sharedProps = {
        userSelect: isDragging.value ? "none" : void 0
      };
      if (props.position) {
        return {
          ...sharedProps,
          position: props.position,
          top: convertToUnit(data.value.top),
          left: convertToUnit(data.value.left)
        };
      }
      return {
        ...sharedProps,
        transform: `translate3d(${convertToUnit(data.value.left)}, ${convertToUnit(data.value.top)}, 0)`
      };
    }
    return null;
  });
  return {
    isDragging,
    draggableEl,
    draggableRef,
    draggableEvents,
    draggableMovement,
    draggableStyles,
    contentStyles
  };
}
export {
  makeDraggableProps,
  useDraggable
};
//# sourceMappingURL=index.mjs.map
