package ru.dbotthepony.mc.otm.client

import com.mojang.blaze3d.systems.RenderSystem
import com.mojang.datafixers.util.Either
import net.minecraft.client.gui.Font
import net.minecraft.client.gui.GuiGraphics
import net.minecraft.client.gui.screens.inventory.tooltip.ClientTooltipComponent
import net.minecraft.world.inventory.tooltip.TooltipComponent
import net.neoforged.neoforge.client.event.RegisterClientTooltipComponentFactoriesEvent
import net.neoforged.neoforge.client.event.RenderTooltipEvent
import ru.dbotthepony.mc.otm.capability.MatteryCapability
import ru.dbotthepony.mc.otm.capability.energy.IMatteryEnergyStorage
import ru.dbotthepony.mc.otm.capability.matter.IMatterStorage
import ru.dbotthepony.mc.otm.client.render.MGUIGraphics
import ru.dbotthepony.mc.otm.client.render.WidgetLocation
import ru.dbotthepony.mc.otm.core.math.Decimal
import kotlin.math.ceil

object MatteryTooltipComponents {
	fun gatherComponents(event: RenderTooltipEvent.GatherComponents) {
		val energyCap = event.itemStack.getCapability(MatteryCapability.ITEM_ENERGY)
		if (energyCap != null && energyCap.maxBatteryLevel > Decimal.ZERO) {
			event.tooltipElements.add(1, Either.right(EnergyStorageGaugeTooltip(energyCap)))
		}

		val matterCap = event.itemStack.getCapability(MatteryCapability.MATTER_ITEM)
		if (matterCap != null && matterCap.maxStoredMatter > Decimal.ZERO) {
			event.tooltipElements.add(1, Either.right(MatterStorageGaugeTooltip(matterCap)))
		}
	}

	fun registerComponents(event: RegisterClientTooltipComponentFactoriesEvent) {
		event.register(EnergyStorageGaugeTooltip::class.java) { it }
		event.register(MatterStorageGaugeTooltip::class.java) { it }
	}

	class EnergyStorageGaugeTooltip(val storage: IMatteryEnergyStorage) : ClientTooltipComponent, TooltipComponent {
		override fun getWidth(font: Font): Int = 96
		override fun getHeight(): Int = 9 + 2

		override fun renderImage(font: Font, x: Int, y: Int, graphics: GuiGraphics) {
			super.renderImage(font, x, y, graphics)

			val level = if (storage.maxBatteryLevel == Decimal.POSITIVE_INFINITY) 1f else (storage.batteryLevel / storage.maxBatteryLevel).toFloat()

			RenderSystem.enableBlend()
			RenderSystem.defaultBlendFunc()
			RenderSystem.disableDepthTest()
			RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, 1.0f)

			val guiGraphics = MGUIGraphics(graphics)

			CHARGE_BG.render(guiGraphics, x.toFloat(), y.toFloat())
			CHARGE.renderPartial(guiGraphics, x.toFloat(), y.toFloat(), width = ceil(level * 95f - 0.5f))

			RenderSystem.disableBlend()
			RenderSystem.enableDepthTest()
		}

		companion object {
			val CHARGE_BG = WidgetLocation.HORIZONTAL_GAUGES.sprite(y = 36f, height = 9f)
			val CHARGE = WidgetLocation.HORIZONTAL_GAUGES.sprite(y = 45f, height = 9f)
		}
	}

	class MatterStorageGaugeTooltip(val storage: IMatterStorage) : ClientTooltipComponent, TooltipComponent {
		override fun getWidth(font: Font): Int = 96
		override fun getHeight(): Int = 9 + 2

		override fun renderImage(font: Font, x: Int, y: Int, graphics: GuiGraphics) {
			super.renderImage(font, x, y, graphics)

			val level = if (storage.maxStoredMatter == Decimal.POSITIVE_INFINITY) 1f else (storage.storedMatter / storage.maxStoredMatter).toFloat()

			RenderSystem.enableBlend()
			RenderSystem.defaultBlendFunc()
			RenderSystem.disableDepthTest()
			RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, 1.0f)

			val guiGraphics = MGUIGraphics(graphics)

			MATTER_BG.render(guiGraphics, x.toFloat(), y.toFloat())
			MATTER.renderPartial(guiGraphics, x.toFloat(), y.toFloat(), width = ceil(level * 95f - 0.5f))

			RenderSystem.disableBlend()
			RenderSystem.enableDepthTest()
		}

		companion object {
			val MATTER_BG = WidgetLocation.HORIZONTAL_GAUGES.sprite(y = 90f, height = 9f)
			val MATTER = WidgetLocation.HORIZONTAL_GAUGES.sprite(y = 99f, height = 9f)
		}
	}
}
