package ru.dbotthepony.mc.otm.datagen.items

import net.minecraft.resources.ResourceLocation
import net.minecraft.world.item.Item
import net.minecraftforge.client.model.generators.ItemModelProvider
import net.minecraftforge.data.event.GatherDataEvent
import org.apache.logging.log4j.LogManager
import ru.dbotthepony.mc.otm.datagen.DataGen
import ru.dbotthepony.mc.otm.core.registryName
import ru.dbotthepony.mc.otm.datagen.modLocation
import java.util.LinkedList

class MatteryItemModelProvider(event: GatherDataEvent) : ItemModelProvider(event.generator.packOutput, DataGen.MOD_ID, event.existingFileHelper) {
	private val callbacks = LinkedList<() -> Unit>()

	fun exec(func: () -> Unit): MatteryItemModelProvider {
		callbacks.add(func)
		return this
	}

	override fun registerModels() {
		for (callback in callbacks) {
			callback.invoke()
		}
	}

	fun block(item: Item) = exec { withExistingParent(item.registryName!!.path, modLocation("block/${item.registryName!!.path}")) }
	fun block(item: Item, path: String) = exec { withExistingParent(item.registryName!!.path, modLocation("block/$path")) }
	fun blocks(vararg items: Item) = items.forEach(this::block)
	fun blocks(items: Collection<Item>) = items.forEach(this::block)

	fun generated(item: Item, texture: ResourceLocation) = exec {
		withExistingParent(item.registryName!!.path, GENERATED).texture("layer0", texture)
	}

	fun generatedTranslucent(item: Item, texture: ResourceLocation) = exec {
		withExistingParent(item.registryName!!.path, GENERATED).texture("layer0", texture).renderType("translucent")
	}

	fun handheld(item: Item, texture: ResourceLocation) = exec {
		withExistingParent(item.registryName!!.path, HANDHELD).texture("layer0", texture)
	}

	fun generated(item: Item) = generated(item, modLocation("item/${item.registryName!!.path}"))
	fun generated(vararg items: Item) = items.forEach { generated(it, modLocation("item/${it.registryName!!.path}")) }
	fun KOT(vararg items: Item) = items.forEach { generated(it, modLocation("block/ph_kitty")) }
	fun generated(items: Collection<Item>) = items.forEach { generated(it, modLocation("item/${it.registryName!!.path}")) }
	fun generatedBlock(vararg items: Item) = items.forEach { generated(it, modLocation("block/${it.registryName!!.path}")) }
	fun generatedBlockDecorative(vararg items: Item) = items.forEach { generated(it, modLocation("block/decorative/${it.registryName!!.path}")) }
	fun handheld(vararg items: Item) = items.forEach { handheld(it, modLocation("item/${it.registryName!!.path}")) }
	fun handheld(items: Collection<Item>) = items.forEach { handheld(it, modLocation("item/${it.registryName!!.path}")) }

	fun generated(item: Item, prefix: String) = generated(item, modLocation("item/${prefix}${item.registryName!!.path}"))
	fun generatedStrict(item: Item, path: String) = generated(item, modLocation("item/$path"))
	fun handheld(item: Item, prefix: String) = handheld(item, modLocation("item/${prefix}${item.registryName!!.path}"))

	fun component(item: Item) = generated(item, "component/")
	fun components(vararg items: Item) = items.forEach(this::component)
	fun components(items: Collection<Item>) = items.forEach(this::component)
	fun resource(item: Item) = generated(item, "resources/")
	fun resources(vararg items: Item) = items.forEach(this::resource)

	fun generatedTiered(items: Array<out Item>, prefix: String) {
		var i = 0

		for (item in items) {
			generated(item, modLocation("item/$prefix$i"))
			i++
		}
	}

	fun generatedTiered(items: Collection<Item>, prefix: String) {
		var i = 0

		for (item in items) {
			generated(item, modLocation("item/$prefix$i"))
			i++
		}
	}

	companion object {
		val GENERATED = ResourceLocation("minecraft", "item/generated")
		val HANDHELD = ResourceLocation("minecraft", "item/handheld")
		private val LOGGER = LogManager.getLogger()
	}
}
