// Utilities
import { computed, inject, onBeforeUnmount, provide, ref } from 'vue';
import { convertToUnit, getUid, propsFactory } from "../util/index.mjs"; // Types

export const VuetifyLayoutKey = Symbol.for('vuetify:layout');
export const makeLayoutProps = propsFactory({
  overlaps: {
    type: Array,
    default: () => []
  },
  fullHeight: Boolean
}, 'layout'); // Composables

export const makeLayoutItemProps = propsFactory({
  name: {
    type: String
  },
  priority: {
    type: Number,
    default: 0
  },
  size: {
    type: [Number, String],
    default: 300
  }
}, 'layout-item');
export function useMain() {
  const layout = inject(VuetifyLayoutKey);
  if (!layout) throw new Error('Could not find injected Vuetify layout');
  return layout;
}
export function useLayoutItem(name, priority, position, amount) {
  const layout = inject(VuetifyLayoutKey);
  if (!layout) throw new Error('Could not find injected Vuetify layout');
  const id = name != null ? name : "layout-item-".concat(getUid());
  const styles = layout.register(id, priority, position, amount);
  onBeforeUnmount(() => layout.unregister(id));
  return styles;
}

const generateLayers = (layout, registered, positions, amounts) => {
  let previousLayer = {
    top: 0,
    left: 0,
    right: 0,
    bottom: 0
  };
  const layers = [{
    id: '',
    layer: { ...previousLayer
    }
  }];
  const ids = !layout.length ? registered : layout.map(l => l.split(':')[0]).filter(l => registered.includes(l));

  for (const id of ids) {
    const position = positions.get(id);
    const amount = amounts.get(id);
    if (!position || !amount) continue;
    const layer = { ...previousLayer,
      [position.value]: parseInt(previousLayer[position.value], 10) + parseInt(amount.value, 10)
    };
    layers.push({
      id,
      layer
    });
    previousLayer = layer;
  }

  return layers;
}; // TODO: Remove undefined from layout and overlaps when vue typing for required: true prop is fixed


export function createLayout(props) {
  const registered = ref([]);
  const positions = new Map();
  const amounts = new Map();
  const priorities = new Map();
  const computedOverlaps = computed(() => {
    var _props$overlaps;

    const map = new Map();
    const overlaps = (_props$overlaps = props.overlaps) != null ? _props$overlaps : [];

    for (const overlap of overlaps.filter(item => item.includes(':'))) {
      const [top, bottom] = overlap.split(':');
      if (!registered.value.includes(top) || !registered.value.includes(bottom)) continue;
      const topPosition = positions.get(top);
      const bottomPosition = positions.get(bottom);
      const topAmount = amounts.get(top);
      const bottomAmount = amounts.get(bottom);
      if (!topPosition || !bottomPosition || !topAmount || !bottomAmount) continue;
      map.set(bottom, {
        position: topPosition.value,
        amount: parseInt(topAmount.value, 10)
      });
      map.set(top, {
        position: bottomPosition.value,
        amount: -parseInt(bottomAmount.value, 10)
      });
    }

    return map;
  });
  const layers = computed(() => {
    const entries = [...priorities.entries()];
    const sortedEntries = entries.sort(([, a], [, b]) => a.value - b.value).map(([id]) => id);
    return generateLayers(sortedEntries, registered.value, positions, amounts);
  });
  const mainStyles = computed(() => {
    const layer = layers.value[layers.value.length - 1].layer;
    return {
      position: 'absolute',
      left: convertToUnit(layer.left),
      right: convertToUnit(layer.right),
      top: convertToUnit(layer.top),
      bottom: convertToUnit(layer.bottom)
    };
  });
  const items = computed(() => {
    return layers.value.slice(1).map(({
      id
    }, index) => {
      const {
        layer
      } = layers.value[index];
      const size = amounts.get(id);
      return {
        id,
        ...layer,
        size: Number(size.value)
      };
    });
  });

  const getLayoutItem = id => {
    return items.value.find(item => item.id === id);
  };

  provide(VuetifyLayoutKey, {
    register: (id, priority, position, amount) => {
      priorities.set(id, priority);
      positions.set(id, position);
      amounts.set(id, amount);
      registered.value.push(id);
      return computed(() => {
        var _amount$value, _amount$value2;

        const index = items.value.findIndex(i => i.id === id);
        if (index < 0) throw new Error("Layout item \"".concat(id, "\" is missing from layout prop"));
        const item = items.value[index];
        if (!item) throw new Error("Could not find layout item \"".concat(id));
        const overlap = computedOverlaps.value.get(id);

        if (overlap) {
          item[overlap.position] += overlap.amount;
        }

        const isHorizontal = position.value === 'left' || position.value === 'right';
        const isOpposite = position.value === 'right';
        const amount = amounts.get(id);
        return {
          [position.value]: 0,
          height: isHorizontal ? "calc(100% - ".concat(item.top, "px - ").concat(item.bottom, "px)") : "".concat((_amount$value = amount == null ? void 0 : amount.value) != null ? _amount$value : 0, "px"),
          marginLeft: isOpposite ? undefined : "".concat(item.left, "px"),
          marginRight: isOpposite ? "".concat(item.right, "px") : undefined,
          marginTop: position.value !== 'bottom' ? "".concat(item.top, "px") : undefined,
          marginBottom: position.value !== 'top' ? "".concat(item.bottom, "px") : undefined,
          position: 'absolute',
          width: !isHorizontal ? "calc(100% - ".concat(item.left, "px - ").concat(item.right, "px)") : "".concat((_amount$value2 = amount == null ? void 0 : amount.value) != null ? _amount$value2 : 0, "px"),
          zIndex: layers.value.length - index
        };
      });
    },
    unregister: id => {
      positions.delete(id);
      amounts.delete(id);
      priorities.delete(id);
      registered.value = registered.value.filter(v => v !== id);
    },
    mainStyles,
    getLayoutItem,
    items
  });
  return {
    layoutClasses: ref('v-layout'),
    getLayoutItem,
    items
  };
}
//# sourceMappingURL=layout.mjs.map