package ru.dbotthepony.mc.otm.config

import net.minecraftforge.common.ForgeConfigSpec
import net.minecraftforge.fml.ModLoadingContext
import net.minecraftforge.fml.config.ModConfig
import ru.dbotthepony.mc.otm.OverdriveThatMatters
import ru.dbotthepony.mc.otm.core.math.Decimal
import ru.dbotthepony.mc.otm.core.math.defineDecimal
import ru.dbotthepony.mc.otm.core.util.WriteOnce

abstract class AbstractConfig(private val configName: String, private val type: ModConfig.Type = ModConfig.Type.SERVER) {
	private var spec: ForgeConfigSpec by WriteOnce()
	protected val builder = ForgeConfigSpec.Builder()
	private var registered = false

	fun verboseValues(name: String, storage: Decimal, receive: Decimal, extract: Decimal = receive): VerboseBalanceValues {
		builder.push(name)

		val obj = object : VerboseBalanceValues {
			override val capacity: Decimal by builder.defineDecimal("capacity", storage, minimum = Decimal.ONE)
			override val receive: Decimal by builder.defineDecimal("receive", receive, minimum = Decimal.ONE)
			override val extract: Decimal by builder.defineDecimal("extract", extract, minimum = Decimal.ONE)
		}

		builder.pop()

		return obj
	}

	fun batteryValues(name: String, storage: Decimal, receive: Decimal, extract: Decimal = receive, initialBatteryLevel: Decimal = Decimal.ZERO): BatteryBalanceValues {
		builder.push(name)

		val obj = object : BatteryBalanceValues {
			override val capacity: Decimal by builder.defineDecimal("capacity", storage, minimum = Decimal.ONE)
			override val receive: Decimal by builder.defineDecimal("receive", receive, minimum = Decimal.ONE)
			override val extract: Decimal by builder.defineDecimal("extract", extract, minimum = Decimal.ONE)
			override val initialBatteryLevel: Decimal by builder.defineDecimal("initialBatteryLevel", initialBatteryLevel, minimum = Decimal.ZERO)
		}

		builder.pop()

		return obj
	}

	fun conciseValues(name: String, storage: Decimal, throughput: Decimal, configurator: ForgeConfigSpec.Builder.() -> Unit = {}): ConciseBalanceValues {
		builder.push(name)

		val obj = object : ConciseBalanceValues {
			override val capacity: Decimal by builder.defineDecimal("capacity", storage, minimum = Decimal.ONE)
			override val throughput: Decimal by builder.defineDecimal("throughput", throughput, minimum = Decimal.ONE)
		}

		configurator.invoke(builder)
		builder.pop()

		return obj
	}

	fun workerValues(name: String, storage: Decimal, throughput: Decimal, workTimeMultiplier: Double = 1.0, powerConsumption: Decimal, configurator: ForgeConfigSpec.Builder.() -> Unit = {}): WorkerBalanceValues {
		builder.push(name)

		val obj = object : WorkerBalanceValues {
			override val capacity: Decimal by builder.defineDecimal("capacity", storage, minimum = Decimal.ONE)
			override val throughput: Decimal by builder.defineDecimal("throughput", throughput, minimum = Decimal.ONE)
			override val powerConsumption: Decimal by builder.defineDecimal("powerConsumption", powerConsumption, minimum = Decimal.ONE)
			override val workTimeMultiplier: Double by builder.defineInRange("workTimeMultiplier", workTimeMultiplier, 0.0)
		}

		configurator.invoke(builder)
		builder.pop()

		return obj
	}

	fun register() {
		check(!registered) { "Already registered config" }
		registered = true
		spec = builder.build()
		ModLoadingContext.get().registerConfig(type, spec, "${OverdriveThatMatters.MOD_ID}-$configName.toml")
	}
}
