package net.minecraft.world.entity.animal.horse;

import net.minecraft.world.entity.Entity;
import net.minecraft.network.syncher.SynchedEntityData;
import net.minecraft.network.syncher.EntityDataSerializers;
import net.minecraft.world.entity.SpawnGroupData;
import net.minecraft.world.entity.MobSpawnType;
import net.minecraft.world.DifficultyInstance;
import net.minecraft.world.level.LevelAccessor;
import net.minecraft.Util;
import net.minecraft.world.entity.AgableMob;
import net.minecraft.world.entity.animal.Animal;
import net.minecraft.world.item.Items;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.damagesource.DamageSource;
import javax.annotation.Nullable;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.world.level.block.SoundType;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.world.Container;
import net.minecraft.world.entity.ai.attributes.AttributeModifier;
import net.minecraft.world.item.HorseArmorItem;
import net.minecraft.world.entity.EquipmentSlot;
import net.minecraft.world.item.ItemStack;
import net.minecraft.nbt.Tag;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.entity.ai.attributes.Attributes;
import net.minecraft.world.level.Level;
import net.minecraft.world.entity.EntityType;
import net.minecraft.network.syncher.EntityDataAccessor;
import java.util.UUID;

public class Horse extends AbstractHorse {
    private static final UUID ARMOR_MODIFIER_UUID;
    private static final EntityDataAccessor<Integer> DATA_ID_TYPE_VARIANT;
    
    public Horse(final EntityType<? extends Horse> aoq, final Level bqb) {
        super(aoq, bqb);
    }
    
    @Override
    protected void randomizeAttributes() {
        this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.generateRandomMaxHealth());
        this.getAttribute(Attributes.MOVEMENT_SPEED).setBaseValue(this.generateRandomSpeed());
        this.getAttribute(Attributes.JUMP_STRENGTH).setBaseValue(this.generateRandomJumpStrength());
    }
    
    @Override
    protected void defineSynchedData() {
        super.defineSynchedData();
        this.entityData.<Integer>define(Horse.DATA_ID_TYPE_VARIANT, 0);
    }
    
    @Override
    public void addAdditionalSaveData(final CompoundTag le) {
        super.addAdditionalSaveData(le);
        le.putInt("Variant", this.getTypeVariant());
        if (!this.inventory.getItem(1).isEmpty()) {
            le.put("ArmorItem", this.inventory.getItem(1).save(new CompoundTag()));
        }
    }
    
    public ItemStack getArmor() {
        return this.getItemBySlot(EquipmentSlot.CHEST);
    }
    
    private void setArmor(final ItemStack bki) {
        this.setItemSlot(EquipmentSlot.CHEST, bki);
        this.setDropChance(EquipmentSlot.CHEST, 0.0f);
    }
    
    @Override
    public void readAdditionalSaveData(final CompoundTag le) {
        super.readAdditionalSaveData(le);
        this.setTypeVariant(le.getInt("Variant"));
        if (le.contains("ArmorItem", 10)) {
            final ItemStack bki3 = ItemStack.of(le.getCompound("ArmorItem"));
            if (!bki3.isEmpty() && this.isArmor(bki3)) {
                this.inventory.setItem(1, bki3);
            }
        }
        this.updateContainerEquipment();
    }
    
    private void setTypeVariant(final int integer) {
        this.entityData.<Integer>set(Horse.DATA_ID_TYPE_VARIANT, integer);
    }
    
    private int getTypeVariant() {
        return this.entityData.<Integer>get(Horse.DATA_ID_TYPE_VARIANT);
    }
    
    private void setVariantAndMarkings(final Variant azv, final Markings azq) {
        this.setTypeVariant((azv.getId() & 0xFF) | (azq.getId() << 8 & 0xFF00));
    }
    
    public Variant getVariant() {
        return Variant.byId(this.getTypeVariant() & 0xFF);
    }
    
    public Markings getMarkings() {
        return Markings.byId((this.getTypeVariant() & 0xFF00) >> 8);
    }
    
    @Override
    protected void updateContainerEquipment() {
        if (this.level.isClientSide) {
            return;
        }
        super.updateContainerEquipment();
        this.setArmorEquipment(this.inventory.getItem(1));
        this.setDropChance(EquipmentSlot.CHEST, 0.0f);
    }
    
    private void setArmorEquipment(final ItemStack bki) {
        this.setArmor(bki);
        if (!this.level.isClientSide) {
            this.getAttribute(Attributes.ARMOR).removeModifier(Horse.ARMOR_MODIFIER_UUID);
            if (this.isArmor(bki)) {
                final int integer3 = ((HorseArmorItem)bki.getItem()).getProtection();
                if (integer3 != 0) {
                    this.getAttribute(Attributes.ARMOR).addTransientModifier(new AttributeModifier(Horse.ARMOR_MODIFIER_UUID, "Horse armor bonus", integer3, AttributeModifier.Operation.ADDITION));
                }
            }
        }
    }
    
    @Override
    public void containerChanged(final Container amz) {
        final ItemStack bki3 = this.getArmor();
        super.containerChanged(amz);
        final ItemStack bki4 = this.getArmor();
        if (this.tickCount > 20 && this.isArmor(bki4) && bki3 != bki4) {
            this.playSound(SoundEvents.HORSE_ARMOR, 0.5f, 1.0f);
        }
    }
    
    @Override
    protected void playGallopSound(final SoundType cbh) {
        super.playGallopSound(cbh);
        if (this.random.nextInt(10) == 0) {
            this.playSound(SoundEvents.HORSE_BREATHE, cbh.getVolume() * 0.6f, cbh.getPitch());
        }
    }
    
    @Override
    protected SoundEvent getAmbientSound() {
        super.getAmbientSound();
        return SoundEvents.HORSE_AMBIENT;
    }
    
    @Override
    protected SoundEvent getDeathSound() {
        super.getDeathSound();
        return SoundEvents.HORSE_DEATH;
    }
    
    @Nullable
    @Override
    protected SoundEvent getEatingSound() {
        return SoundEvents.HORSE_EAT;
    }
    
    @Override
    protected SoundEvent getHurtSound(final DamageSource anw) {
        super.getHurtSound(anw);
        return SoundEvents.HORSE_HURT;
    }
    
    @Override
    protected SoundEvent getAngrySound() {
        super.getAngrySound();
        return SoundEvents.HORSE_ANGRY;
    }
    
    @Override
    public InteractionResult mobInteract(final Player bec, final InteractionHand anf) {
        final ItemStack bki4 = bec.getItemInHand(anf);
        if (!this.isBaby()) {
            if (this.isTamed() && bec.isSecondaryUseActive()) {
                this.openInventory(bec);
                return InteractionResult.sidedSuccess(this.level.isClientSide);
            }
            if (this.isVehicle()) {
                return super.mobInteract(bec, anf);
            }
        }
        if (!bki4.isEmpty()) {
            if (this.isFood(bki4)) {
                return this.fedFood(bec, bki4);
            }
            final InteractionResult ang5 = bki4.interactLivingEntity(bec, this, anf);
            if (ang5.consumesAction()) {
                return ang5;
            }
            if (!this.isTamed()) {
                this.makeMad();
                return InteractionResult.sidedSuccess(this.level.isClientSide);
            }
            final boolean boolean6 = !this.isBaby() && !this.isSaddled() && bki4.getItem() == Items.SADDLE;
            if (this.isArmor(bki4) || boolean6) {
                this.openInventory(bec);
                return InteractionResult.sidedSuccess(this.level.isClientSide);
            }
        }
        if (this.isBaby()) {
            return super.mobInteract(bec, anf);
        }
        this.doPlayerRide(bec);
        return InteractionResult.sidedSuccess(this.level.isClientSide);
    }
    
    @Override
    public boolean canMate(final Animal ayk) {
        return ayk != this && (ayk instanceof Donkey || ayk instanceof Horse) && this.canParent() && ((AbstractHorse)ayk).canParent();
    }
    
    @Override
    public AgableMob getBreedOffspring(final AgableMob aok) {
        AbstractHorse azm3;
        if (aok instanceof Donkey) {
            azm3 = EntityType.MULE.create(this.level);
        }
        else {
            final Horse azo4 = (Horse)aok;
            azm3 = EntityType.HORSE.create(this.level);
            final int integer6 = this.random.nextInt(9);
            Variant azv5;
            if (integer6 < 4) {
                azv5 = this.getVariant();
            }
            else if (integer6 < 8) {
                azv5 = azo4.getVariant();
            }
            else {
                azv5 = Util.<Variant>getRandom(Variant.values(), this.random);
            }
            final int integer7 = this.random.nextInt(5);
            Markings azq7;
            if (integer7 < 2) {
                azq7 = this.getMarkings();
            }
            else if (integer7 < 4) {
                azq7 = azo4.getMarkings();
            }
            else {
                azq7 = Util.<Markings>getRandom(Markings.values(), this.random);
            }
            ((Horse)azm3).setVariantAndMarkings(azv5, azq7);
        }
        this.setOffspringAttributes(aok, azm3);
        return azm3;
    }
    
    @Override
    public boolean canWearArmor() {
        return true;
    }
    
    @Override
    public boolean isArmor(final ItemStack bki) {
        return bki.getItem() instanceof HorseArmorItem;
    }
    
    @Nullable
    @Override
    public SpawnGroupData finalizeSpawn(final LevelAccessor bqc, final DifficultyInstance ane, final MobSpawnType apb, @Nullable SpawnGroupData apo, @Nullable final CompoundTag le) {
        Variant azv7;
        if (apo instanceof HorseGroupData) {
            azv7 = ((HorseGroupData)apo).variant;
        }
        else {
            azv7 = Util.<Variant>getRandom(Variant.values(), this.random);
            apo = new HorseGroupData(azv7);
        }
        this.setVariantAndMarkings(azv7, Util.<Markings>getRandom(Markings.values(), this.random));
        return super.finalizeSpawn(bqc, ane, apb, apo, le);
    }
    
    static {
        ARMOR_MODIFIER_UUID = UUID.fromString("556E1665-8B10-40C8-8F9D-CF9B1667F295");
        DATA_ID_TYPE_VARIANT = SynchedEntityData.<Integer>defineId(Horse.class, EntityDataSerializers.INT);
    }
    
    public static class HorseGroupData extends AgableMobGroupData {
        public final Variant variant;
        
        public HorseGroupData(final Variant azv) {
            this.variant = azv;
        }
    }
}
