package ru.dbotthepony.mc.otm.client

import com.mojang.blaze3d.platform.InputConstants
import com.mojang.blaze3d.systems.RenderSystem
import net.minecraft.client.KeyMapping
import net.minecraftforge.client.event.RegisterKeyMappingsEvent
import net.minecraftforge.client.event.RenderGuiEvent
import net.minecraftforge.client.event.RenderLevelStageEvent
import net.minecraftforge.client.settings.KeyConflictContext
import ru.dbotthepony.mc.otm.OverdriveThatMatters
import ru.dbotthepony.mc.otm.android.AndroidActiveFeature
import ru.dbotthepony.mc.otm.capability.matteryPlayer
import ru.dbotthepony.mc.otm.client.render.Widgets18
import ru.dbotthepony.mc.otm.client.render.renderRect
import ru.dbotthepony.mc.otm.client.render.is3DContext
import ru.dbotthepony.mc.otm.core.math.RGBAColor
import ru.dbotthepony.mc.otm.network.ActivateAndroidFeaturePacket
import ru.dbotthepony.mc.otm.network.MatteryPlayerNetworkChannel
import kotlin.math.roundToInt

object AndroidAbilityKeyMapping : KeyMapping("key.otm.android_ability", KeyConflictContext.IN_GAME, InputConstants.Type.KEYSYM.getOrCreate(InputConstants.KEY_V), OverdriveThatMatters.MOD_ID) {
	private var feature: AndroidActiveFeature? = null

	override fun setDown(isDown: Boolean) {
		val old = this.isDown
		super.setDown(isDown)

		if (old != isDown && minecraft.player?.isSpectator == false) {
			if (isDown) {
				val capability = minecraft.player?.matteryPlayer ?: return

				if (capability.isAndroid) {
					feature = capability.features.map { it as? AndroidActiveFeature }.filter { it != null && it.isActive }.findFirst().orElse(null)
				} else {
					feature = null
				}
			} else {
				val feature = feature

				if (feature != null && feature.activate(true) && minecraft.player != null && feature.android.isAndroid) {
					MatteryPlayerNetworkChannel.sendToServer(ActivateAndroidFeaturePacket(feature.type))
				}

				this.feature = null
			}
		}
	}

	fun onRenderGuiEvent(event: RenderGuiEvent.Post) {
		if (!isDown) {
			return
		}

		val feature = feature ?: return

		val iconSize = 18f

		val x = minecraft.window.guiScaledWidth.toFloat() * .5f + iconSize / 2f
		val y = minecraft.window.guiScaledHeight.toFloat() * .5f - iconSize / 2f

		feature.renderIcon(event.guiGraphics, x, y, iconSize, iconSize)

		if (feature.isOnCooldown) {
			val cooldownPct = feature.cooldownPercent

			if (cooldownPct > 0.0f) {
				val nodrawpixels = (iconSize * (1 - cooldownPct)).roundToInt().toFloat()
				event.guiGraphics.renderRect(x, y + nodrawpixels, iconSize, iconSize - nodrawpixels, color = RGBAColor.HALF_TRANSPARENT)
			}

			Widgets18.COOLDOWN.render(event.guiGraphics, x, y + iconSize, iconSize, iconSize)
		}
	}

	fun onRenderLevel(event: RenderLevelStageEvent) {
		if (!isDown) {
			return
		}

		val feature = feature ?: return

		if (event.stage === feature.previewRenderStage) {
			try {
				is3DContext = true
				event.poseStack.pushPose()
				feature.renderPreview(event.poseStack, event.camera)
			} finally {
				is3DContext = false
				event.poseStack.popPose()
			}
		}
	}

	fun register(event: RegisterKeyMappingsEvent) {
		event.register(this)
	}
}
