"use strict";
Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
const vue = require("vue");
const gridItem_vue = require("./grid-item.vue.js");
const index = require("../../../@vexip-ui/hooks/dist/index.js");
const index$1 = require("../../../@vexip-ui/utils/dist/index.js");
const common = require("../helpers/common.js");
const responsive = require("../helpers/responsive.js");
const De = /* @__PURE__ */ vue.defineComponent({
  __name: "grid-layout",
  props: {
    autoSize: { type: Boolean, default: true },
    colNum: { default: 12 },
    rowHeight: { default: 150 },
    maxRows: { default: 1 / 0 },
    margin: { default: () => [10, 10] },
    isDraggable: { type: Boolean, default: true },
    isResizable: { type: Boolean, default: true },
    isMirrored: { type: Boolean, default: false },
    isBounded: { type: Boolean, default: false },
    useCssTransforms: { type: Boolean, default: true },
    verticalCompact: { type: Boolean, default: true },
    restoreOnDrag: { type: Boolean, default: false },
    layout: {},
    responsive: { type: Boolean, default: false },
    responsiveLayouts: { default: () => ({}) },
    transformScale: { default: 1 },
    breakpoints: { default: () => ({ lg: 1200, md: 996, sm: 768, xs: 480, xxs: 0 }) },
    cols: { default: () => ({ lg: 12, md: 10, sm: 6, xs: 4, xxs: 2 }) },
    preventCollision: { type: Boolean, default: false },
    useStyleCursor: { type: Boolean, default: true }
  },
  emits: [
    "layout-before-mount",
    "layout-mounted",
    "layout-updated",
    "breakpoint-changed",
    "update:layout",
    "layout-ready"
  ],
  setup(Y, { expose: N, emit: $ }) {
    const a = Y, u = $, t = vue.reactive({
      width: -1,
      mergedStyle: {},
      lastLayoutLength: 0,
      isDragging: false,
      placeholder: {
        x: 0,
        y: 0,
        w: 0,
        h: 0,
        i: ""
      },
      layouts: {},
      // array to store all layouts from different breakpoints
      lastBreakpoint: null,
      // store last active breakpoint
      originalLayout: null
      // store original Layout
    }), k = /* @__PURE__ */ new Map(), o = vue.ref(a.layout), g = vue.ref(), { observeResize: A, unobserveResize: U } = index.useResize(), r = index$1.createEventEmitter();
    r.on("resizeEvent", q), r.on("dragEvent", G), vue.onBeforeMount(() => {
      u("layout-before-mount", o.value);
    }), vue.onMounted(() => {
      u("layout-mounted", o.value), vue.nextTick(() => {
        common.validateLayout(o.value), t.originalLayout = o.value, vue.nextTick(() => {
          D(), g.value && A(g.value, index$1.debounce(C, 16)), common.compact(o.value, a.verticalCompact), u("layout-updated", o.value), y(), C();
        });
      });
    }), vue.onBeforeUnmount(() => {
      r.clearAll(), g.value && U(g.value);
    });
    function q(e, n, l, f, d, c) {
      S(e, n, l, f, d, c);
    }
    function G(e, n, l, f, d, c) {
      E(e, n, l, f, d, c);
    }
    vue.watch(
      () => t.width,
      (e, n) => {
        vue.nextTick(() => {
          r.emit("updateWidth", e), n === -1 && vue.nextTick(() => {
            u("layout-ready", o.value);
          }), y();
        });
      }
    ), vue.watch(
      () => [a.layout, a.layout.length],
      () => {
        o.value = a.layout, R();
      }
    ), vue.watch(
      () => a.colNum,
      (e) => {
        r.emit("setColNum", e);
      }
    ), vue.watch(
      () => a.rowHeight,
      (e) => {
        r.emit("setRowHeight", e);
      }
    ), vue.watch(
      () => a.isDraggable,
      (e) => {
        r.emit("setDraggable", e);
      }
    ), vue.watch(
      () => a.isResizable,
      (e) => {
        r.emit("setResizable", e);
      }
    ), vue.watch(
      () => a.isBounded,
      (e) => {
        r.emit("setBounded", e);
      }
    ), vue.watch(
      () => a.transformScale,
      (e) => {
        r.emit("setTransformScale", e);
      }
    ), vue.watch(
      () => a.responsive,
      (e) => {
        e || (u("update:layout", t.originalLayout), r.emit("setColNum", a.colNum)), C();
      }
    ), vue.watch(
      () => a.maxRows,
      (e) => {
        r.emit("setMaxRows", e);
      }
    ), vue.watch([() => a.margin, () => a.margin[1]], y), vue.provide(
      common.LAYOUT_KEY,
      vue.reactive({
        ...vue.toRefs(a),
        ...vue.toRefs(t),
        increaseItem: K,
        decreaseItem: j
      })
    ), vue.provide(common.EMITTER_KEY, r), N({ state: t, getItem: P, resizeEvent: S, dragEvent: E, layoutUpdate: R });
    function K(e) {
      k.set(e.i, e);
    }
    function j(e) {
      k.delete(e.i);
    }
    function P(e) {
      return k.get(e);
    }
    function R() {
      if (!index$1.isNull(o.value) && !index$1.isNull(t.originalLayout)) {
        if (o.value.length !== t.originalLayout.length) {
          const e = J(o.value, t.originalLayout);
          if (e.length > 0)
            if (o.value.length > t.originalLayout.length)
              t.originalLayout = t.originalLayout.concat(e);
            else {
              const n = new Set(e.map((l) => l.i));
              t.originalLayout = t.originalLayout.filter((l) => !n.has(l.i));
            }
          t.lastLayoutLength = o.value.length, D();
        }
        common.compact(o.value, a.verticalCompact), r.emit("updateWidth", t.width), y(), u("layout-updated", o.value);
      }
    }
    function y() {
      t.mergedStyle = {
        height: V()
      };
    }
    function C() {
      g.value && (t.width = g.value.offsetWidth), r.emit("resizeEvent");
    }
    function V() {
      if (!a.autoSize) return;
      const e = parseFloat(a.margin[1]);
      return common.bottom(o.value) * (a.rowHeight + e) + e + "px";
    }
    let b;
    function E(e, n, l, f, d, c) {
      let i = common.getLayoutItem(o.value, n);
      index$1.isNull(i) && (i = { h: 0, w: 0, x: 0, y: 0, i: "" }), e === "dragstart" && !a.verticalCompact && (b = o.value.reduce(
        (v, { i: x, x: p, y: h }) => ({
          ...v,
          [x]: { x: p, y: h }
        }),
        {}
      )), e === "dragmove" || e === "dragstart" ? (t.placeholder.i = n, t.placeholder.x = i.x, t.placeholder.y = i.y, t.placeholder.w = c, t.placeholder.h = d, vue.nextTick(() => {
        t.isDragging = true;
      }), r.emit("updateWidth", t.width)) : vue.nextTick(() => {
        t.isDragging = false;
      }), o.value = common.moveElement(o.value, i, l, f, true, a.preventCollision), a.restoreOnDrag ? (i.static = true, common.compact(o.value, a.verticalCompact, b), i.static = false) : common.compact(o.value, a.verticalCompact), r.emit("compact"), y(), e === "dragend" && (b = void 0, u("layout-updated", o.value));
    }
    function S(e, n, l, f, d, c) {
      let i = common.getLayoutItem(o.value, n);
      index$1.isNull(i) && (i = { h: 0, w: 0, x: 0, y: 0, i: "" });
      let v;
      if (a.preventCollision) {
        const x = common.getAllCollisions(o.value, { ...i, w: c, h: d }).filter(
          (p) => p.i !== i.i
        );
        if (v = x.length > 0, v) {
          let p = 1 / 0, h = 1 / 0;
          x.forEach((L) => {
            L.x > i.x && (p = Math.min(p, L.x)), L.y > i.y && (h = Math.min(h, L.y));
          }), Number.isFinite(p) && (i.w = p - i.x), Number.isFinite(h) && (i.h = h - i.y);
        }
      }
      v || (i.w = c, i.h = d), e === "resizestart" || e === "resizemove" ? (t.placeholder.i = n, t.placeholder.x = l, t.placeholder.y = f, t.placeholder.w = i.w, t.placeholder.h = i.h, vue.nextTick(() => {
        t.isDragging = true;
      }), r.emit("updateWidth", t.width)) : e && vue.nextTick(() => {
        t.isDragging = false;
      }), a.responsive && X(), common.compact(o.value, a.verticalCompact), r.emit("compact"), y(), e === "resizeend" && u("layout-updated", o.value);
    }
    function X() {
      const e = responsive.getBreakpointFromWidth(a.breakpoints, t.width);
      if (e === t.lastBreakpoint)
        return;
      const n = responsive.getColsFromBreakpoint(e, a.cols);
      !index$1.isNull(t.lastBreakpoint) && !t.layouts[t.lastBreakpoint] && (t.layouts[t.lastBreakpoint] = common.cloneLayout(o.value));
      const l = responsive.findOrGenerateResponsiveLayout(
        t.originalLayout,
        t.layouts,
        a.breakpoints,
        e,
        t.lastBreakpoint,
        n,
        a.verticalCompact
      );
      t.layouts[e] = l, t.lastBreakpoint !== e && u("breakpoint-changed", e, l), o.value = l, u("update:layout", l), t.lastBreakpoint = e, r.emit("setColNum", n);
    }
    function D() {
      t.layouts = Object.assign({}, a.responsiveLayouts);
    }
    function J(e, n) {
      const l = new Set(n.map((i) => i.i)), f = new Set(e.map((i) => i.i)), d = e.filter((i) => !l.has(i.i)), c = n.filter((i) => !f.has(i.i));
      return d.concat(c);
    }
    return (e, n) => (vue.openBlock(), vue.createElementBlock("div", {
      ref_key: "wrapper",
      ref: g,
      class: "vgl-layout",
      style: vue.normalizeStyle(t.mergedStyle)
    }, [
      e.$slots.default ? vue.renderSlot(e.$slots, "default", { key: 0 }) : (vue.openBlock(true), vue.createElementBlock(vue.Fragment, { key: 1 }, vue.renderList(o.value, (l) => (vue.openBlock(), vue.createBlock(gridItem_vue.default, vue.mergeProps({
        key: l.i,
        ref_for: true
      }, l), {
        default: vue.withCtx(() => [
          vue.renderSlot(e.$slots, "item", { item: l })
        ]),
        _: 2
      }, 1040))), 128)),
      vue.withDirectives(vue.createVNode(gridItem_vue.default, {
        class: "vgl-item--placeholder",
        x: t.placeholder.x,
        y: t.placeholder.y,
        w: t.placeholder.w,
        h: t.placeholder.h,
        i: t.placeholder.i
      }, null, 8, ["x", "y", "w", "h", "i"]), [
        [vue.vShow, t.isDragging]
      ])
    ], 4));
  }
});
exports.default = De;
