package ru.dbotthepony.mc.otm.config

import ru.dbotthepony.mc.otm.core.math.Decimal
import ru.dbotthepony.mc.otm.core.math.defineDecimal

object AndroidConfig : AbstractConfig("androids") {
	val REGENERATE_ENERGY: Boolean by builder
		.comment("If (technically) hunger is above threshold, it turns into energy")
		.comment("This setting controls whenever to regenerate small amount of energy while eating as Android")
		.comment("And also whenever to regenerate energy while in peaceful")
		.comment("If this is disabled, any (technically) excess hunger will be nullified, unless playing on peaceful difficulty.")
		.define("REGENERATE_ENERGY", true)

	val TIME_BETWEEN_NATURAL_REGENERATION: Int by builder
		.comment("Time in ticks between natural health regeneration ticks")
		.comment("Default value is meant to be one of downsides of being an android,")
		.comment("so please, don't blindly buff it, players have ability to research into Nanobots Regeneration,")
		.comment("which provide superior regeneration on average than human players.")
		.comment("---")
		.comment("This regeneration obeys natural regeneration gamerule")
		.comment("---")
		.comment("Reason for this config option is that FoodData does not tick")
		.comment("for android players, since 'hunger' (for compatibility) is managed by mod in such case")
		.defineInRange("TIME_BETWEEN_NATURAL_REGENERATION", 120, 0, Int.MAX_VALUE)

	object NanobotsRegeneration {
		init {
			builder.push("NanobotsRegeneration")
		}

		val COOLDOWN: List<Int> by builder
			.comment("In ticks, time between heal ticks")
			.comment("One heal tick restores 1 heart (2 health points) at most")
			.comment("If not getting hurt in specified period of ticks, heal tick takes place, tick timer resets to zero and THIS array' index advances by 1")
			.comment("Index inside this array can not exceed of one of ability's")
			.comment("")
			.comment("Wording in pseudocode:")
			.comment("if (ticksSinceTakingDamage >= cooldownConfigOption[healTicks /* or config's biggest index, whichever is smaller */]) {")
			.comment("    healTicks = min(healTicks + 1, level /* ability level */)")
			.comment("    ticksSinceTakingDamage = 0")
			.comment("    this.ply.heal(...)")
			.comment("}")
			.defineList("COOLDOWN", { mutableListOf(60, 50, 40, 30) }) { it is Int }

		val ENERGY_PER_HITPOINT by builder
			.comment("Energy required to regenerate 1 health point (half a heart)")
			.defineDecimal("ENERGY_PER_HITPOINT", Decimal(800))

		init {
			builder.pop()
		}
	}

	val ANDROID_ENERGY_PER_HUNGER_POINT by builder.defineDecimal("energyPerHunger", Decimal(2000), Decimal.ZERO)
	val ANDROID_MAX_ENERGY by builder
		.comment("Internal battery of every android has this much storage")
		.comment("Keep in mind that already existing players won't get their value changed since it is", "stored inside their savedata")
		.defineDecimal("capacity", Decimal(80_000), Decimal.ZERO)
	val NIGHT_VISION_POWER_DRAW by builder.defineDecimal("nightVisionPowerDraw", Decimal(8), Decimal.ZERO)

	val FALL_DAMAGE_REDUCTION_PER_LEVEL_P: Double by builder
		.comment("In percent. Level of feature is multiplied by this")
		.comment("First, fall damage is reduced by flat resistance, then reduced by percentage resistance (this)")
		.defineInRange("FALL_DAMAGE_REDUCTION_PER_LEVEL_P", 0.2, 0.01, 1.0)

	val FALL_DAMAGE_REDUCTION_PER_LEVEL_F: Double by builder
		.comment("In flat half of hearts. Level of feature is multiplied by this")
		.comment("First, fall damage is reduced by flat resistance (this), then reduced by percentage resistance")
		.defineInRange("FALL_DAMAGE_REDUCTION_PER_LEVEL_F", 1.5, 0.0, Float.MAX_VALUE.toDouble())

	object EnderTeleporter {
		init {
			builder.comment("Ender Teleporter ability").push("EnderTeleporter")
		}

		val ENERGY_COST by builder.defineDecimal("ENERGY_COST", Decimal(4096), Decimal.ZERO)
		val COOLDOWN: Int by builder.comment("In ticks").defineInRange("COOLDOWN", 40, 0, Int.MAX_VALUE)
		val MAX_PHASE_DISTANCE: Int by builder.comment("Determines how much blocks can we 'phase' through to teleport on solid surface").defineInRange("MAX_PHASE_DISTANCE", 6, 0, Int.MAX_VALUE)
		val MAX_DISTANCE: Double by builder.comment("In blocks, euclidean distance").defineInRange("MAX_DISTANCE", 12.0, 2.0, Int.MAX_VALUE.toDouble())

		init {
			builder.pop()
		}
	}

	object JumpBoost {
		init {
			builder.comment("Jump boost ability").push("JumpBoost")
		}

		val ENERGY_COST by builder.defineDecimal("ENERGY_COST", Decimal(1024), Decimal.ZERO)
		val POWER: Double by builder.comment("The jump height on jump boost, as (level + 1) of feature, in meters per second").defineInRange("POWER", 6.0, 0.0, Double.MAX_VALUE)
		val BASE_COOLDOWN: Int by builder.comment("In ticks").defineInRange("BASE_COOLDOWN", 40, 0, Int.MAX_VALUE)
		val COOLDOWN_REDUCTION: Int by builder.comment("In ticks, per level of feature").defineInRange("COOLDOWN_REDUCTION", 20, 0, Int.MAX_VALUE)

		init {
			builder.pop()
		}
	}

	object Magnet {
		init {
			builder.comment("Item magnet ability").push("Magnet")
		}

		val POWER_DRAW by builder.comment("Per tick per stack").defineDecimal("POWER_DRAW", Decimal(8), Decimal.ZERO)
		val RADIUS_HORIZONTAL: Double by builder.defineInRange("RADIUS_HORIZONTAL", 6.0, 0.0, Double.MAX_VALUE / 4.0)
		val RADIUS_VERTICAL: Double by builder.defineInRange("RADIUS_VERTICAL", 3.0, 0.0, Double.MAX_VALUE / 4.0)

		init {
			builder.pop()
		}
	}

	object Shockwave {
		init {
			builder.comment("Shockwave ability").push("Shockwave")
		}

		val TERMINAL_VELOCITY: Double by builder.comment("In meters per second vertically").defineInRange("TERMINAL_VELOCITY", 5.6, 0.0)
		val ACCELERATION: Double by builder.comment("In meters per second vertically").defineInRange("ACCELERATION", 4.0, 0.0)
		val COOLDOWN: Int by builder.comment("In ticks").defineInRange("COOLDOWN", 30, 1)
		val RADIUS_HORIZONTAL: Double by builder.comment("In meters").defineInRange("RADIUS_HORIZONTAL", 4.0, 0.0)
		val RADIUS_VERTICAL: Double by builder.comment("In meters").defineInRange("RADIUS_VERTICAL", 1.0, 0.0)

		val RADIUS_HORIZONTAL_WARDEN: Double by builder.comment("In meters, when searching for Warden").defineInRange("RADIUS_HORIZONTAL_WARDEN", 16.0, 0.0)
		val RADIUS_VERTICAL_WARDEN: Double by builder.comment("In meters, when searching for Warden").defineInRange("RADIUS_VERTICAL_WARDEN", 6.0, 0.0)

		val BREAK_BLOCKS: Boolean by builder.comment("Break blocks without any blast resistance").define("BREAK_BLOCKS", true)
		val DAMAGE: Double by builder.comment("Max potential damage done by shockwave").defineInRange("DAMAGE", 12.0, 0.0, Float.MAX_VALUE.toDouble())
		val WARDEN_DAMAGE_MULT: Double by builder.defineInRange("WARDEN_DAMAGE_MULT", 4.0, 0.0, Float.MAX_VALUE.toDouble())
		val ENERGY_COST by builder.defineDecimal("ENERGY_COST", Decimal(2048), Decimal.ZERO)

		init {
			builder.pop()
		}
	}

	init {
		NanobotsRegeneration
		EnderTeleporter
		JumpBoost
		Magnet
		Shockwave
	}
}
