package ru.dbotthepony.mc.otm.registry

import net.minecraft.client.gui.screens.MenuScreens
import net.minecraft.world.flag.FeatureFlags
import net.minecraft.world.inventory.MenuType
import net.minecraftforge.eventbus.api.IEventBus
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent
import net.minecraftforge.registries.DeferredRegister
import net.minecraftforge.registries.ForgeRegistries
import ru.dbotthepony.mc.otm.OverdriveThatMatters
import ru.dbotthepony.mc.otm.block.entity.tech.AndroidChargerBlockEntity
import ru.dbotthepony.mc.otm.client.screen.decorative.CargoCrateScreen
import ru.dbotthepony.mc.otm.client.screen.decorative.FluidTankScreen
import ru.dbotthepony.mc.otm.client.screen.decorative.HoloSignScreen
import ru.dbotthepony.mc.otm.client.screen.decorative.MinecartCargoCrateScreen
import ru.dbotthepony.mc.otm.client.screen.matter.MatterReconstructorScreen
import ru.dbotthepony.mc.otm.client.screen.matter.MatterBottlerScreen
import ru.dbotthepony.mc.otm.client.screen.matter.MatterCapacitorBankScreen
import ru.dbotthepony.mc.otm.client.screen.matter.MatterDecomposerScreen
import ru.dbotthepony.mc.otm.client.screen.matter.MatterPanelScreen
import ru.dbotthepony.mc.otm.client.screen.matter.MatterRecyclerScreen
import ru.dbotthepony.mc.otm.client.screen.matter.MatterReplicatorScreen
import ru.dbotthepony.mc.otm.client.screen.matter.MatterScannerScreen
import ru.dbotthepony.mc.otm.client.screen.matter.PatternStorageScreen
import ru.dbotthepony.mc.otm.client.screen.storage.DriveRackScreen
import ru.dbotthepony.mc.otm.client.screen.storage.DriveViewerScreen
import ru.dbotthepony.mc.otm.client.screen.storage.ItemMonitorScreen
import ru.dbotthepony.mc.otm.client.screen.storage.StorageBusScreen
import ru.dbotthepony.mc.otm.client.screen.storage.StorageExporterScreen
import ru.dbotthepony.mc.otm.client.screen.storage.StorageImporterScreen
import ru.dbotthepony.mc.otm.client.screen.storage.StoragePowerSupplierScreen
import ru.dbotthepony.mc.otm.client.screen.tech.AndroidChargerScreen
import ru.dbotthepony.mc.otm.client.screen.tech.AndroidStationScreen
import ru.dbotthepony.mc.otm.client.screen.tech.BatteryBankScreen
import ru.dbotthepony.mc.otm.client.screen.tech.ChemicalGeneratorScreen
import ru.dbotthepony.mc.otm.client.screen.tech.CobblerScreen
import ru.dbotthepony.mc.otm.client.screen.tech.EnergyCounterScreen
import ru.dbotthepony.mc.otm.client.screen.tech.EnergyServoScreen
import ru.dbotthepony.mc.otm.client.screen.tech.EssenceStorageScreen
import ru.dbotthepony.mc.otm.client.screen.tech.PlatePressScreen
import ru.dbotthepony.mc.otm.client.screen.tech.PoweredFurnaceScreen
import ru.dbotthepony.mc.otm.client.screen.tech.TwinPlatePressScreen
import ru.dbotthepony.mc.otm.menu.decorative.CargoCrateMenu
import ru.dbotthepony.mc.otm.menu.decorative.FluidTankMenu
import ru.dbotthepony.mc.otm.menu.decorative.HoloSignMenu
import ru.dbotthepony.mc.otm.menu.decorative.MinecartCargoCrateMenu
import ru.dbotthepony.mc.otm.menu.matter.MatterReconstructorMenu
import ru.dbotthepony.mc.otm.menu.matter.MatterBottlerMenu
import ru.dbotthepony.mc.otm.menu.matter.MatterCapacitorBankMenu
import ru.dbotthepony.mc.otm.menu.matter.MatterDecomposerMenu
import ru.dbotthepony.mc.otm.menu.matter.MatterPanelMenu
import ru.dbotthepony.mc.otm.menu.matter.MatterRecyclerMenu
import ru.dbotthepony.mc.otm.menu.matter.MatterReplicatorMenu
import ru.dbotthepony.mc.otm.menu.matter.MatterScannerMenu
import ru.dbotthepony.mc.otm.menu.matter.PatternStorageMenu
import ru.dbotthepony.mc.otm.menu.storage.DriveRackMenu
import ru.dbotthepony.mc.otm.menu.storage.DriveViewerMenu
import ru.dbotthepony.mc.otm.menu.storage.ItemMonitorMenu
import ru.dbotthepony.mc.otm.menu.storage.StorageBusMenu
import ru.dbotthepony.mc.otm.menu.storage.StorageExporterMenu
import ru.dbotthepony.mc.otm.menu.storage.StorageImporterMenu
import ru.dbotthepony.mc.otm.menu.storage.StoragePowerSupplierMenu
import ru.dbotthepony.mc.otm.menu.tech.AndroidChargerMenu
import ru.dbotthepony.mc.otm.menu.tech.AndroidStationMenu
import ru.dbotthepony.mc.otm.menu.tech.BatteryBankMenu
import ru.dbotthepony.mc.otm.menu.tech.ChemicalGeneratorMenu
import ru.dbotthepony.mc.otm.menu.tech.CobblerMenu
import ru.dbotthepony.mc.otm.menu.tech.EnergyCounterMenu
import ru.dbotthepony.mc.otm.menu.tech.EnergyServoMenu
import ru.dbotthepony.mc.otm.menu.tech.EssenceStorageMenu
import ru.dbotthepony.mc.otm.menu.tech.PlatePressMenu
import ru.dbotthepony.mc.otm.menu.tech.PoweredFurnaceMenu
import ru.dbotthepony.mc.otm.menu.tech.TwinPlatePressMenu

object MMenus {
	private val registry = DeferredRegister.create(ForgeRegistries.MENU_TYPES, OverdriveThatMatters.MOD_ID)

	val ANDROID_STATION: MenuType<AndroidStationMenu> by registry.register(MNames.ANDROID_STATION) { MenuType(::AndroidStationMenu, FeatureFlags.VANILLA_SET) }
	val ANDROID_CHARGER: MenuType<AndroidChargerMenu> by registry.register(MNames.ANDROID_CHARGER) { MenuType({ a, b -> AndroidChargerMenu(a, b, null as AndroidChargerBlockEntity?) }, FeatureFlags.VANILLA_SET) }
	val BATTERY_BANK: MenuType<BatteryBankMenu> by registry.register(MNames.BATTERY_BANK) { MenuType(::BatteryBankMenu, FeatureFlags.VANILLA_SET) }
	val MATTER_DECOMPOSER: MenuType<MatterDecomposerMenu> by registry.register(MNames.MATTER_DECOMPOSER) { MenuType(::MatterDecomposerMenu, FeatureFlags.VANILLA_SET) }
	val MATTER_CAPACITOR_BANK: MenuType<MatterCapacitorBankMenu> by registry.register(MNames.MATTER_CAPACITOR_BANK) { MenuType(::MatterCapacitorBankMenu, FeatureFlags.VANILLA_SET) }
	val PATTERN_STORAGE: MenuType<PatternStorageMenu> by registry.register(MNames.PATTERN_STORAGE) { MenuType(::PatternStorageMenu, FeatureFlags.VANILLA_SET) }
	val MATTER_SCANNER: MenuType<MatterScannerMenu> by registry.register(MNames.MATTER_SCANNER) { MenuType(::MatterScannerMenu, FeatureFlags.VANILLA_SET) }
	val MATTER_PANEL: MenuType<MatterPanelMenu> by registry.register(MNames.MATTER_PANEL) { MenuType(::MatterPanelMenu, FeatureFlags.VANILLA_SET) }
	val MATTER_REPLICATOR: MenuType<MatterReplicatorMenu> by registry.register(MNames.MATTER_REPLICATOR) { MenuType(::MatterReplicatorMenu, FeatureFlags.VANILLA_SET) }
	val MATTER_BOTTLER: MenuType<MatterBottlerMenu> by registry.register(MNames.MATTER_BOTTLER) { MenuType(::MatterBottlerMenu, FeatureFlags.VANILLA_SET) }
	val DRIVE_VIEWER: MenuType<DriveViewerMenu> by registry.register(MNames.DRIVE_VIEWER) { MenuType(::DriveViewerMenu, FeatureFlags.VANILLA_SET) }
	val CARGO_CRATE: MenuType<CargoCrateMenu> by registry.register(MNames.CARGO_CRATE) { MenuType(::CargoCrateMenu, FeatureFlags.VANILLA_SET) }
	val MINECART_CARGO_CRATE: MenuType<MinecartCargoCrateMenu> by registry.register(MNames.MINECART_CARGO_CRATE) { MenuType(::MinecartCargoCrateMenu, FeatureFlags.VANILLA_SET) }
	val DRIVE_RACK: MenuType<DriveRackMenu> by registry.register(MNames.DRIVE_RACK) { MenuType(::DriveRackMenu, FeatureFlags.VANILLA_SET) }
	val ITEM_MONITOR: MenuType<ItemMonitorMenu> by registry.register(MNames.ITEM_MONITOR) { MenuType(::ItemMonitorMenu, FeatureFlags.VANILLA_SET) }
	val ENERGY_COUNTER: MenuType<EnergyCounterMenu> by registry.register(MNames.ENERGY_COUNTER) { MenuType(::EnergyCounterMenu, FeatureFlags.VANILLA_SET) }
	val CHEMICAL_GENERATOR: MenuType<ChemicalGeneratorMenu> by registry.register(MNames.CHEMICAL_GENERATOR) { MenuType(::ChemicalGeneratorMenu, FeatureFlags.VANILLA_SET) }
	val PLATE_PRESS: MenuType<PlatePressMenu> by registry.register(MNames.PLATE_PRESS) { MenuType(::PlatePressMenu, FeatureFlags.VANILLA_SET) }
	val POWERED_FURNACE: MenuType<PoweredFurnaceMenu> by registry.register(MNames.POWERED_FURNACE) { MenuType(::PoweredFurnaceMenu, FeatureFlags.VANILLA_SET) }
	val TWIN_PLATE_PRESS: MenuType<TwinPlatePressMenu> by registry.register(MNames.TWIN_PLATE_PRESS) { MenuType(::TwinPlatePressMenu, FeatureFlags.VANILLA_SET) }
	val MATTER_RECYCLER: MenuType<MatterRecyclerMenu> by registry.register(MNames.MATTER_RECYCLER) { MenuType(::MatterRecyclerMenu, FeatureFlags.VANILLA_SET) }
	val ENERGY_SERVO: MenuType<EnergyServoMenu> by registry.register(MNames.ENERGY_SERVO) { MenuType(::EnergyServoMenu, FeatureFlags.VANILLA_SET) }
	val HOLO_SIGN: MenuType<HoloSignMenu> by registry.register(MNames.HOLO_SIGN) { MenuType(::HoloSignMenu, FeatureFlags.VANILLA_SET) }
	val COBBLESTONE_GENERATOR: MenuType<CobblerMenu> by registry.register(MNames.COBBLESTONE_GENERATOR) { MenuType(::CobblerMenu, FeatureFlags.VANILLA_SET) }
	val ESSENCE_STORAGE: MenuType<EssenceStorageMenu> by registry.register(MNames.ESSENCE_STORAGE) { MenuType(::EssenceStorageMenu, FeatureFlags.VANILLA_SET) }
	val ITEM_REPAIER: MenuType<MatterReconstructorMenu> by registry.register(MNames.MATTER_RECONSTRUCTOR) { MenuType(::MatterReconstructorMenu, FeatureFlags.VANILLA_SET) }
	val FLUID_TANK: MenuType<FluidTankMenu> by registry.register(MNames.FLUID_TANK) { MenuType(::FluidTankMenu, FeatureFlags.VANILLA_SET) }

	val STORAGE_BUS: MenuType<StorageBusMenu> by registry.register(MNames.STORAGE_BUS) { MenuType(::StorageBusMenu, FeatureFlags.VANILLA_SET) }
	val STORAGE_EXPORTER: MenuType<StorageExporterMenu> by registry.register(MNames.STORAGE_EXPORTER) { MenuType(::StorageExporterMenu, FeatureFlags.VANILLA_SET) }
	val STORAGE_IMPORTER: MenuType<StorageImporterMenu> by registry.register(MNames.STORAGE_IMPORTER) { MenuType(::StorageImporterMenu, FeatureFlags.VANILLA_SET) }
	val STORAGE_POWER_SUPPLIER: MenuType<StoragePowerSupplierMenu> by registry.register(MNames.STORAGE_POWER_SUPPLIER) { MenuType(::StoragePowerSupplierMenu, FeatureFlags.VANILLA_SET) }

	internal fun register(bus: IEventBus) {
		registry.register(bus)
		bus.addListener(this::registerClient)
	}

	@Suppress("unchecked_cast")
	private fun registerClient(event: FMLClientSetupEvent) {
		event.enqueueWork {
			MenuScreens.register(ANDROID_STATION, ::AndroidStationScreen)
			MenuScreens.register(ANDROID_CHARGER, ::AndroidChargerScreen)
			MenuScreens.register(BATTERY_BANK, ::BatteryBankScreen)
			MenuScreens.register(MATTER_DECOMPOSER, ::MatterDecomposerScreen)
			MenuScreens.register(MATTER_CAPACITOR_BANK, ::MatterCapacitorBankScreen)
			MenuScreens.register(PATTERN_STORAGE, ::PatternStorageScreen)
			MenuScreens.register(MATTER_SCANNER, ::MatterScannerScreen)
			MenuScreens.register(MATTER_PANEL, ::MatterPanelScreen)
			MenuScreens.register(MATTER_REPLICATOR, ::MatterReplicatorScreen)
			MenuScreens.register(MATTER_BOTTLER, ::MatterBottlerScreen)
			MenuScreens.register(DRIVE_VIEWER, ::DriveViewerScreen)
			MenuScreens.register(CARGO_CRATE, ::CargoCrateScreen)
			MenuScreens.register(MINECART_CARGO_CRATE, ::MinecartCargoCrateScreen)
			MenuScreens.register(DRIVE_RACK, ::DriveRackScreen)
			MenuScreens.register(ITEM_MONITOR, ::ItemMonitorScreen)
			MenuScreens.register(ENERGY_COUNTER, ::EnergyCounterScreen)
			MenuScreens.register(CHEMICAL_GENERATOR, ::ChemicalGeneratorScreen)
			MenuScreens.register(PLATE_PRESS, ::PlatePressScreen)
			MenuScreens.register(TWIN_PLATE_PRESS, ::TwinPlatePressScreen)
			MenuScreens.register(MATTER_RECYCLER, ::MatterRecyclerScreen)
			MenuScreens.register(STORAGE_BUS, ::StorageBusScreen)
			MenuScreens.register(STORAGE_EXPORTER, ::StorageExporterScreen)
			MenuScreens.register(STORAGE_IMPORTER, ::StorageImporterScreen)
			MenuScreens.register(STORAGE_POWER_SUPPLIER, ::StoragePowerSupplierScreen)
			MenuScreens.register(ENERGY_SERVO, ::EnergyServoScreen)
			MenuScreens.register(HOLO_SIGN, ::HoloSignScreen)
			MenuScreens.register(COBBLESTONE_GENERATOR, ::CobblerScreen)
			MenuScreens.register(ESSENCE_STORAGE, ::EssenceStorageScreen)
			MenuScreens.register(ITEM_REPAIER, ::MatterReconstructorScreen)
			MenuScreens.register(FLUID_TANK, ::FluidTankScreen)
			MenuScreens.register(POWERED_FURNACE, ::PoweredFurnaceScreen)
		}
	}
}
