package net.minecraft.client.resources.model;

import net.minecraft.client.renderer.texture.TextureAtlas;
import net.minecraft.world.level.material.FluidState;
import net.minecraft.util.profiling.ProfilerFiller;
import net.minecraft.server.packs.resources.ResourceManager;
import net.minecraft.world.level.block.state.BlockState;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
import net.minecraft.client.color.block.BlockColors;
import net.minecraft.client.renderer.texture.TextureManager;
import net.minecraft.client.renderer.block.BlockModelShaper;
import javax.annotation.Nullable;
import net.minecraft.client.renderer.texture.AtlasSet;
import net.minecraft.resources.ResourceLocation;
import java.util.Map;
import net.minecraft.server.packs.resources.SimplePreparableReloadListener;

public class ModelManager extends SimplePreparableReloadListener<ModelBakery> implements AutoCloseable {
    private Map<ResourceLocation, BakedModel> bakedRegistry;
    @Nullable
    private AtlasSet atlases;
    private final BlockModelShaper blockModelShaper;
    private final TextureManager textureManager;
    private final BlockColors blockColors;
    private int maxMipmapLevels;
    private BakedModel missingModel;
    private Object2IntMap<BlockState> modelGroups;
    
    public ModelManager(final TextureManager elw, final BlockColors dmn, final int integer) {
        this.textureManager = elw;
        this.blockColors = dmn;
        this.maxMipmapLevels = integer;
        this.blockModelShaper = new BlockModelShaper(this);
    }
    
    public BakedModel getModel(final ModelResourceLocation enn) {
        return this.bakedRegistry.getOrDefault(enn, this.missingModel);
    }
    
    public BakedModel getMissingModel() {
        return this.missingModel;
    }
    
    public BlockModelShaper getBlockModelShaper() {
        return this.blockModelShaper;
    }
    
    @Override
    protected ModelBakery prepare(final ResourceManager abc, final ProfilerFiller ami) {
        ami.startTick();
        final ModelBakery enl4 = new ModelBakery(abc, this.blockColors, ami, this.maxMipmapLevels);
        ami.endTick();
        return enl4;
    }
    
    @Override
    protected void apply(final ModelBakery enl, final ResourceManager abc, final ProfilerFiller ami) {
        ami.startTick();
        ami.push("upload");
        if (this.atlases != null) {
            this.atlases.close();
        }
        this.atlases = enl.uploadTextures(this.textureManager, ami);
        this.bakedRegistry = enl.getBakedTopLevelModels();
        this.modelGroups = enl.getModelGroups();
        this.missingModel = this.bakedRegistry.get(ModelBakery.MISSING_MODEL_LOCATION);
        ami.popPush("cache");
        this.blockModelShaper.rebuildCache();
        ami.pop();
        ami.endTick();
    }
    
    public boolean requiresRender(final BlockState cfj1, final BlockState cfj2) {
        if (cfj1 == cfj2) {
            return false;
        }
        final int integer4 = this.modelGroups.getInt(cfj1);
        if (integer4 != -1) {
            final int integer5 = this.modelGroups.getInt(cfj2);
            if (integer4 == integer5) {
                final FluidState cxa6 = cfj1.getFluidState();
                final FluidState cxa7 = cfj2.getFluidState();
                return cxa6 != cxa7;
            }
        }
        return true;
    }
    
    public TextureAtlas getAtlas(final ResourceLocation uh) {
        return this.atlases.getAtlas(uh);
    }
    
    @Override
    public void close() {
        if (this.atlases != null) {
            this.atlases.close();
        }
    }
    
    public void updateMaxMipLevel(final int integer) {
        this.maxMipmapLevels = integer;
    }
}
