package ru.dbotthepony.mc.otm.core.multiblock

import it.unimi.dsi.fastutil.objects.Reference2IntOpenHashMap
import net.minecraft.world.level.block.entity.BlockEntity
import java.util.Collections

class BlockEntitySet<T : Any>(private val listener: GlobalBlockEntityRemovalListener, val tag: BlockEntityTag<T>) {
	private val items = Reference2IntOpenHashMap<T>()
	val set: Set<T> = Collections.unmodifiableSet(items.keys)

	fun add(blockEntity: BlockEntity) {
		if (tag.test(blockEntity)) {
			val new = items.getInt(blockEntity) + 1

			if (new == 1)
				GlobalBlockEntityRemovalListener.listen(blockEntity, listener)

			items.put(blockEntity as T, new)
		}
	}

	fun remove(blockEntity: BlockEntity) {
		if (tag.test(blockEntity)) {
			val existing = items.getInt(blockEntity)

			if (existing == 1) {
				GlobalBlockEntityRemovalListener.stopListening(blockEntity, listener)
				items.removeInt(blockEntity)
			} else if (existing > 1) {
				items.put(blockEntity as T, existing - 1)
			}
		}
	}

	fun blockEntityRemoved(blockEntity: BlockEntity): Boolean {
		return items.removeInt(blockEntity as T) != 0
	}

	fun clear() {
		items.keys.forEach {
			GlobalBlockEntityRemovalListener.stopListening(it as BlockEntity, listener)
		}

		items.clear()
	}
}
