package ru.dbotthepony.mc.otm.client.screen.panels.slot

import com.mojang.blaze3d.systems.RenderSystem
import net.minecraft.client.gui.GuiGraphics
import net.minecraft.client.gui.screens.Screen.getTooltipFromItem
import net.minecraft.client.renderer.GameRenderer
import net.minecraft.network.chat.Component
import net.minecraft.world.item.ItemStack
import net.minecraftforge.client.extensions.common.IClientItemExtensions
import ru.dbotthepony.mc.otm.client.render.*
import ru.dbotthepony.mc.otm.client.screen.MatteryScreen
import ru.dbotthepony.mc.otm.client.screen.panels.EditablePanel
import ru.dbotthepony.mc.otm.client.screen.panels.IItemStackPanel
import ru.dbotthepony.mc.otm.core.math.RGBAColor

abstract class AbstractSlotPanel<out S : MatteryScreen<*>> @JvmOverloads constructor(
	screen: S,
	parent: EditablePanel<*>?,
	x: Float = 0f,
	y: Float = 0f,
	width: Float = SIZE,
	height: Float = SIZE,
) : EditablePanel<S>(screen, parent, x, y, width, height), IItemStackPanel {
	open var slotBackground: IGUIRenderable? = null
	open var slotBackgroundEmpty: IGUIRenderable? = null

	protected open fun renderSlotBackground(graphics: GuiGraphics, mouseX: Float, mouseY: Float, partialTick: Float) {
		SLOT_BACKGROUND.render(graphics, width = width, height = height)
		slotBackground?.render(graphics, 0f, 0f, width, height)
	}

	protected open fun renderRegular(graphics: GuiGraphics, itemstack: ItemStack, countOverride: String? = null) {
		RenderSystem.setShader(GameRenderer::getPositionTexShader)

		if (!itemstack.isEmpty) {
			screen.renderItemStack(graphics, itemstack, countOverride)
			clearDepth(graphics)
		}

		if (isHovered) {
			graphics.renderRect(1f, 1f, width - 1, height - 1, color = SLOT_HIGHLIGHT)
		}
	}

	protected open fun getItemStackTooltip(stack: ItemStack): List<Component> {
		return getTooltipFromItem(ru.dbotthepony.mc.otm.client.minecraft, stack)
	}

	override fun innerRender(graphics: GuiGraphics, mouseX: Float, mouseY: Float, partialTick: Float) {
		renderSlotBackground(graphics, mouseX, mouseY, partialTick)
		val itemStack = itemStack
		renderRegular(graphics, itemStack)

		if (itemStack.isEmpty) {
			slotBackgroundEmpty?.render(graphics, 0f, 0f, width, height)
		}
	}

	override fun innerRenderTooltips(graphics: GuiGraphics, mouseX: Float, mouseY: Float, partialTick: Float): Boolean {
		if (isHovered) {
			val itemstack = itemStack

			if (!itemstack.isEmpty) {
				val font = IClientItemExtensions.of(itemstack).getFont(itemstack, IClientItemExtensions.FontContext.TOOLTIP)

				graphics.renderComponentTooltip(
					font ?: screen.font,
					getItemStackTooltip(itemstack),
					mouseX.toInt(),
					mouseY.toInt(),
					itemstack
				)

				return true
			}
		}
		return false
	}

	companion object {
		val SLOT_HIGHLIGHT = RGBAColor(255, 255, 255, 100)
		val SLOT_HIGHLIGHT_DRAG = RGBAColor(200, 200, 200, 150)
		const val SIZE = 18f
		val SLOT_BACKGROUND = WidgetLocation.MISC.sprite(0f, 0f, SIZE, SIZE)
		val FILTERED_SLOT_BACKGROUND = WidgetLocation.MISC.sprite(46f, 0f, SIZE, SIZE)
	}
}
