package ru.dbotthepony.kstarbound.network.packets.clientbound

import ru.dbotthepony.kommons.arrays.Object2DArray
import ru.dbotthepony.kommons.io.readSignedVarInt
import ru.dbotthepony.kommons.io.readVarInt
import ru.dbotthepony.kommons.io.readVector2i
import ru.dbotthepony.kommons.io.writeSignedVarInt
import ru.dbotthepony.kommons.io.writeStruct2i
import ru.dbotthepony.kommons.io.writeVarInt
import ru.dbotthepony.kommons.vector.Vector2i
import ru.dbotthepony.kstarbound.client.ClientConnection
import ru.dbotthepony.kstarbound.network.IClientPacket
import ru.dbotthepony.kstarbound.network.LegacyNetworkCellState
import ru.dbotthepony.kstarbound.server.world.ServerChunk
import ru.dbotthepony.kstarbound.world.Chunk
import java.io.DataInputStream
import java.io.DataOutputStream

class LegacyTileUpdatePacket(val position: Vector2i, val tile: LegacyNetworkCellState) : IClientPacket {
	override fun write(stream: DataOutputStream, isLegacy: Boolean) {
		stream.writeSignedVarInt(position.x)
		stream.writeSignedVarInt(position.y)
		tile.write(stream)
	}

	override fun play(connection: ClientConnection) {
		TODO("Not yet implemented")
	}

	companion object {
		fun read(stream: DataInputStream, isLegacy: Boolean): LegacyTileUpdatePacket {
			check(isLegacy) { "Using legacy packet in native protocol" }
			return LegacyTileUpdatePacket(Vector2i(stream.readSignedVarInt(), stream.readSignedVarInt()), LegacyNetworkCellState.read(stream))
		}
	}
}

class LegacyTileArrayUpdatePacket(val origin: Vector2i, val data: Object2DArray<LegacyNetworkCellState>) : IClientPacket {
	constructor(chunk: ServerChunk) : this(chunk.pos.tile, chunk.legacyNetworkCells())

	override fun write(stream: DataOutputStream, isLegacy: Boolean) {
		stream.writeSignedVarInt(origin.x)
		stream.writeSignedVarInt(origin.y)
		stream.writeVarInt(data.columns)
		stream.writeVarInt(data.rows)

		for (y in data.rowIndices) {
			for (x in data.columnIndices) {
				data[x, y].write(stream)
			}
		}
	}

	override fun play(connection: ClientConnection) {
		TODO("Not yet implemented")
	}

	companion object {
		fun read(stream: DataInputStream, isLegacy: Boolean): LegacyTileArrayUpdatePacket {
			check(isLegacy) { "Using legacy packet in native protocol" }
			val origin = Vector2i(stream.readSignedVarInt(), stream.readSignedVarInt())

			val columns = stream.readVarInt()
			val rows = stream.readVarInt()

			val data = Object2DArray.nulls<LegacyNetworkCellState>(columns, rows)

			for (y in data.rowIndices) {
				for (x in data.columnIndices) {
					data[x, y] = LegacyNetworkCellState.read(stream)
				}
			}

			return LegacyTileArrayUpdatePacket(origin, data as Object2DArray<LegacyNetworkCellState>)
		}
	}
}
