package net.minecraft.world.entity.vehicle;

import net.minecraft.world.entity.player.Inventory;
import net.minecraft.world.level.storage.loot.LootTable;
import net.minecraft.world.level.storage.loot.parameters.LootContextParamSets;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.storage.loot.parameters.LootContextParams;
import net.minecraft.world.level.storage.loot.LootContext;
import net.minecraft.advancements.CriteriaTriggers;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.inventory.AbstractContainerMenu;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.InteractionHand;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.server.level.ServerLevel;
import java.util.List;
import net.minecraft.world.ContainerHelper;
import net.minecraft.world.entity.player.Player;
import java.util.Iterator;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.Containers;
import net.minecraft.world.level.GameRules;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.level.Level;
import net.minecraft.world.entity.EntityType;
import javax.annotation.Nullable;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.ItemStack;
import net.minecraft.core.NonNullList;
import net.minecraft.world.MenuProvider;
import net.minecraft.world.Container;

public abstract class AbstractMinecartContainer extends AbstractMinecart implements Container, MenuProvider {
    private NonNullList<ItemStack> itemStacks;
    private boolean dropEquipment;
    @Nullable
    private ResourceLocation lootTable;
    private long lootTableSeed;
    
    protected AbstractMinecartContainer(final EntityType<?> aoq, final Level bqb) {
        super(aoq, bqb);
        this.itemStacks = NonNullList.<ItemStack>withSize(36, ItemStack.EMPTY);
        this.dropEquipment = true;
    }
    
    protected AbstractMinecartContainer(final EntityType<?> aoq, final double double2, final double double3, final double double4, final Level bqb) {
        super(aoq, bqb, double2, double3, double4);
        this.itemStacks = NonNullList.<ItemStack>withSize(36, ItemStack.EMPTY);
        this.dropEquipment = true;
    }
    
    @Override
    public void destroy(final DamageSource anw) {
        super.destroy(anw);
        if (this.level.getGameRules().getBoolean(GameRules.RULE_DOENTITYDROPS)) {
            Containers.dropContents(this.level, this, this);
        }
    }
    
    @Override
    public boolean isEmpty() {
        for (final ItemStack bki3 : this.itemStacks) {
            if (!bki3.isEmpty()) {
                return false;
            }
        }
        return true;
    }
    
    @Override
    public ItemStack getItem(final int integer) {
        this.unpackLootTable(null);
        return this.itemStacks.get(integer);
    }
    
    @Override
    public ItemStack removeItem(final int integer1, final int integer2) {
        this.unpackLootTable(null);
        return ContainerHelper.removeItem(this.itemStacks, integer1, integer2);
    }
    
    @Override
    public ItemStack removeItemNoUpdate(final int integer) {
        this.unpackLootTable(null);
        final ItemStack bki3 = this.itemStacks.get(integer);
        if (bki3.isEmpty()) {
            return ItemStack.EMPTY;
        }
        this.itemStacks.set(integer, ItemStack.EMPTY);
        return bki3;
    }
    
    @Override
    public void setItem(final int integer, final ItemStack bki) {
        this.unpackLootTable(null);
        this.itemStacks.set(integer, bki);
        if (!bki.isEmpty() && bki.getCount() > this.getMaxStackSize()) {
            bki.setCount(this.getMaxStackSize());
        }
    }
    
    @Override
    public boolean setSlot(final int integer, final ItemStack bki) {
        if (integer >= 0 && integer < this.getContainerSize()) {
            this.setItem(integer, bki);
            return true;
        }
        return false;
    }
    
    @Override
    public void setChanged() {
    }
    
    @Override
    public boolean stillValid(final Player bec) {
        return !this.removed && bec.distanceToSqr(this) <= 64.0;
    }
    
    @Nullable
    @Override
    public Entity changeDimension(final ServerLevel zd) {
        this.dropEquipment = false;
        return super.changeDimension(zd);
    }
    
    @Override
    public void remove() {
        if (!this.level.isClientSide && this.dropEquipment) {
            Containers.dropContents(this.level, this, this);
        }
        super.remove();
    }
    
    @Override
    protected void addAdditionalSaveData(final CompoundTag le) {
        super.addAdditionalSaveData(le);
        if (this.lootTable != null) {
            le.putString("LootTable", this.lootTable.toString());
            if (this.lootTableSeed != 0L) {
                le.putLong("LootTableSeed", this.lootTableSeed);
            }
        }
        else {
            ContainerHelper.saveAllItems(le, this.itemStacks);
        }
    }
    
    @Override
    protected void readAdditionalSaveData(final CompoundTag le) {
        super.readAdditionalSaveData(le);
        this.itemStacks = NonNullList.<ItemStack>withSize(this.getContainerSize(), ItemStack.EMPTY);
        if (le.contains("LootTable", 8)) {
            this.lootTable = new ResourceLocation(le.getString("LootTable"));
            this.lootTableSeed = le.getLong("LootTableSeed");
        }
        else {
            ContainerHelper.loadAllItems(le, this.itemStacks);
        }
    }
    
    @Override
    public InteractionResult interact(final Player bec, final InteractionHand anf) {
        bec.openMenu(this);
        return InteractionResult.sidedSuccess(this.level.isClientSide);
    }
    
    @Override
    protected void applyNaturalSlowdown() {
        float float2 = 0.98f;
        if (this.lootTable == null) {
            final int integer3 = 15 - AbstractContainerMenu.getRedstoneSignalFromContainer(this);
            float2 += integer3 * 0.001f;
        }
        this.setDeltaMovement(this.getDeltaMovement().multiply(float2, 0.0, float2));
    }
    
    public void unpackLootTable(@Nullable final Player bec) {
        if (this.lootTable != null && this.level.getServer() != null) {
            final LootTable daw3 = this.level.getServer().getLootTables().get(this.lootTable);
            if (bec instanceof ServerPlayer) {
                CriteriaTriggers.GENERATE_LOOT.trigger((ServerPlayer)bec, this.lootTable);
            }
            this.lootTable = null;
            final LootContext.Builder a4 = new LootContext.Builder((ServerLevel)this.level).<BlockPos>withParameter(LootContextParams.BLOCK_POS, this.blockPosition()).withOptionalRandomSeed(this.lootTableSeed);
            if (bec != null) {
                a4.withLuck(bec.getLuck()).<Entity>withParameter(LootContextParams.THIS_ENTITY, bec);
            }
            daw3.fill(this, a4.create(LootContextParamSets.CHEST));
        }
    }
    
    @Override
    public void clearContent() {
        this.unpackLootTable(null);
        this.itemStacks.clear();
    }
    
    public void setLootTable(final ResourceLocation uh, final long long2) {
        this.lootTable = uh;
        this.lootTableSeed = long2;
    }
    
    @Nullable
    @Override
    public AbstractContainerMenu createMenu(final int integer, final Inventory beb, final Player bec) {
        if (this.lootTable == null || !bec.isSpectator()) {
            this.unpackLootTable(beb.player);
            return this.createMenu(integer, beb);
        }
        return null;
    }
    
    protected abstract AbstractContainerMenu createMenu(final int integer, final Inventory beb);
}
