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

package com.hypixel.hytale.server.worldgen.cave.prefab;

import com.hypixel.hytale.server.worldgen.biome.Biome;
import com.hypixel.hytale.server.worldgen.cave.element.CaveNode;
import com.hypixel.hytale.math.util.MathUtil;
import javax.annotation.Nonnull;
import java.util.Random;
import com.hypixel.hytale.procedurallib.condition.ICoordinateRndCondition;
import com.hypixel.hytale.procedurallib.condition.ICoordinateCondition;
import com.hypixel.hytale.procedurallib.supplier.IDoubleCoordinateHashSupplier;
import com.hypixel.hytale.procedurallib.supplier.IDoubleRange;
import com.hypixel.hytale.server.worldgen.util.condition.BlockMaskCondition;
import com.hypixel.hytale.procedurallib.condition.IIntCondition;
import com.hypixel.hytale.server.worldgen.cave.CavePrefabPlacement;
import com.hypixel.hytale.server.core.prefab.PrefabRotation;
import javax.annotation.Nullable;
import com.hypixel.hytale.server.worldgen.loader.WorldGenPrefabSupplier;
import com.hypixel.hytale.common.map.IWeightedMap;

public class CavePrefabContainer
{
    protected final CavePrefabEntry[] entries;
    
    public CavePrefabContainer(final CavePrefabEntry[] entries) {
        this.entries = entries;
    }
    
    public CavePrefabEntry[] getEntries() {
        return this.entries;
    }
    
    public static class CavePrefabEntry
    {
        protected final IWeightedMap<WorldGenPrefabSupplier> prefabs;
        protected final CavePrefabConfig config;
        
        public CavePrefabEntry(final IWeightedMap<WorldGenPrefabSupplier> prefabs, final CavePrefabConfig config) {
            this.prefabs = prefabs;
            this.config = config;
        }
        
        public IWeightedMap<WorldGenPrefabSupplier> getPrefabs() {
            return this.prefabs;
        }
        
        @Nullable
        public WorldGenPrefabSupplier getPrefab(final double random) {
            return this.prefabs.get(random);
        }
        
        public CavePrefabConfig getConfig() {
            return this.config;
        }
        
        public static class CavePrefabConfig
        {
            protected final PrefabRotation[] rotations;
            protected final CavePrefabPlacement placement;
            protected final IIntCondition biomeMask;
            protected final BlockMaskCondition blockMask;
            protected final IDoubleRange iterations;
            protected final IDoubleCoordinateHashSupplier displacementSupplier;
            protected final ICoordinateCondition maskCondition;
            protected final ICoordinateRndCondition heightCondition;
            
            public CavePrefabConfig(final PrefabRotation[] rotations, final CavePrefabPlacement placement, final IIntCondition biomeMask, final BlockMaskCondition blockMask, final IDoubleRange iterations, final IDoubleCoordinateHashSupplier displacementSupplier, final ICoordinateCondition maskCondition, final ICoordinateRndCondition heightCondition) {
                this.rotations = rotations;
                this.placement = placement;
                this.biomeMask = biomeMask;
                this.blockMask = blockMask;
                this.iterations = iterations;
                this.displacementSupplier = displacementSupplier;
                this.maskCondition = maskCondition;
                this.heightCondition = heightCondition;
            }
            
            public PrefabRotation getRotation(@Nonnull final Random random) {
                return this.rotations[random.nextInt(this.rotations.length)];
            }
            
            public IIntCondition getBiomeMask() {
                return this.biomeMask;
            }
            
            public BlockMaskCondition getBlockMask() {
                return this.blockMask;
            }
            
            public int getIterations(final double random) {
                return MathUtil.floor(this.iterations.getValue(random));
            }
            
            public double getDisplacement(final int seed, final int x, final int z, @Nonnull final CaveNode caveNode) {
                return this.displacementSupplier.get(seed, x, z, seed + caveNode.getSeedOffset());
            }
            
            public int getHeight(final int seed, final int x, final int z, @Nonnull final CaveNode caveNode) {
                final int y = this.placement.getFunction().generate(seed, x, z, caveNode);
                if (y == -1) {
                    return -1;
                }
                return (int)(y + this.getDisplacement(seed, x, z, caveNode));
            }
            
            public boolean isMatchingNoiseDensity(final int seed, final int x, final int z) {
                return this.maskCondition.eval(seed, x, z);
            }
            
            public boolean isMatchingHeight(final int seed, final int x, final int y, final int z, final Random random) {
                return this.heightCondition.eval(seed, x, z, y, random);
            }
            
            public boolean isMatchingBiome(@Nonnull final Biome biome) {
                return this.biomeMask.eval(biome.getId());
            }
        }
    }
}
