package ru.dbotthepony.kstarbound.defs.animation

import ru.dbotthepony.kommons.math.RGBAColor
import ru.dbotthepony.kommons.vector.Vector2d
import ru.dbotthepony.kstarbound.defs.AssetPath
import ru.dbotthepony.kstarbound.json.builder.IStringSerializable
import ru.dbotthepony.kstarbound.json.builder.JsonFactory
import java.util.random.RandomGenerator

interface ParticleFactory {
	fun create(): Particle
	fun create(random: RandomGenerator): Particle
}

@JsonFactory
class ParticleConfig(
	val kind: String? = null,
	val definition: JsonData,
) : ParticleFactory {
	override fun create(): Particle {
		return definition.create()
	}

	override fun create(random: RandomGenerator): Particle {
		return definition.create(random)
	}

	enum class Type(override val jsonName: String) : IStringSerializable {
		VARIANCE("variance"),
		EMBER("ember"),
		TEXTURED("textured"),
		ANIMATED("animated"),
		STREAK("streak"),
		TEXT("text");
	}

	enum class Layer(override val jsonName: String) : IStringSerializable {
		BACK("back"),
		MIDDLE("middle"),
		FRONT("front");
	}

	enum class DestructionAction(override val jsonName: String) : IStringSerializable {
		NONE("none"),
		IMAGE("image"),
		FADE("fade"),
		SHRINK("shrink");
	}

	@JsonFactory
	data class JsonData(
		val variance: JsonData? = null,
		val type: Type = Type.VARIANCE,
		val size: Double? = null,
		val image: AssetPath? = null,
		val animation: AssetPath? = null,
		val text: String? = null,
		val string: String? = null,
		val color: RGBAColor? = null,
		val light: RGBAColor = RGBAColor.TRANSPARENT_BLACK,
		val fade: Double = 0.0,
		val fullbright: Boolean = false,
		val position: Vector2d = Vector2d.ZERO,
		val velocity: Vector2d? = null,
		val initialVelocity: Vector2d? = null,
		val finalVelocity: Vector2d? = null,
		val approach: Vector2d = Vector2d.ZERO,
		val flip: Boolean = false,
		val flippable: Boolean = true,
		val rotation: Double = 0.0,
		val angularVelocity: Double = 0.0,
		val length: Double = 10.0,
		val destructionAction: DestructionAction = DestructionAction.NONE,
		val destructionImage: AssetPath? = null,
		val destructionTime: Double = 0.0,
		val timeToLive: Double = 0.0,
		val layer: Layer = Layer.MIDDLE,
		val underwaterOnly: Boolean = false,
		val collidesForeground: Boolean? = null,
		val collidesLiquid: Boolean? = null,
		val ignoreWind: Boolean = true,
		val trail: Boolean = false,
	) : ParticleFactory {
		private val variance2 = if (variance != null) Particle(variance) else null
		private val prototype = Particle(this)

		override fun create(): Particle {
			return prototype.copy()
		}

		override fun create(random: RandomGenerator): Particle {
			if (variance2 == null)
				return prototype.copy()

			return prototype.copy().applyVariance(variance2, random)
		}
	}
}
