package ru.dbotthepony.mc.otm.client.screen.storage

import net.minecraft.client.gui.GuiGraphics
import net.minecraft.network.chat.Component
import net.minecraft.world.entity.player.Inventory
import net.minecraft.world.item.ItemStack
import ru.dbotthepony.mc.otm.client.screen.MatteryScreen
import ru.dbotthepony.mc.otm.core.TranslatableComponent
import ru.dbotthepony.mc.otm.client.screen.panels.*
import ru.dbotthepony.mc.otm.client.screen.panels.button.CheckBoxLabelInputPanel
import ru.dbotthepony.mc.otm.client.screen.panels.slot.AbstractSlotPanel
import ru.dbotthepony.mc.otm.client.screen.panels.slot.BatterySlotPanel
import ru.dbotthepony.mc.otm.client.screen.panels.slot.FilterSlotPanel
import ru.dbotthepony.mc.otm.client.screen.panels.slot.SlotPanel
import ru.dbotthepony.mc.otm.client.screen.panels.util.DiscreteScrollBarPanel
import ru.dbotthepony.mc.otm.client.screen.panels.util.GridPanel
import ru.dbotthepony.mc.otm.client.screen.widget.PowerGaugePanel
import ru.dbotthepony.mc.otm.core.math.integerDivisionDown
import ru.dbotthepony.mc.otm.item.PortableCondensationDriveItem
import ru.dbotthepony.mc.otm.menu.storage.DriveViewerMenu
import yalter.mousetweaks.api.MouseTweaksDisableWheelTweak

@MouseTweaksDisableWheelTweak
class DriveViewerScreen(menu: DriveViewerMenu, inventory: Inventory, title: Component) :
	MatteryScreen<DriveViewerMenu>(menu, inventory, title) {

	override fun makeMainFrame(): FramePanel<MatteryScreen<*>> {
		val frame = FramePanel(this, null, 0f, 0f, FRAME_WIDTH, FRAME_HEIGHT, getTitle())

		frame.makeCloseButton()
		frame.onClose { onClose() }

		val views = ArrayList<EditablePanel<*>>()
		val settings = ArrayList<EditablePanel<*>>()

		frame.Tab(onOpen = {
			for (panel in views) {
				panel.visible = true
			}
		}, onClose = {
			for (panel in views) {
				panel.visible = false
			}
		})

		frame.Tab(onOpen = {
			for (panel in settings) {
				panel.visible = true
			}
		}, onClose = {
			for (panel in settings) {
				panel.visible = false
			}
		})

		views.add(PowerGaugePanel(this, frame, menu.energyWidget, 8f, 16f))
		views.add(BatterySlotPanel(this, frame, menu.batterySlot, 8f, 67f))
		views.add(SlotPanel(this, frame, menu.driveSlot, 8f, 85f))

		val grid = GridPanel(this, frame, 28f, 16f, GRID_WIDTH * 18f, GRID_HEIGHT * 18f, GRID_WIDTH, GRID_HEIGHT)

		val scrollBar = DiscreteScrollBarPanel(this, frame, { integerDivisionDown(menu.networkedItemView.itemCount, GRID_WIDTH) }, { _, _, _ -> }, 192f, 14f, 92f)

		views.add(grid)
		views.add(scrollBar)

		for (i in 0 until GRID_WIDTH * GRID_HEIGHT) {
			object : AbstractSlotPanel<DriveViewerScreen>(this@DriveViewerScreen, grid, 0f, 0f) {
				override val itemStack: ItemStack get() {
					val index = i + scrollBar.scroll * GRID_WIDTH
					return menu.networkedItemView.sortedView.getOrNull(index)?.stack?.item ?: ItemStack.EMPTY
				}

				override fun mouseScrolledInner(x: Double, y: Double, scroll: Double): Boolean {
					return scrollBar.mouseScrolledInner(x, y, scroll)
				}

				override fun mouseClickedInner(x: Double, y: Double, button: Int): Boolean {
					val index = i + scrollBar.scroll * GRID_WIDTH
					menu.networkedItemView.mouseClick(index, button)
					return true
				}

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

				override fun getItemStackTooltip(stack: ItemStack): List<Component> {
					return super.getItemStackTooltip(stack).also {
						it as MutableList<Component>
						val index = i + scrollBar.scroll * GRID_WIDTH
						val realStack = menu.networkedItemView.sortedView.getOrNull(index)!!.stack
						it.add(TranslatableComponent("otm.gui.item_amount", realStack.count.toString()))
					}
				}
			}
		}

		val dock_left = FlexGridPanel(this, frame, 0f, 0f, 90f, 0f)
		dock_left.dock = Dock.LEFT
		dock_left.setDockMargin(4f, 0f, 4f, 0f)

		val grid_filter = FlexGridPanel(this, frame)
		grid_filter.dock = Dock.FILL
		settings.add(dock_left)
		settings.add(grid_filter)

		for (i in 0 until PortableCondensationDriveItem.MAX_FILTERS) {
			FilterSlotPanel(this, grid_filter, menu.driveFilterSlots[i], 0f, 0f)
		}

		CheckBoxLabelInputPanel(this, dock_left, menu.isWhitelist, TranslatableComponent("otm.gui.filter.is_whitelist"), width = 90f, height = 20f).also { it.setDockMargin(0f, 4f, 0f, 0f) }
		CheckBoxLabelInputPanel(this, dock_left, menu.matchTag, TranslatableComponent("otm.gui.filter.match_tag"), width = 90f, height = 20f).also { it.setDockMargin(0f, 4f, 0f, 0f) }
		CheckBoxLabelInputPanel(this, dock_left, menu.matchNBT, TranslatableComponent("otm.gui.filter.match_nbt"), width = 90f, height = 20f).also { it.setDockMargin(0f, 4f, 0f, 0f) }

		for (panel in settings) {
			panel.visible = false
		}

		return frame
	}

	companion object {
		const val FRAME_WIDTH = 210f
		const val FRAME_HEIGHT = 110f
		const val GRID_WIDTH = 9
		const val GRID_HEIGHT = 5
	}
}
