/*
 * Copyright (c) 2018 modmuss50 and Gigabit101
 *
 *
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 *
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 *
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

package reborncore.common.network;

import net.minecraft.network.PacketBuffer;
import net.minecraft.util.math.BlockPos;

import java.math.BigInteger;
import java.util.Arrays;
import java.util.Objects;

public enum ObjectBufferUtils {

	STRING(String.class, (string, buffer) -> {
		buffer.writeInt(string.length());
		buffer.writeString(string);
	}, buffer -> {
		return buffer.readString(buffer.readInt());
	}),
	INT(Integer.class, (value, buffer) -> {
		buffer.writeInt(value);
	}, PacketBuffer::readInt),
	LONG(Long.class, (pos, buffer) -> {
		buffer.writeLong(pos);
	}, ExtendedPacketBuffer::readLong),
	BLOCK_POS(BlockPos.class, (pos, buffer) -> {
		buffer.writeBlockPos(pos);
	}, PacketBuffer::readBlockPos),
	BIG_INT(BigInteger.class, (pos, buffer) -> {
		buffer.writeBigInt(pos);
	}, ExtendedPacketBuffer::readBigInt);
	Class clazz;
	ObjectWriter writer;
	ObjectReader reader;

	<T> ObjectBufferUtils(Class<T> clazz, ObjectWriter<T> writer, ObjectReader<T> reader) {
		this.clazz = clazz;
		this.writer = writer;
		this.reader = reader;
	}

	public static void writeObject(Object object, ExtendedPacketBuffer buffer){
		ObjectBufferUtils utils = Arrays.stream(values()).filter(objectBufferUtils -> objectBufferUtils.clazz == object.getClass()).findFirst().orElse(null);
		Objects.requireNonNull(utils, "No support found for " + object.getClass());
		buffer.writeInt(utils.ordinal());
		utils.writer.write(object, buffer);
	}

	public static Object readObject(ExtendedPacketBuffer buffer){
		ObjectBufferUtils utils = values()[buffer.readInt()];
		Objects.requireNonNull(utils, "Could not find reader");
		return utils.reader.read(buffer);
	}

	private interface ObjectWriter<T> {
		void write(T object, ExtendedPacketBuffer buffer);
	}

	private interface ObjectReader<T> {
		T read(ExtendedPacketBuffer buffer);
	}

}

@@ -1554,16 +1554,17 @@
 );%0A%09%7D),%0A
+%0A
 %09INT(Int
@@ -1650,16 +1650,17 @@
 adInt),%0A
+%0A
 %09LONG(Lo
@@ -1750,16 +1750,229 @@
 dLong),%0A
+%0A%09DOUBLE(Double.class, (pos, buffer) -%3E %7B%0A%09%09buffer.writeDouble(pos);%0A%09%7D, ExtendedPacketBuffer::readDouble),%0A%0A%09FLOAT(Float.class, (pos, buffer) -%3E %7B%0A%09%09buffer.writeFloat(pos);%0A%09%7D, ExtendedPacketBuffer::readFloat),%0A%0A
 %09BLOCK_P
@@ -2071,16 +2071,17 @@
 ckPos),%0A
+%0A
 %09BIG_INT
@@ -2137,32 +2137,32 @@
 iteBigInt(pos);%0A
-
 %09%7D, ExtendedPack
@@ -2184,16 +2184,17 @@
 igInt);%0A
+%0A
 %09Class c

Add more support to the buffer utils