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

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

import com.hypixel.hytale.server.worldgen.cache.InterpolatedBiomeCountList;
import javax.annotation.Nonnull;
import com.hypixel.hytale.server.worldgen.cache.CoreDataCacheEntry;

public class HeightThresholdInterpolator
{
    public static final int MAX_RADIUS = 5;
    public static final int MAX_RADIUS2 = 25;
    private final ChunkGeneratorExecution execution;
    @Nonnull
    private final CoreDataCacheEntry[] entries;
    private final int radius;
    private final int size;
    private final int totalSize;
    
    public HeightThresholdInterpolator(final ChunkGeneratorExecution execution) {
        this.execution = execution;
        this.radius = 5;
        this.size = 32;
        this.totalSize = this.size + 2 * this.radius;
        this.entries = new CoreDataCacheEntry[this.totalSize * this.totalSize];
    }
    
    @Nonnull
    public CoreDataCacheEntry[] getEntries() {
        return this.entries;
    }
    
    @Nonnull
    public HeightThresholdInterpolator populate(final int seed) {
        final ChunkGenerator generator = this.execution.getChunkGenerator();
        for (int cx = -this.radius, mx = this.size + this.radius; cx < mx; ++cx) {
            for (int cz = -this.radius, mz = this.size + this.radius; cz < mz; ++cz) {
                this.setTableEntry(cx, cz, generator.getCoreData(seed, this.execution.globalX(cx), this.execution.globalZ(cz)));
            }
        }
        for (int cx = 0; cx < this.size; ++cx) {
            for (int cz2 = 0; cz2 < this.size; ++cz2) {
                final CoreDataCacheEntry entry = this.tableEntry(cx, cz2);
                if (entry.biomeCountList == null) {
                    final InterpolatedBiomeCountList list = new InterpolatedBiomeCountList();
                    this.generateInterpolatedBiomeCountAt(cx, cz2, list);
                    entry.biomeCountList = list;
                }
                if (entry.heightNoise == Double.NEGATIVE_INFINITY) {
                    entry.heightNoise = generator.generateInterpolatedHeightNoise(entry.biomeCountList);
                }
            }
        }
        return this;
    }
    
    public void generateInterpolatedBiomeCountAt(final int cx, final int cz, @Nonnull final InterpolatedBiomeCountList biomeCountList) {
        final ZoneBiomeResult center = this.tableEntry(cx, cz).zoneBiomeResult;
        biomeCountList.setCenter(center);
        final int radius = center.getBiome().getInterpolation().getRadius();
        final int radius2 = radius * radius;
        for (int ix = -radius; ix <= radius; ++ix) {
            for (int iz = -radius; iz <= radius; ++iz) {
                if (ix != 0 || iz != 0) {
                    final int distance2 = ix * ix + iz * iz;
                    if (distance2 <= radius2) {
                        final ZoneBiomeResult biomeResult = this.tableEntry(cx + ix, cz + iz).zoneBiomeResult;
                        biomeCountList.add(biomeResult, distance2);
                    }
                }
            }
        }
        if (biomeCountList.getBiomeIds().size() == 1) {
            final InterpolatedBiomeCountList.BiomeCountResult result = biomeCountList.get(center.getBiome());
            result.heightNoise = center.heightmapNoise;
            result.count = 1;
        }
    }
    
    public double getHeightNoise(final int cx, final int cz) {
        return this.tableEntry(cx, cz).heightNoise;
    }
    
    public float getHeightThreshold(final int seed, final int x, final int z, final int y) {
        return this.interpolateHeightThreshold(seed, x, z, y);
    }
    
    private float interpolateHeightThreshold(final int seed, final int x, final int z, final int y) {
        final CoreDataCacheEntry entry = this.tableEntry(this.execution.localX(x), this.execution.localZ(z));
        return ChunkGenerator.generateInterpolatedThreshold(seed, x, z, y, entry.biomeCountList);
    }
    
    protected CoreDataCacheEntry tableEntry(final int cx, final int cz) {
        return this.entries[this.indexLocal(cx, cz)];
    }
    
    protected void setTableEntry(final int cx, final int cz, final CoreDataCacheEntry entry) {
        this.entries[this.indexLocal(cx, cz)] = entry;
    }
    
    protected ZoneBiomeResult zoneBiomeResult(final int cx, final int cz) {
        return this.tableEntry(cx, cz).zoneBiomeResult;
    }
    
    public int getLowestNonOne(final int cx, final int cz) {
        return this.execution.getChunkGenerator().generateLowestThresholdDependent(this.tableEntry(cx, cz).biomeCountList);
    }
    
    public int getHighestNonZero(final int cx, final int cz) {
        return this.execution.getChunkGenerator().generateHighestThresholdDependent(this.tableEntry(cx, cz).biomeCountList);
    }
    
    protected int indexLocal(final int x, final int z) {
        return (x + this.radius) * this.totalSize + z + this.radius;
    }
}
