package ru.dbotthepony.mc.otm.graph.storage

import it.unimi.dsi.fastutil.objects.Object2ObjectArrayMap
import it.unimi.dsi.fastutil.objects.Object2ObjectFunction
import ru.dbotthepony.mc.otm.capability.energy.IMatteryEnergyStorage
import ru.dbotthepony.mc.otm.graph.GraphNodeList
import ru.dbotthepony.mc.otm.storage.*
import java.util.LinkedList

class StorageGraph : GraphNodeList<StorageNode, StorageGraph>() {
	private val virtualComponents = Object2ObjectArrayMap<StorageStack.Type<*>, VirtualComponent<*>>()
	val powerDemandingNodes = LinkedList<IMatteryEnergyStorage>()

	fun <T : StorageStack<T>> getVirtualComponent(type: StorageStack.Type<T>): VirtualComponent<T> {
		return virtualComponents.computeIfAbsent(type, Object2ObjectFunction { VirtualComponent(type) }) as VirtualComponent<T>
	}

	fun <T : StorageStack<T>> add(storage: IStorage<T>) {
		getVirtualComponent(storage.storageType).add(storage)
	}

	fun <T : StorageStack<T>> remove(storage: IStorage<T>) {
		getVirtualComponent(storage.storageType).remove(storage)
	}

	fun <T : StorageStack<T>> contains(storage: IStorage<T>): Boolean {
		val virtual = virtualComponents[storage.storageType] ?: return false
		return (virtual as VirtualComponent<T>).contains(storage)
	}

	override fun onNodeAdded(node: StorageNode) {
		node.attachComponents(this)
	}

	override fun onNodeRemoved(node: StorageNode) {
		node.removeComponents(this)
	}
}
