package net.minecraft.world.level.biome;

import com.google.common.collect.ImmutableList;
import java.util.function.Function;
import net.minecraft.util.Mth;
import java.util.Random;
import net.minecraft.world.level.levelgen.WorldgenRandom;
import java.util.List;
import net.minecraft.world.level.levelgen.synth.SimplexNoise;
import com.mojang.serialization.Codec;

public class TheEndBiomeSource extends BiomeSource {
    public static final Codec<TheEndBiomeSource> CODEC;
    private final SimplexNoise islandNoise;
    private static final List<Biome> POSSIBLE_BIOMES;
    private final long seed;
    
    public TheEndBiomeSource(final long long1) {
        super(TheEndBiomeSource.POSSIBLE_BIOMES);
        this.seed = long1;
        final WorldgenRandom ciy4 = new WorldgenRandom(long1);
        ciy4.consumeCount(17292);
        this.islandNoise = new SimplexNoise(ciy4);
    }
    
    @Override
    protected Codec<? extends BiomeSource> codec() {
        return TheEndBiomeSource.CODEC;
    }
    
    @Override
    public BiomeSource withSeed(final long long1) {
        return new TheEndBiomeSource(long1);
    }
    
    @Override
    public Biome getNoiseBiome(final int integer1, final int integer2, final int integer3) {
        final int integer4 = integer1 >> 2;
        final int integer5 = integer3 >> 2;
        if (integer4 * (long)integer4 + integer5 * (long)integer5 <= 4096L) {
            return Biomes.THE_END;
        }
        final float float7 = getHeightValue(this.islandNoise, integer4 * 2 + 1, integer5 * 2 + 1);
        if (float7 > 40.0f) {
            return Biomes.END_HIGHLANDS;
        }
        if (float7 >= 0.0f) {
            return Biomes.END_MIDLANDS;
        }
        if (float7 < -20.0f) {
            return Biomes.SMALL_END_ISLANDS;
        }
        return Biomes.END_BARRENS;
    }
    
    public boolean stable(final long long1) {
        return this.seed == long1;
    }
    
    public static float getHeightValue(final SimplexNoise cwg, final int integer2, final int integer3) {
        final int integer4 = integer2 / 2;
        final int integer5 = integer3 / 2;
        final int integer6 = integer2 % 2;
        final int integer7 = integer3 % 2;
        float float8 = 100.0f - Mth.sqrt((float)(integer2 * integer2 + integer3 * integer3)) * 8.0f;
        float8 = Mth.clamp(float8, -100.0f, 80.0f);
        for (int integer8 = -12; integer8 <= 12; ++integer8) {
            for (int integer9 = -12; integer9 <= 12; ++integer9) {
                final long long11 = integer4 + integer8;
                final long long12 = integer5 + integer9;
                if (long11 * long11 + long12 * long12 > 4096L && cwg.getValue((double)long11, (double)long12) < -0.8999999761581421) {
                    final float float9 = (Mth.abs((float)long11) * 3439.0f + Mth.abs((float)long12) * 147.0f) % 13.0f + 9.0f;
                    final float float10 = (float)(integer6 - integer8 * 2);
                    final float float11 = (float)(integer7 - integer9 * 2);
                    float float12 = 100.0f - Mth.sqrt(float10 * float10 + float11 * float11) * float9;
                    float12 = Mth.clamp(float12, -100.0f, 80.0f);
                    float8 = Math.max(float8, float12);
                }
            }
        }
        return float8;
    }
    
    static {
        CODEC = Codec.LONG.fieldOf("seed").xmap((Function)TheEndBiomeSource::new, buh -> buh.seed).stable().codec();
        POSSIBLE_BIOMES = ImmutableList.<Biome>of(Biomes.THE_END, Biomes.END_HIGHLANDS, Biomes.END_MIDLANDS, Biomes.SMALL_END_ISLANDS, Biomes.END_BARRENS);
    }
}
