package ru.dbotthepony.kstarbound.defs.world

import com.google.common.collect.ImmutableList
import com.google.common.collect.ImmutableMap
import com.google.gson.JsonElement
import com.google.gson.JsonNull
import com.google.gson.JsonObject
import ru.dbotthepony.kommons.util.AABBi
import ru.dbotthepony.kommons.util.Either
import ru.dbotthepony.kommons.vector.Vector2d
import ru.dbotthepony.kommons.vector.Vector2i
import ru.dbotthepony.kstarbound.json.builder.JsonFactory
import ru.dbotthepony.kstarbound.world.Direction

@JsonFactory
data class WorldStructure(
	val region: AABBi = AABBi(Vector2i.ZERO, Vector2i.ZERO),
	val anchorPosition: Vector2i = Vector2i.ZERO,
	var config: JsonElement = JsonObject(),
	val backgroundOverlays: ImmutableList<Overlay> = ImmutableList.of(),
	val foregroundOverlays: ImmutableList<Overlay> = ImmutableList.of(),
	val backgroundBlocks: ImmutableList<Block> = ImmutableList.of(),
	val foregroundBlocks: ImmutableList<Block> = ImmutableList.of(),
	val objects: ImmutableList<Obj> = ImmutableList.of(),
	val flaggedBlocks: ImmutableMap<String, ImmutableList<Vector2i>> = ImmutableMap.of(),
) {
	init {
		if (config == JsonNull.INSTANCE) {
			// so it is not omitted
			config = JsonObject()
		}
	}

	@JsonFactory
	data class Overlay(val min: Vector2d, val image: String, val fullbright: Boolean)

	@JsonFactory
	data class Block(val position: Vector2i, val materialId: Either<Int, String>, val residual: Boolean)

	@JsonFactory
	data class Obj(
		val position: Vector2i,
		val name: String,
		val direction: Direction,
		val parameters: JsonElement,
		val residual: Boolean = false,
	)
}
