// 
// Decompiled by Procyon v0.6.0
// 

package com.hypixel.hytale.builtin.hytalegenerator.material;

import javax.annotation.Nullable;
import com.hypixel.hytale.server.core.prefab.PrefabRotation;
import com.hypixel.hytale.server.core.asset.type.blocktype.config.Rotation;
import com.hypixel.hytale.server.core.universe.world.storage.ChunkStore;
import com.hypixel.hytale.component.Holder;
import com.hypixel.hytale.server.core.asset.type.blocktype.config.BlockType;
import com.hypixel.hytale.builtin.hytalegenerator.LoggerUtil;
import javax.annotation.Nonnull;
import com.hypixel.hytale.server.core.asset.type.fluid.Fluid;
import java.util.HashMap;
import java.util.Map;

public class MaterialCache
{
    private final Map<Integer, SolidMaterial> hashToSolidMap;
    private final Map<Integer, FluidMaterial> hashToFluidMap;
    private final Map<Integer, Material> hashToMaterialMap;
    public final SolidMaterial EMPTY_AIR;
    public final SolidMaterial ROCK_STONE;
    public final SolidMaterial SOIL_GRASS;
    public final SolidMaterial SOIL_DIRT;
    public final SolidMaterial SOIL_MUD;
    public final SolidMaterial SOIL_NEEDLES;
    public final SolidMaterial SOIL_GRAVEL;
    public final SolidMaterial ROCK_QUARTZITE;
    public final SolidMaterial ROCK_MARBLE;
    public final SolidMaterial ROCK_SHALE;
    public final SolidMaterial FLUID_WATER;
    public final SolidMaterial BEDROCK;
    public final FluidMaterial UNKNOWN_FLUID;
    public final FluidMaterial EMPTY_FLUID;
    public final Material EMPTY;
    
    public MaterialCache() {
        this.hashToSolidMap = new HashMap<Integer, SolidMaterial>();
        this.hashToFluidMap = new HashMap<Integer, FluidMaterial>();
        this.hashToMaterialMap = new HashMap<Integer, Material>();
        this.EMPTY_AIR = this.getSolidMaterial("Empty_Air");
        this.ROCK_STONE = this.getSolidMaterial("Rock_Stone");
        this.SOIL_GRASS = this.getSolidMaterial("Soil_Grass");
        this.SOIL_DIRT = this.getSolidMaterial("Soil_Dirt");
        this.SOIL_MUD = this.getSolidMaterial("Soil_Mud");
        this.SOIL_NEEDLES = this.getSolidMaterial("Soil_Needles");
        this.SOIL_GRAVEL = this.getSolidMaterial("Soil_Gravel");
        this.ROCK_QUARTZITE = this.getSolidMaterial("Rock_Quartzite");
        this.ROCK_MARBLE = this.getSolidMaterial("Rock_Marble");
        this.ROCK_SHALE = this.getSolidMaterial("Rock_Shale");
        this.FLUID_WATER = this.getSolidMaterial("Fluid_Water");
        this.BEDROCK = this.getSolidMaterial("Rock_Volcanic");
        this.UNKNOWN_FLUID = this.getFluidMaterial(Fluid.UNKNOWN.getId());
        this.EMPTY_FLUID = this.getFluidMaterial(Fluid.EMPTY.getId());
        this.EMPTY = this.getMaterial(this.EMPTY_AIR, this.EMPTY_FLUID);
    }
    
    @Nonnull
    public Material getMaterial(@Nonnull final SolidMaterial solidMaterial, @Nonnull final FluidMaterial fluidMaterial) {
        final int hash = Material.hashCode(solidMaterial, fluidMaterial);
        Material material = this.hashToMaterialMap.get(hash);
        if (material == null) {
            material = new Material(solidMaterial, fluidMaterial);
            this.hashToMaterialMap.put(hash, material);
            return material;
        }
        return material;
    }
    
    public FluidMaterial getFluidMaterial(@Nonnull final String fluidString) {
        int fluidId = 0;
        final Fluid key = Fluid.getAssetMap().getAsset(fluidString);
        if (key != null) {
            fluidId = Fluid.getAssetMap().getIndex(fluidString);
            final byte level = (byte)((fluidId == 0) ? 0 : ((byte)key.getMaxFluidLevel()));
            return this.getOrRegisterFluid(fluidId, level);
        }
        LoggerUtil.getLogger().warning("Attempted to register an invalid Fluid " + fluidString + ", using Unknown instead.");
        return this.UNKNOWN_FLUID;
    }
    
    public FluidMaterial getFluidMaterial(final int fluidId, final byte level) {
        final Fluid key = Fluid.getAssetMap().getAsset(fluidId);
        if (key == null) {
            LoggerUtil.getLogger().warning("Attempted to register an invalid Fluid " + fluidId + ", using Unknown instead.");
            return this.UNKNOWN_FLUID;
        }
        return this.getOrRegisterFluid(fluidId, level);
    }
    
    private FluidMaterial getOrRegisterFluid(final int fluidId, final byte level) {
        final int hash = FluidMaterial.contentHash(fluidId, level);
        FluidMaterial fluidMaterial = this.hashToFluidMap.get(hash);
        if (fluidMaterial != null) {
            return fluidMaterial;
        }
        fluidMaterial = new FluidMaterial(this, fluidId, level);
        this.hashToFluidMap.put(hash, fluidMaterial);
        return fluidMaterial;
    }
    
    public SolidMaterial getSolidMaterial(@Nonnull final String solidString) {
        int blockId = 0;
        final BlockType key = BlockType.fromString(solidString);
        if (key != null) {
            blockId = BlockType.getAssetMap().getIndex(key.getId());
        }
        if (BlockType.getAssetMap().getAsset(blockId) == null) {
            System.out.println("Attempted to register an invalid block ID " + blockId + ": using Empty_Air instead.");
            return this.EMPTY_AIR;
        }
        final int hash = SolidMaterial.contentHash(blockId, 0, 0, 0, null);
        SolidMaterial solidMaterial = this.hashToSolidMap.get(hash);
        if (solidMaterial != null) {
            return solidMaterial;
        }
        solidMaterial = new SolidMaterial(this, blockId, 0, 0, 0, null);
        this.hashToSolidMap.put(blockId, solidMaterial);
        return solidMaterial;
    }
    
    public SolidMaterial getSolidMaterialRotatedY(@Nonnull final SolidMaterial solidMaterial, final Rotation rotation) {
        final PrefabRotation prefabRotation = PrefabRotation.fromRotation(rotation);
        final int rotatedRotation = prefabRotation.getRotation(solidMaterial.rotation);
        final int rotatedFiller = prefabRotation.getFiller(solidMaterial.filler);
        final int hash = SolidMaterial.contentHash(solidMaterial.blockId, solidMaterial.support, rotatedRotation, rotatedFiller, solidMaterial.holder);
        SolidMaterial rotatedSolidMaterial = this.hashToSolidMap.get(hash);
        if (rotatedSolidMaterial != null) {
            return rotatedSolidMaterial;
        }
        rotatedSolidMaterial = new SolidMaterial(this, solidMaterial.blockId, solidMaterial.support, rotatedRotation, rotatedFiller, solidMaterial.holder);
        this.hashToSolidMap.put(hash, rotatedSolidMaterial);
        return rotatedSolidMaterial;
    }
    
    public SolidMaterial getSolidMaterial(final int blockId, final int support, final int rotation, final int filler, @Nullable final Holder<ChunkStore> holder) {
        if (BlockType.getAssetMap().getAsset(blockId) == null) {
            System.out.println("Attempted to register an invalid block ID " + blockId + ": using Empty_Air instead.");
            return this.EMPTY_AIR;
        }
        final int hash = SolidMaterial.contentHash(blockId, support, rotation, filler, holder);
        SolidMaterial solidMaterial = this.hashToSolidMap.get(hash);
        if (solidMaterial != null) {
            return solidMaterial;
        }
        solidMaterial = new SolidMaterial(this, blockId, support, rotation, filler, holder);
        this.hashToSolidMap.put(hash, solidMaterial);
        return solidMaterial;
    }
}
