Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: 'Module' } });
const require_error = require('../../../../utils/error.js');
const require_defaults = require('../defaults.js');
const require_utils = require('../utils.js');
const require_build_list = require('../builders/build-list.js');

//#region ../../packages/components/virtual-list/src/components/dynamic-size-list.ts
const SCOPE = "ElDynamicSizeList";
const getItemFromCache = (props, index, listCache) => {
	const { itemSize } = props;
	const { items, lastVisitedIndex } = listCache;
	if (index > lastVisitedIndex) {
		let offset = 0;
		if (lastVisitedIndex >= 0) {
			const item = items[lastVisitedIndex];
			offset = item.offset + item.size;
		}
		for (let i = lastVisitedIndex + 1; i <= index; i++) {
			const size = itemSize(i);
			items[i] = {
				offset,
				size
			};
			offset += size;
		}
		listCache.lastVisitedIndex = index;
	}
	return items[index];
};
const findItem = (props, listCache, offset) => {
	const { items, lastVisitedIndex } = listCache;
	if ((lastVisitedIndex > 0 ? items[lastVisitedIndex].offset : 0) >= offset) return bs(props, listCache, 0, lastVisitedIndex, offset);
	return es(props, listCache, Math.max(0, lastVisitedIndex), offset);
};
const bs = (props, listCache, low, high, offset) => {
	while (low <= high) {
		const mid = low + Math.floor((high - low) / 2);
		const currentOffset = getItemFromCache(props, mid, listCache).offset;
		if (currentOffset === offset) return mid;
		else if (currentOffset < offset) low = mid + 1;
		else if (currentOffset > offset) high = mid - 1;
	}
	return Math.max(0, low - 1);
};
const es = (props, listCache, index, offset) => {
	const { total } = props;
	let exponent = 1;
	while (index < total && getItemFromCache(props, index, listCache).offset < offset) {
		index += exponent;
		exponent *= 2;
	}
	return bs(props, listCache, Math.floor(index / 2), Math.min(index, total - 1), offset);
};
const getEstimatedTotalSize = ({ total }, { items, estimatedItemSize, lastVisitedIndex }) => {
	let totalSizeOfMeasuredItems = 0;
	if (lastVisitedIndex >= total) lastVisitedIndex = total - 1;
	if (lastVisitedIndex >= 0) {
		const item = items[lastVisitedIndex];
		totalSizeOfMeasuredItems = item.offset + item.size;
	}
	const totalSizeOfUnmeasuredItems = (total - lastVisitedIndex - 1) * estimatedItemSize;
	return totalSizeOfMeasuredItems + totalSizeOfUnmeasuredItems;
};
const DynamicSizeList = require_build_list.default({
	name: "ElDynamicSizeList",
	getItemOffset: (props, index, listCache) => getItemFromCache(props, index, listCache).offset,
	getItemSize: (_, index, { items }) => items[index].size,
	getEstimatedTotalSize,
	getOffset: (props, index, alignment, scrollOffset, listCache) => {
		const { height, layout, width } = props;
		const size = require_utils.isHorizontal(layout) ? width : height;
		const item = getItemFromCache(props, index, listCache);
		const estimatedTotalSize = getEstimatedTotalSize(props, listCache);
		const maxOffset = Math.max(0, Math.min(estimatedTotalSize - size, item.offset));
		const minOffset = Math.max(0, item.offset - size + item.size);
		if (alignment === require_defaults.SMART_ALIGNMENT) if (scrollOffset >= minOffset - size && scrollOffset <= maxOffset + size) alignment = require_defaults.AUTO_ALIGNMENT;
		else alignment = require_defaults.CENTERED_ALIGNMENT;
		switch (alignment) {
			case require_defaults.START_ALIGNMENT: return maxOffset;
			case require_defaults.END_ALIGNMENT: return minOffset;
			case require_defaults.CENTERED_ALIGNMENT: return Math.round(minOffset + (maxOffset - minOffset) / 2);
			case require_defaults.AUTO_ALIGNMENT:
			default: if (scrollOffset >= minOffset && scrollOffset <= maxOffset) return scrollOffset;
			else if (scrollOffset < minOffset) return minOffset;
			else return maxOffset;
		}
	},
	getStartIndexForOffset: (props, offset, listCache) => findItem(props, listCache, offset),
	getStopIndexForStartIndex: (props, startIndex, scrollOffset, listCache) => {
		const { height, total, layout, width } = props;
		const size = require_utils.isHorizontal(layout) ? width : height;
		const item = getItemFromCache(props, startIndex, listCache);
		const maxOffset = scrollOffset + size;
		let offset = item.offset + item.size;
		let stopIndex = startIndex;
		while (stopIndex < total - 1 && offset < maxOffset) {
			stopIndex++;
			offset += getItemFromCache(props, stopIndex, listCache).size;
		}
		return stopIndex;
	},
	initCache({ estimatedItemSize = require_defaults.DEFAULT_DYNAMIC_LIST_ITEM_SIZE }, instance) {
		const cache = {
			items: {},
			estimatedItemSize,
			lastVisitedIndex: -1
		};
		cache.clearCacheAfterIndex = (index, forceUpdate = true) => {
			cache.lastVisitedIndex = Math.min(cache.lastVisitedIndex, index - 1);
			instance.exposed?.getItemStyleCache(-1);
			if (forceUpdate) instance.proxy?.$forceUpdate();
		};
		return cache;
	},
	clearCache: false,
	validateProps: ({ itemSize }) => {
		if (process.env.NODE_ENV !== "production") {
			if (typeof itemSize !== "function") require_error.throwError(SCOPE, `
          itemSize is required as function, but the given value was ${typeof itemSize}
        `);
		}
	}
});

//#endregion
exports.default = DynamicSizeList;
//# sourceMappingURL=dynamic-size-list.js.map