package ru.dbotthepony.mc.otm.container

import net.minecraft.nbt.CompoundTag
import net.minecraft.nbt.Tag
import net.minecraft.world.Container
import net.minecraft.world.entity.player.Player
import net.minecraft.world.entity.player.StackedContents
import net.minecraft.world.inventory.AbstractContainerMenu
import net.minecraft.world.inventory.CraftingContainer
import net.minecraft.world.item.Item
import net.minecraft.world.item.ItemStack
import net.minecraftforge.common.util.INBTSerializable
import java.util.function.Predicate

object DummyMenu : AbstractContainerMenu(null, 0) {
	override fun quickMoveStack(pPlayer: Player, pIndex: Int): ItemStack {
		return ItemStack.EMPTY
	}

	override fun stillValid(pPlayer: Player): Boolean {
		return false
	}
}

// урод
open class MatteryCraftingContainer private constructor(private val listener: MatteryContainer.ContainerListener, width: Int, height: Int, private val parent: MatteryContainer) : CraftingContainer(DummyMenu, width, height), IMatteryContainer by parent, INBTSerializable<CompoundTag?> {
	constructor(width: Int, height: Int) : this(MatteryContainer.EmptyListener, width, height)
	constructor(listener: () -> Unit, width: Int, height: Int) : this({ _, _, _ -> listener.invoke() }, width, height, MatteryContainer(width * height))
	constructor(listener: MatteryContainer.ContainerListener, width: Int, height: Int) : this(listener, width, height, MatteryContainer(width * height))

	init {
		parent.listener = MatteryContainer.ContainerListener { slot, new, old -> this@MatteryCraftingContainer.setChanged(slot, new, old) }
	}

	protected open fun setChanged(slot: Int, new: ItemStack, old: ItemStack) {
		listener.setChanged(slot, new, old)
	}

	override fun serializeNBT(): CompoundTag {
		return parent.serializeNBT()
	}

	override fun deserializeNBT(nbt: CompoundTag?) {
		parent.deserializeNBT(nbt)
	}

	override fun clearContent() {
		parent.clearContent()
	}

	override fun getContainerSize(): Int {
		return parent.getContainerSize()
	}

	override fun isEmpty(): Boolean {
		return parent.isEmpty()
	}

	override fun getItem(p_39332_: Int): ItemStack {
		return parent.getItem(p_39332_)
	}

	override fun removeItem(p_39334_: Int, p_39335_: Int): ItemStack {
		return parent.removeItem(p_39334_, p_39335_)
	}

	override fun removeItemNoUpdate(p_39344_: Int): ItemStack {
		return parent.removeItemNoUpdate(p_39344_)
	}

	override fun setItem(p_39337_: Int, p_39338_: ItemStack) {
		parent.setItem(p_39337_, p_39338_)
	}

	override fun setChanged() {
		parent.setChanged()
	}

	override fun stillValid(p_39340_: Player): Boolean {
		return parent.stillValid(p_39340_)
	}

	override fun fillStackedContents(p_39342_: StackedContents) {
		parent.fillStackedContents(p_39342_)
	}

	override fun getMaxStackSize(): Int {
		return parent.getMaxStackSize()
	}

	override fun startOpen(p_18955_: Player) {
		parent.startOpen(p_18955_)
	}

	override fun stopOpen(p_18954_: Player) {
		parent.stopOpen(p_18954_)
	}

	override fun canPlaceItem(p_18952_: Int, p_18953_: ItemStack): Boolean {
		return parent.canPlaceItem(p_18952_, p_18953_)
	}

	override fun countItem(p_18948_: Item): Int {
		return parent.countItem(p_18948_)
	}

	override fun hasAnyOf(p_18950_: Set<Item>): Boolean {
		return parent.hasAnyOf(p_18950_)
	}

	override fun hasAnyMatching(p_216875_: Predicate<ItemStack>): Boolean {
		return parent.hasAnyMatching(p_216875_)
	}
}
