package ru.dbotthepony.kstarbound.client.network.packets

import ru.dbotthepony.kommons.io.readCollection
import ru.dbotthepony.kommons.io.writeCollection
import ru.dbotthepony.kommons.io.writeStruct2i
import ru.dbotthepony.kstarbound.client.ClientConnection
import ru.dbotthepony.kstarbound.network.IClientPacket
import ru.dbotthepony.kstarbound.io.readChunkPos
import ru.dbotthepony.kstarbound.world.CHUNK_SIZE
import ru.dbotthepony.kstarbound.world.Chunk
import ru.dbotthepony.kstarbound.world.ChunkPos
import ru.dbotthepony.kstarbound.world.api.ImmutableCell
import ru.dbotthepony.kstarbound.world.api.MutableCell
import java.io.DataInputStream
import java.io.DataOutputStream

class ChunkCellsPacket(val pos: ChunkPos, val data: List<ImmutableCell>) : IClientPacket {
	constructor(stream: DataInputStream, isLegacy: Boolean) : this(stream.readChunkPos(), stream.readCollection { MutableCell().readLegacy(stream).immutable() })
	constructor(chunk: Chunk<*, *>) : this(chunk.pos, ArrayList<ImmutableCell>(CHUNK_SIZE * CHUNK_SIZE).also {
		for (x in 0 until CHUNK_SIZE) {
			for (y in 0 until CHUNK_SIZE) {
				it.add(chunk.getCell(x, y).immutable())
			}
		}
	})

	override fun write(stream: DataOutputStream, isLegacy: Boolean) {
		stream.writeStruct2i(pos)
		stream.writeCollection(data) { it.write(stream) }
	}

	override fun play(connection: ClientConnection) {
		connection.client.mailbox.execute {
			val chunk = connection.client.world?.chunkMap?.compute(pos.x, pos.y) ?: return@execute
			val itr = data.iterator()

			for (x in 0 until CHUNK_SIZE) {
				for (y in 0 until CHUNK_SIZE) {
					chunk.setCell(x, y, itr.next())
				}
			}
		}
	}
}
