package ru.dbotthepony.kstarbound.defs.dungeon

import com.google.common.collect.ImmutableList
import com.google.gson.JsonSyntaxException
import ru.dbotthepony.kommons.util.KOptional
import ru.dbotthepony.kommons.vector.Vector2i
import ru.dbotthepony.kstarbound.Starbound
import ru.dbotthepony.kstarbound.util.AssetPathStack
import java.util.stream.Stream

class TiledPartReader(part: DungeonPart, parts: Stream<String>) : PartReader(part) {
	val maps: ImmutableList<TiledMap> = parts
		.map { Starbound.locate(AssetPathStack.remap(it)) }
		.peek { check(it.exists) { "Dungeon references part which does not exist: $it" } }
		// well, i don't think anyone gonna patch THESE json files, i guess
		// so ignore json patches and just read directly
		.map {
			try {
				TiledMap(Starbound.gson.fromJson(it.jsonReader(), TiledMap.JsonData::class.java))
			} catch (err: Throwable) {
				throw JsonSyntaxException("Exception while reading tile map $it", err)
			}
		}
		.collect(ImmutableList.toImmutableList())

	// also why would you ever want multiple maps specified lmao
	// it already has layers and everything else you would ever need

	override val size: Vector2i
		get() = maps.firstOrNull()?.size ?: Vector2i.ZERO

	override fun bind(def: DungeonDefinition) {

	}

	override fun <T> walkTiles(callback: TileCallback<T>): KOptional<T> {
		for (map in maps) {
			val result = map.walkTiles(callback)
			if (result.isPresent) return result
		}

		return KOptional()
	}

	override fun <T> walkTilesAt(x: Int, y: Int, callback: TileCallback<T>): KOptional<T> {
		for (map in maps) {
			val result = map.walkTilesAt(x, y, callback)
			if (result.isPresent) return result
		}

		return KOptional()
	}
}
