package ru.dbotthepony.mc.otm.client.render

import ru.dbotthepony.mc.otm.block.entity.MatteryDeviceBlockEntity
import ru.dbotthepony.mc.otm.capability.FlowDirection
import ru.dbotthepony.mc.otm.core.immutableMap
import ru.dbotthepony.mc.otm.core.math.RelativeSide

private fun makeButton(grid: GridAtlas): StretchingRectangleElement {
	val x = grid.currentX
	val y = grid.currentY

	return StretchingRectangleElement(
		topLeft = grid.texture.sprite(x, y, 2f, 2f, grid.atlasWidth, grid.atlasHeight),
		topRight = grid.texture.sprite(x + 16f, y, 2f, 2f, grid.atlasWidth, grid.atlasHeight),
		bottomLeft = grid.texture.sprite(x, y + 16f, 2f, 2f, grid.atlasWidth, grid.atlasHeight),
		bottomRight = grid.texture.sprite(x + 16f, y + 16f, 2f, 2f, grid.atlasWidth, grid.atlasHeight),
		middle = grid.texture.sprite(x + 2f, y + 2f, 14f, 14f, grid.atlasWidth, grid.atlasHeight),
		top = grid.texture.sprite(x + 2f, y, 14f, 2f, grid.atlasWidth, grid.atlasHeight),
		left = grid.texture.sprite(x, y + 2f, 2f, 14f, grid.atlasWidth, grid.atlasHeight),
		right = grid.texture.sprite(x + 16f, y + 2f, 2f, 14f, grid.atlasWidth, grid.atlasHeight),
		bottom = grid.texture.sprite(x + 2f, y + 16f, 14f, 2f, grid.atlasWidth, grid.atlasHeight),
	)
}

object Widgets18 {
	private val buttonGrids = WidgetLocation.LARGE_BUTTON.grid(rows = 1, columns = 4)

	val BUTTON_IDLE_STRETCHABLE = makeButton(buttonGrids)
	val BUTTON_IDLE = buttonGrids.next()
	val BUTTON_HOVERED_STRETCHABLE = makeButton(buttonGrids)
	val BUTTON_HOVERED = buttonGrids.next()
	val BUTTON_PRESSED_STRETCHABLE = makeButton(buttonGrids)
	val BUTTON_PRESSED = buttonGrids.next()
	val BUTTON_DISABLED_STRETCHABLE = makeButton(buttonGrids)
	val BUTTON_DISABLED = buttonGrids.next()

	private val storageGrid = WidgetLocation.STORAGE_CONTROLS.grid(rows = 2, columns = 5)
	val ARROW_DOWN = storageGrid.next()
	val ARROW_UP = storageGrid.next()
	val SORT_DEFAULT = storageGrid.next()
	val SORT_ALPHABET = storageGrid.next()
	val SORT_COUNT = storageGrid.next()
	val SORT_MODID = storageGrid.next()
	val SORT_ID = storageGrid.next()
	val SORT_MATTER_VALUE = storageGrid.next()
	val SORT_MATTER_COMPLEXITY = storageGrid.next()

	private val miscGrid = WidgetLocation.MISC_18.grid(4, 4)

	val COOLDOWN = miscGrid.next()
	val CROSS = miscGrid.next()
	val FORWARD_SLASH = miscGrid.next()
	val RETURN_ARROW_LEFT = miscGrid.next()
	val CURIOS_INVENTORY = miscGrid.next()

	private val slotBgGrid = WidgetLocation.SLOT_BACKGROUNDS.grid(4, 4)

	val BATTERY_SLOT_BACKGROUND = slotBgGrid.next()
	val EQUIPMENT_BATTERY_SLOT_BACKGROUND = slotBgGrid.next()
	val PATTERN_SLOT_BACKGROUND = slotBgGrid.next()
	val MATTER_CAPACITOR_SLOT_BACKGROUND = slotBgGrid.next()
	val CHARGE_SLOT_BACKGROUND = slotBgGrid.next()

	private val controlsGrid = WidgetLocation.SIDE_CONTROLS.grid(rows = 8, columns = 9)

	val BATTERY_ONLY = controlsGrid.next()
	val ITEMS_CONFIGURATION = controlsGrid.next()
	val ENERGY_CONFIGURATION = controlsGrid.next()
	val FLUID_CONFIGURATION = controlsGrid.next()

	val REDSTONE_IGNORED = controlsGrid.next()
	val REDSTONE_LOW = controlsGrid.next()
	val REDSTONE_HIGH = controlsGrid.next()

	val BALANCING_DISABLED = controlsGrid.next()
	val BALANCING_ENABLED = controlsGrid.next()

	class SideControls {
		val disabled = controlsGrid.next()
		val input = controlsGrid.next()
		val pull = controlsGrid.next()
		val output = controlsGrid.next()
		val push = controlsGrid.next()
		val inputOutput = controlsGrid.next()
		val pullOutput = controlsGrid.next()
		val inputPush = controlsGrid.next()
		val pullPush = controlsGrid.next()

		val flow = immutableMap {
			put(FlowDirection.NONE, disabled)
			put(FlowDirection.INPUT, input)
			put(FlowDirection.OUTPUT, output)
			put(FlowDirection.BI_DIRECTIONAL, inputOutput)
		}

		val flowPush = immutableMap {
			put(FlowDirection.NONE, disabled)
			put(FlowDirection.INPUT, input)
			put(FlowDirection.OUTPUT, push)
			put(FlowDirection.BI_DIRECTIONAL, inputPush)
		}

		val flowPull = immutableMap {
			put(FlowDirection.NONE, disabled)
			put(FlowDirection.INPUT, pull)
			put(FlowDirection.OUTPUT, output)
			put(FlowDirection.BI_DIRECTIONAL, pullOutput)
		}

		val flowPullPush = immutableMap {
			put(FlowDirection.NONE, disabled)
			put(FlowDirection.INPUT, pull)
			put(FlowDirection.OUTPUT, push)
			put(FlowDirection.BI_DIRECTIONAL, pullPush)
		}

		val items = immutableMap {
			put(MatteryDeviceBlockEntity.ItemHandlerMode.DISABLED, disabled)
			put(MatteryDeviceBlockEntity.ItemHandlerMode.INPUT, input)
			put(MatteryDeviceBlockEntity.ItemHandlerMode.OUTPUT, output)
			put(MatteryDeviceBlockEntity.ItemHandlerMode.INPUT_OUTPUT, inputOutput)
			put(MatteryDeviceBlockEntity.ItemHandlerMode.BATTERY, BATTERY_ONLY)
		}

		val itemsPush = immutableMap {
			put(MatteryDeviceBlockEntity.ItemHandlerMode.DISABLED, disabled)
			put(MatteryDeviceBlockEntity.ItemHandlerMode.INPUT, input)
			put(MatteryDeviceBlockEntity.ItemHandlerMode.OUTPUT, push)
			put(MatteryDeviceBlockEntity.ItemHandlerMode.INPUT_OUTPUT, inputPush)
			put(MatteryDeviceBlockEntity.ItemHandlerMode.BATTERY, BATTERY_ONLY)
		}

		val itemsPull = immutableMap {
			put(MatteryDeviceBlockEntity.ItemHandlerMode.DISABLED, disabled)
			put(MatteryDeviceBlockEntity.ItemHandlerMode.INPUT, pull)
			put(MatteryDeviceBlockEntity.ItemHandlerMode.OUTPUT, output)
			put(MatteryDeviceBlockEntity.ItemHandlerMode.INPUT_OUTPUT, pullOutput)
			put(MatteryDeviceBlockEntity.ItemHandlerMode.BATTERY, BATTERY_ONLY)
		}

		val itemsPullPush = immutableMap {
			put(MatteryDeviceBlockEntity.ItemHandlerMode.DISABLED, disabled)
			put(MatteryDeviceBlockEntity.ItemHandlerMode.INPUT, pull)
			put(MatteryDeviceBlockEntity.ItemHandlerMode.OUTPUT, push)
			put(MatteryDeviceBlockEntity.ItemHandlerMode.INPUT_OUTPUT, pullPush)
			put(MatteryDeviceBlockEntity.ItemHandlerMode.BATTERY, BATTERY_ONLY)
		}
	}

	val LEFT_CONTROLS = SideControls()
	val RIGHT_CONTROLS = SideControls()
	val TOP_CONTROLS = SideControls()
	val BOTTOM_CONTROLS = SideControls()
	val FRONT_CONTROLS = SideControls()
	val BACK_CONTROLS = SideControls()

	val CONTROLS = immutableMap {
		put(RelativeSide.BOTTOM, BOTTOM_CONTROLS)
		put(RelativeSide.TOP, TOP_CONTROLS)
		put(RelativeSide.LEFT, LEFT_CONTROLS)
		put(RelativeSide.RIGHT, RIGHT_CONTROLS)
		put(RelativeSide.FRONT, FRONT_CONTROLS)
		put(RelativeSide.BACK, BACK_CONTROLS)
	}

	val UPGRADES = controlsGrid.next()
}
