package ru.dbotthepony.mc.otm.container

import net.minecraft.world.Container
import net.minecraft.world.entity.player.Player
import net.minecraft.world.item.Item
import net.minecraft.world.item.ItemStack
import java.util.function.Predicate

// passthrough all default methods to fix Kotlin bug related to implementation delegation not properly working on Java interfaces
// and also to give params proper names
// https://youtrack.jetbrains.com/issue/KT-55080/Change-the-behavior-of-inheritance-delegation-to-delegates-implementing-Java-interfaces-with-default-methods
interface IContainer : Container {
	override fun getMaxStackSize(): Int {
		return super.getMaxStackSize()
	}

	override fun startOpen(player: Player) {
		super.startOpen(player)
	}

	override fun stopOpen(player: Player) {
		super.stopOpen(player)
	}

	override fun canPlaceItem(slot: Int, itemStack: ItemStack): Boolean {
		return super.canPlaceItem(slot, itemStack)
	}

	override fun canTakeItem(container: Container, slot: Int, itemStack: ItemStack): Boolean {
		return super.canTakeItem(container, slot, itemStack)
	}

	override fun countItem(item: Item): Int {
		return super.countItem(item)
	}

	override fun hasAnyOf(items: Set<Item>): Boolean {
		return super.hasAnyOf(items)
	}

	override fun hasAnyMatching(predicate: Predicate<ItemStack>): Boolean {
		return super.hasAnyMatching(predicate)
	}

	override fun clearContent()
	override fun getContainerSize(): Int
	override fun isEmpty(): Boolean
	override fun getItem(slot: Int): ItemStack
	override fun removeItem(slot: Int, amount: Int): ItemStack
	override fun removeItemNoUpdate(slot: Int): ItemStack
	override fun setItem(slot: Int, itemStack: ItemStack)
	override fun setChanged()

	override fun stillValid(player: Player): Boolean
	companion object {
		fun wrap(container: Container): IContainer {
			if (container is IContainer)
				return container
			else
				return object : IContainer, Container by container {
					override fun getMaxStackSize(): Int {
						return container.getMaxStackSize()
					}

					override fun startOpen(player: Player) {
						container.startOpen(player)
					}

					override fun stopOpen(player: Player) {
						container.stopOpen(player)
					}

					override fun canPlaceItem(slot: Int, itemStack: ItemStack): Boolean {
						return container.canPlaceItem(slot, itemStack)
					}

					override fun canTakeItem(container: Container, slot: Int, itemStack: ItemStack): Boolean {
						return container.canTakeItem(container, slot, itemStack)
					}

					override fun countItem(item: Item): Int {
						return container.countItem(item)
					}

					override fun hasAnyOf(items: Set<Item>): Boolean {
						return container.hasAnyOf(items)
					}

					override fun hasAnyMatching(predicate: Predicate<ItemStack>): Boolean {
						return container.hasAnyMatching(predicate)
					}
				}
		}
	}
}
