package ru.dbotthepony.mc.otm.capability.fluid

import net.minecraft.nbt.CompoundTag
import net.minecraft.world.item.BlockItem
import net.minecraft.world.item.ItemStack
import net.minecraftforge.common.util.INBTSerializable
import net.minecraftforge.fluids.FluidStack
import ru.dbotthepony.mc.otm.core.nbt.set
import ru.dbotthepony.mc.otm.core.tagNotNull
import java.util.function.IntSupplier

/**
 * Fluid handler for blocks
 */
class BlockMatteryFluidHandler(val onChanged: (new: FluidStack, old: FluidStack) -> Unit, private val _capacity: IntSupplier) : AbstractMatteryFluidHandler(), INBTSerializable<CompoundTag?> {
	override var fluid: FluidStack = FluidStack.EMPTY
		set(value) {
			val old = field
			field = value
			onChanged(value, old)
		}

	override val capacity: Int
		get() = _capacity.asInt

	override fun serializeNBT(): CompoundTag {
		return fluid.writeToNBT(CompoundTag())
	}

	override fun deserializeNBT(nbt: CompoundTag?) {
		fluid = FluidStack.loadFluidStackFromNBT(nbt)
	}

	/**
	 * Fluid handler for items representing block with [BlockMatteryFluidHandler]
	 */
	open class Item(itemStack: ItemStack, capacity: IntSupplier, private val nbtName: String) : ItemMatteryFluidHandler(itemStack, capacity) {
		override var fluid: FluidStack
			get() {
				val sub = itemStack.tag?.get(BlockItem.BLOCK_ENTITY_TAG) as? CompoundTag ?: return FluidStack.EMPTY
				return FluidStack.loadFluidStackFromNBT(sub[nbtName] as? CompoundTag ?: return FluidStack.EMPTY)
			}
			set(value) {
				var sub = itemStack.tagNotNull.get(BlockItem.BLOCK_ENTITY_TAG) as? CompoundTag

				if (sub == null) {
					sub = CompoundTag()
					itemStack.tagNotNull[BlockItem.BLOCK_ENTITY_TAG] = sub
				}

				sub[nbtName] = value.writeToNBT(CompoundTag())
			}
	}
}
