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