package net.minecraft.network.syncher;

import net.minecraft.world.entity.npc.VillagerProfession;
import net.minecraft.world.entity.npc.VillagerType;
import net.minecraft.core.particles.ParticleType;
import net.minecraft.core.Registry;
import net.minecraft.world.level.block.Block;
import net.minecraft.network.FriendlyByteBuf;
import javax.annotation.Nullable;
import net.minecraft.world.entity.Pose;
import java.util.OptionalInt;
import net.minecraft.world.entity.npc.VillagerData;
import net.minecraft.nbt.CompoundTag;
import java.util.UUID;
import net.minecraft.core.Direction;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Rotations;
import net.minecraft.core.particles.ParticleOptions;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.item.ItemStack;
import java.util.Optional;
import net.minecraft.network.chat.Component;
import net.minecraft.util.CrudeIncrementalIntIdentityHashBiMap;

public class EntityDataSerializers {
    private static final CrudeIncrementalIntIdentityHashBiMap<EntityDataSerializer<?>> SERIALIZERS;
    public static final EntityDataSerializer<Byte> BYTE;
    public static final EntityDataSerializer<Integer> INT;
    public static final EntityDataSerializer<Float> FLOAT;
    public static final EntityDataSerializer<String> STRING;
    public static final EntityDataSerializer<Component> COMPONENT;
    public static final EntityDataSerializer<Optional<Component>> OPTIONAL_COMPONENT;
    public static final EntityDataSerializer<ItemStack> ITEM_STACK;
    public static final EntityDataSerializer<Optional<BlockState>> BLOCK_STATE;
    public static final EntityDataSerializer<Boolean> BOOLEAN;
    public static final EntityDataSerializer<ParticleOptions> PARTICLE;
    public static final EntityDataSerializer<Rotations> ROTATIONS;
    public static final EntityDataSerializer<BlockPos> BLOCK_POS;
    public static final EntityDataSerializer<Optional<BlockPos>> OPTIONAL_BLOCK_POS;
    public static final EntityDataSerializer<Direction> DIRECTION;
    public static final EntityDataSerializer<Optional<UUID>> OPTIONAL_UUID;
    public static final EntityDataSerializer<CompoundTag> COMPOUND_TAG;
    public static final EntityDataSerializer<VillagerData> VILLAGER_DATA;
    public static final EntityDataSerializer<OptionalInt> OPTIONAL_UNSIGNED_INT;
    public static final EntityDataSerializer<Pose> POSE;
    
    public static void registerSerializer(final EntityDataSerializer<?> tr) {
        EntityDataSerializers.SERIALIZERS.add(tr);
    }
    
    @Nullable
    public static EntityDataSerializer<?> getSerializer(final int integer) {
        return EntityDataSerializers.SERIALIZERS.byId(integer);
    }
    
    public static int getSerializedId(final EntityDataSerializer<?> tr) {
        return EntityDataSerializers.SERIALIZERS.getId(tr);
    }
    
    static {
        SERIALIZERS = new CrudeIncrementalIntIdentityHashBiMap<EntityDataSerializer<?>>(16);
        BYTE = new EntityDataSerializer<Byte>() {
            @Override
            public void write(final FriendlyByteBuf mg, final Byte byte2) {
                mg.writeByte(byte2);
            }
            
            @Override
            public Byte read(final FriendlyByteBuf mg) {
                return mg.readByte();
            }
            
            @Override
            public Byte copy(final Byte byte1) {
                return byte1;
            }
        };
        INT = new EntityDataSerializer<Integer>() {
            @Override
            public void write(final FriendlyByteBuf mg, final Integer integer) {
                mg.writeVarInt(integer);
            }
            
            @Override
            public Integer read(final FriendlyByteBuf mg) {
                return mg.readVarInt();
            }
            
            @Override
            public Integer copy(final Integer integer) {
                return integer;
            }
        };
        FLOAT = new EntityDataSerializer<Float>() {
            @Override
            public void write(final FriendlyByteBuf mg, final Float float2) {
                mg.writeFloat(float2);
            }
            
            @Override
            public Float read(final FriendlyByteBuf mg) {
                return mg.readFloat();
            }
            
            @Override
            public Float copy(final Float float1) {
                return float1;
            }
        };
        STRING = new EntityDataSerializer<String>() {
            @Override
            public void write(final FriendlyByteBuf mg, final String string) {
                mg.writeUtf(string);
            }
            
            @Override
            public String read(final FriendlyByteBuf mg) {
                return mg.readUtf(32767);
            }
            
            @Override
            public String copy(final String string) {
                return string;
            }
        };
        COMPONENT = new EntityDataSerializer<Component>() {
            @Override
            public void write(final FriendlyByteBuf mg, final Component mr) {
                mg.writeComponent(mr);
            }
            
            @Override
            public Component read(final FriendlyByteBuf mg) {
                return mg.readComponent();
            }
            
            @Override
            public Component copy(final Component mr) {
                return mr;
            }
        };
        OPTIONAL_COMPONENT = new EntityDataSerializer<Optional<Component>>() {
            @Override
            public void write(final FriendlyByteBuf mg, final Optional<Component> optional) {
                if (optional.isPresent()) {
                    mg.writeBoolean(true);
                    mg.writeComponent(optional.get());
                }
                else {
                    mg.writeBoolean(false);
                }
            }
            
            @Override
            public Optional<Component> read(final FriendlyByteBuf mg) {
                return mg.readBoolean() ? Optional.<Component>of(mg.readComponent()) : Optional.<Component>empty();
            }
            
            @Override
            public Optional<Component> copy(final Optional<Component> optional) {
                return optional;
            }
        };
        ITEM_STACK = new EntityDataSerializer<ItemStack>() {
            @Override
            public void write(final FriendlyByteBuf mg, final ItemStack bki) {
                mg.writeItem(bki);
            }
            
            @Override
            public ItemStack read(final FriendlyByteBuf mg) {
                return mg.readItem();
            }
            
            @Override
            public ItemStack copy(final ItemStack bki) {
                return bki.copy();
            }
        };
        BLOCK_STATE = new EntityDataSerializer<Optional<BlockState>>() {
            @Override
            public void write(final FriendlyByteBuf mg, final Optional<BlockState> optional) {
                if (optional.isPresent()) {
                    mg.writeVarInt(Block.getId(optional.get()));
                }
                else {
                    mg.writeVarInt(0);
                }
            }
            
            @Override
            public Optional<BlockState> read(final FriendlyByteBuf mg) {
                final int integer3 = mg.readVarInt();
                if (integer3 == 0) {
                    return Optional.<BlockState>empty();
                }
                return Optional.<BlockState>of(Block.stateById(integer3));
            }
            
            @Override
            public Optional<BlockState> copy(final Optional<BlockState> optional) {
                return optional;
            }
        };
        BOOLEAN = new EntityDataSerializer<Boolean>() {
            @Override
            public void write(final FriendlyByteBuf mg, final Boolean boolean2) {
                mg.writeBoolean(boolean2);
            }
            
            @Override
            public Boolean read(final FriendlyByteBuf mg) {
                return mg.readBoolean();
            }
            
            @Override
            public Boolean copy(final Boolean boolean1) {
                return boolean1;
            }
        };
        PARTICLE = new EntityDataSerializer<ParticleOptions>() {
            @Override
            public void write(final FriendlyByteBuf mg, final ParticleOptions hf) {
                mg.writeVarInt(Registry.PARTICLE_TYPE.getId(hf.getType()));
                hf.writeToNetwork(mg);
            }
            
            @Override
            public ParticleOptions read(final FriendlyByteBuf mg) {
                return this.<ParticleOptions>readParticle(mg, Registry.PARTICLE_TYPE.byId(mg.readVarInt()));
            }
            
            private <T extends ParticleOptions> T readParticle(final FriendlyByteBuf mg, final ParticleType<T> hg) {
                return hg.getDeserializer().fromNetwork(hg, mg);
            }
            
            @Override
            public ParticleOptions copy(final ParticleOptions hf) {
                return hf;
            }
        };
        ROTATIONS = new EntityDataSerializer<Rotations>() {
            @Override
            public void write(final FriendlyByteBuf mg, final Rotations gn) {
                mg.writeFloat(gn.getX());
                mg.writeFloat(gn.getY());
                mg.writeFloat(gn.getZ());
            }
            
            @Override
            public Rotations read(final FriendlyByteBuf mg) {
                return new Rotations(mg.readFloat(), mg.readFloat(), mg.readFloat());
            }
            
            @Override
            public Rotations copy(final Rotations gn) {
                return gn;
            }
        };
        BLOCK_POS = new EntityDataSerializer<BlockPos>() {
            @Override
            public void write(final FriendlyByteBuf mg, final BlockPos fu) {
                mg.writeBlockPos(fu);
            }
            
            @Override
            public BlockPos read(final FriendlyByteBuf mg) {
                return mg.readBlockPos();
            }
            
            @Override
            public BlockPos copy(final BlockPos fu) {
                return fu;
            }
        };
        OPTIONAL_BLOCK_POS = new EntityDataSerializer<Optional<BlockPos>>() {
            @Override
            public void write(final FriendlyByteBuf mg, final Optional<BlockPos> optional) {
                mg.writeBoolean(optional.isPresent());
                if (optional.isPresent()) {
                    mg.writeBlockPos(optional.get());
                }
            }
            
            @Override
            public Optional<BlockPos> read(final FriendlyByteBuf mg) {
                if (!mg.readBoolean()) {
                    return Optional.<BlockPos>empty();
                }
                return Optional.<BlockPos>of(mg.readBlockPos());
            }
            
            @Override
            public Optional<BlockPos> copy(final Optional<BlockPos> optional) {
                return optional;
            }
        };
        DIRECTION = new EntityDataSerializer<Direction>() {
            @Override
            public void write(final FriendlyByteBuf mg, final Direction fz) {
                mg.writeEnum(fz);
            }
            
            @Override
            public Direction read(final FriendlyByteBuf mg) {
                return mg.<Direction>readEnum(Direction.class);
            }
            
            @Override
            public Direction copy(final Direction fz) {
                return fz;
            }
        };
        OPTIONAL_UUID = new EntityDataSerializer<Optional<UUID>>() {
            @Override
            public void write(final FriendlyByteBuf mg, final Optional<UUID> optional) {
                mg.writeBoolean(optional.isPresent());
                if (optional.isPresent()) {
                    mg.writeUUID(optional.get());
                }
            }
            
            @Override
            public Optional<UUID> read(final FriendlyByteBuf mg) {
                if (!mg.readBoolean()) {
                    return Optional.<UUID>empty();
                }
                return Optional.<UUID>of(mg.readUUID());
            }
            
            @Override
            public Optional<UUID> copy(final Optional<UUID> optional) {
                return optional;
            }
        };
        COMPOUND_TAG = new EntityDataSerializer<CompoundTag>() {
            @Override
            public void write(final FriendlyByteBuf mg, final CompoundTag le) {
                mg.writeNbt(le);
            }
            
            @Override
            public CompoundTag read(final FriendlyByteBuf mg) {
                return mg.readNbt();
            }
            
            @Override
            public CompoundTag copy(final CompoundTag le) {
                return le.copy();
            }
        };
        VILLAGER_DATA = new EntityDataSerializer<VillagerData>() {
            @Override
            public void write(final FriendlyByteBuf mg, final VillagerData bdq) {
                mg.writeVarInt(Registry.VILLAGER_TYPE.getId(bdq.getType()));
                mg.writeVarInt(Registry.VILLAGER_PROFESSION.getId(bdq.getProfession()));
                mg.writeVarInt(bdq.getLevel());
            }
            
            @Override
            public VillagerData read(final FriendlyByteBuf mg) {
                return new VillagerData(Registry.VILLAGER_TYPE.byId(mg.readVarInt()), Registry.VILLAGER_PROFESSION.byId(mg.readVarInt()), mg.readVarInt());
            }
            
            @Override
            public VillagerData copy(final VillagerData bdq) {
                return bdq;
            }
        };
        OPTIONAL_UNSIGNED_INT = new EntityDataSerializer<OptionalInt>() {
            @Override
            public void write(final FriendlyByteBuf mg, final OptionalInt optionalInt) {
                mg.writeVarInt(optionalInt.orElse(-1) + 1);
            }
            
            @Override
            public OptionalInt read(final FriendlyByteBuf mg) {
                final int integer3 = mg.readVarInt();
                return (integer3 == 0) ? OptionalInt.empty() : OptionalInt.of(integer3 - 1);
            }
            
            @Override
            public OptionalInt copy(final OptionalInt optionalInt) {
                return optionalInt;
            }
        };
        POSE = new EntityDataSerializer<Pose>() {
            @Override
            public void write(final FriendlyByteBuf mg, final Pose apj) {
                mg.writeEnum(apj);
            }
            
            @Override
            public Pose read(final FriendlyByteBuf mg) {
                return mg.<Pose>readEnum(Pose.class);
            }
            
            @Override
            public Pose copy(final Pose apj) {
                return apj;
            }
        };
        registerSerializer(EntityDataSerializers.BYTE);
        registerSerializer(EntityDataSerializers.INT);
        registerSerializer(EntityDataSerializers.FLOAT);
        registerSerializer(EntityDataSerializers.STRING);
        registerSerializer(EntityDataSerializers.COMPONENT);
        registerSerializer(EntityDataSerializers.OPTIONAL_COMPONENT);
        registerSerializer(EntityDataSerializers.ITEM_STACK);
        registerSerializer(EntityDataSerializers.BOOLEAN);
        registerSerializer(EntityDataSerializers.ROTATIONS);
        registerSerializer(EntityDataSerializers.BLOCK_POS);
        registerSerializer(EntityDataSerializers.OPTIONAL_BLOCK_POS);
        registerSerializer(EntityDataSerializers.DIRECTION);
        registerSerializer(EntityDataSerializers.OPTIONAL_UUID);
        registerSerializer(EntityDataSerializers.BLOCK_STATE);
        registerSerializer(EntityDataSerializers.COMPOUND_TAG);
        registerSerializer(EntityDataSerializers.PARTICLE);
        registerSerializer(EntityDataSerializers.VILLAGER_DATA);
        registerSerializer(EntityDataSerializers.OPTIONAL_UNSIGNED_INT);
        registerSerializer(EntityDataSerializers.POSE);
    }
}
