package net.minecraft.world.level.newbiome.context;

import it.unimi.dsi.fastutil.longs.Long2IntLinkedOpenHashMap;
import net.minecraft.util.LinearCongruentialGenerator;
import net.minecraft.world.level.levelgen.SimpleRandomSource;
import net.minecraft.world.level.levelgen.synth.NoiseGeneratorPerlin;
import net.minecraft.world.level.newbiome.area.AreaLazy;
import net.minecraft.world.level.newbiome.layer.traits.AreaTransformer8;

public class WorldGenContextArea implements AreaContextTransformed<AreaLazy> {

    private static final int MAX_CACHE = 1024;
    private final Long2IntLinkedOpenHashMap cache;
    private final int maxCache;
    private final NoiseGeneratorPerlin biomeNoise;
    private final long seed;
    private long rval;

    public WorldGenContextArea(int i, long j, long k) {
        this.seed = b(j, k);
        this.biomeNoise = new NoiseGeneratorPerlin(new SimpleRandomSource(j));
        this.cache = new Long2IntLinkedOpenHashMap(16, 0.25F);
        this.cache.defaultReturnValue(Integer.MIN_VALUE);
        this.maxCache = i;
    }

    @Override
    public AreaLazy a(AreaTransformer8 areatransformer8) {
        return new AreaLazy(this.cache, this.maxCache, areatransformer8);
    }

    public AreaLazy a(AreaTransformer8 areatransformer8, AreaLazy arealazy) {
        return new AreaLazy(this.cache, Math.min(1024, arealazy.a() * 4), areatransformer8);
    }

    public AreaLazy a(AreaTransformer8 areatransformer8, AreaLazy arealazy, AreaLazy arealazy1) {
        return new AreaLazy(this.cache, Math.min(1024, Math.max(arealazy.a(), arealazy1.a()) * 4), areatransformer8);
    }

    @Override
    public void a(long i, long j) {
        long k = this.seed;

        k = LinearCongruentialGenerator.a(k, i);
        k = LinearCongruentialGenerator.a(k, j);
        k = LinearCongruentialGenerator.a(k, i);
        k = LinearCongruentialGenerator.a(k, j);
        this.rval = k;
    }

    @Override
    public int a(int i) {
        int j = Math.floorMod(this.rval >> 24, i);

        this.rval = LinearCongruentialGenerator.a(this.rval, this.seed);
        return j;
    }

    @Override
    public NoiseGeneratorPerlin a() {
        return this.biomeNoise;
    }

    private static long b(long i, long j) {
        long k = LinearCongruentialGenerator.a(j, j);

        k = LinearCongruentialGenerator.a(k, j);
        k = LinearCongruentialGenerator.a(k, j);
        long l = LinearCongruentialGenerator.a(i, k);

        l = LinearCongruentialGenerator.a(l, k);
        l = LinearCongruentialGenerator.a(l, k);
        return l;
    }
}
