package ru.dbotthepony.mc.otm.menu.widget

import ru.dbotthepony.mc.otm.capability.energy.IMatteryEnergyStorage
import ru.dbotthepony.mc.otm.capability.matter.IMatterStorage
import ru.dbotthepony.mc.otm.capability.matter.IPatternStorage
import ru.dbotthepony.mc.otm.core.math.Decimal
import ru.dbotthepony.mc.otm.core.util.DecimalValueCodec
import ru.dbotthepony.mc.otm.menu.MatteryMenu
import ru.dbotthepony.mc.otm.network.synchronizer.FieldSynchronizer

@Suppress("unused")
class LevelGaugeWidget(synchronizer: FieldSynchronizer) {
	constructor(menu: MatteryMenu) : this(menu.mSynchronizer)

	var levelProvider = { Decimal.ONE }
	var maxLevelProvider = { Decimal.ONE }

	val level by synchronizer.ComputedField(getter = { levelProvider.invoke() }, codec = DecimalValueCodec)
	val maxLevel by synchronizer.ComputedField(getter = { maxLevelProvider.invoke() }, codec = DecimalValueCodec)

	constructor(
		menu: MatteryMenu,
		power: IMatteryEnergyStorage?
	) : this(menu.mSynchronizer) {
		if (power != null) {
			with(power)
		}
	}

	constructor(
		menu: MatteryMenu,
		matter: IMatterStorage?
	) : this(menu.mSynchronizer) {
		if (matter != null) {
			with(matter)
		}
	}

	constructor(
		menu: MatteryMenu,
		patterns: IPatternStorage?
	) : this(menu.mSynchronizer) {
		if (patterns != null) {
			with(patterns)
		}
	}

	constructor(
		menu: MatteryMenu,
		level: () -> Decimal,
		maxLevel: () -> Decimal,
	) : this(menu.mSynchronizer) {
		this.levelProvider = level
		this.maxLevelProvider = maxLevel
	}

	constructor(
		synchronizer: FieldSynchronizer,
		power: IMatteryEnergyStorage?
	) : this(synchronizer) {
		if (power != null) {
			with(power)
		}
	}

	constructor(
		synchronizer: FieldSynchronizer,
		matter: IMatterStorage?
	) : this(synchronizer) {
		if (matter != null) {
			with(matter)
		}
	}

	constructor(
		synchronizer: FieldSynchronizer,
		patterns: IPatternStorage?
	) : this(synchronizer) {
		if (patterns != null) {
			with(patterns)
		}
	}

	constructor(
		synchronizer: FieldSynchronizer,
		level: () -> Decimal,
		maxLevel: () -> Decimal,
	) : this(synchronizer) {
		this.levelProvider = level
		this.maxLevelProvider = maxLevel
	}

	val percentage: Float get() = level.percentage(maxLevel)

	fun with(level: () -> Decimal, maxLevel: () -> Decimal): LevelGaugeWidget {
		this.levelProvider = level
		this.maxLevelProvider = maxLevel
		return this
	}

	fun with(patterns: IPatternStorage): LevelGaugeWidget {
		this.levelProvider = { Decimal(patterns.storedPatterns) }
		this.maxLevelProvider = { Decimal(patterns.patternCapacity) }
		return this
	}

	fun with(power: IMatteryEnergyStorage): LevelGaugeWidget {
		this.levelProvider = power::batteryLevel
		this.maxLevelProvider = power::maxBatteryLevel
		return this
	}

	fun with(matter: IMatterStorage): LevelGaugeWidget {
		this.levelProvider = matter::storedMatter
		this.maxLevelProvider = matter::maxStoredMatter
		return this
	}
}
