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

package com.hypixel.hytale.server.worldgen.util;

import com.hypixel.hytale.math.util.MathUtil;
import java.util.Objects;
import com.hypixel.hytale.procedurallib.supplier.IDoubleCoordinateSupplier2d;
import com.hypixel.hytale.procedurallib.property.NoiseProperty;
import com.hypixel.hytale.procedurallib.supplier.IDoubleRange;
import javax.annotation.Nonnull;
import java.util.Arrays;
import javax.annotation.Nullable;

public class NoiseBlockArray
{
    public static final NoiseBlockArray EMPTY;
    protected final Entry[] entries;
    
    public NoiseBlockArray(final Entry[] entries) {
        this.entries = entries;
    }
    
    public Entry[] getEntries() {
        return this.entries;
    }
    
    public BlockFluidEntry getTopBlockAt(final int seed, final double x, final double z) {
        for (int i = 0; i < this.entries.length; ++i) {
            final Entry entry = this.entries[i];
            final int repetitions = entry.getRepetitions(seed, x, z);
            if (repetitions > 0) {
                return entry.blockEntry;
            }
        }
        return BlockFluidEntry.EMPTY;
    }
    
    public BlockFluidEntry getBottomBlockAt(final int seed, final double x, final double z) {
        for (int i = this.entries.length - 1; i >= 0; --i) {
            final Entry entry = this.entries[i];
            final int repetitions = entry.getRepetitions(seed, x, z);
            if (repetitions > 0) {
                return entry.blockEntry;
            }
        }
        return BlockFluidEntry.EMPTY;
    }
    
    @Override
    public boolean equals(@Nullable final Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || this.getClass() != o.getClass()) {
            return false;
        }
        final NoiseBlockArray that = (NoiseBlockArray)o;
        return Arrays.equals(this.entries, that.entries);
    }
    
    @Override
    public int hashCode() {
        return Arrays.hashCode(this.entries);
    }
    
    @Nonnull
    @Override
    public String toString() {
        return "NoiseBlockArray{entries=" + Arrays.toString(this.entries);
    }
    
    static {
        EMPTY = new NoiseBlockArray(new Entry[0]);
    }
    
    public static class Entry
    {
        protected final String blockName;
        protected final BlockFluidEntry blockEntry;
        protected final IDoubleRange repetitions;
        @Nonnull
        protected final NoiseProperty noise;
        @Nonnull
        protected final IDoubleCoordinateSupplier2d noiseSupplier;
        
        public Entry(final String blockName, final BlockFluidEntry blockEntry, final IDoubleRange repetitions, @Nonnull final NoiseProperty noise) {
            this.blockName = blockName;
            this.blockEntry = blockEntry;
            this.repetitions = repetitions;
            Objects.requireNonNull(this.noise = noise);
            this.noiseSupplier = noise::get;
        }
        
        public String getBlockName() {
            return this.blockName;
        }
        
        public BlockFluidEntry getBlockEntry() {
            return this.blockEntry;
        }
        
        public int getRepetitions(final int seed, final double x, final double z) {
            return MathUtil.floor(this.repetitions.getValue(seed, x, z, this.noiseSupplier));
        }
        
        @Override
        public boolean equals(@Nullable final Object o) {
            if (this == o) {
                return true;
            }
            if (o == null || this.getClass() != o.getClass()) {
                return false;
            }
            final Entry entry = (Entry)o;
            return this.blockEntry == entry.blockEntry && this.blockName.equals(entry.blockName) && this.repetitions.equals(entry.repetitions) && this.noise.equals(entry.noise) && this.noiseSupplier.equals(entry.noiseSupplier);
        }
        
        @Override
        public int hashCode() {
            int result = this.blockName.hashCode();
            result = 31 * result + this.blockEntry.hashCode();
            result = 31 * result + this.repetitions.hashCode();
            result = 31 * result + this.noise.hashCode();
            result = 31 * result + this.noiseSupplier.hashCode();
            return result;
        }
        
        @Nonnull
        @Override
        public String toString() {
            return "Entry{blockName='" + this.blockName + "', blockEntry=" + String.valueOf(this.blockEntry) + ", repetitions=" + String.valueOf(this.repetitions) + ", noise=" + String.valueOf(this.noise);
        }
    }
}
