package eu.mhsl.minenet.minigames.world.generator.featureEnriched;

import de.articdive.jnoise.JNoise;
import eu.mhsl.minenet.minigames.util.NumberUtil;
import eu.mhsl.minenet.minigames.world.generator.terrain.HeightTerrainGenerator;
import net.minestom.server.coordinate.Point;

import java.util.function.Function;

public class ValeGenerator extends HeightTerrainGenerator {
    private final JNoise curves = JNoise.newBuilder()
        .fastSimplex()
        .setSeed(this.rnd.nextLong())
        .setFrequency(0.01)
        .build();

    private final JNoise largeCurves = JNoise.newBuilder()
        .fastSimplex()
        .setSeed(this.rnd.nextLong())
        .setFrequency(0.001)
        .build();

    private Function<Integer, Double> xShiftMultiplier = multiplier -> 1d;
    private Function<Integer, Double> xShiftOffset = z -> 0d;

    public ValeGenerator() {
        this.setCalculateHeight(this::calculateY);
        this.setHeightNoiseMultiplier(point -> (int) NumberUtil.map(this.calculateY(point), -64, 100, 0, 16));
    }

    private int calculateY(Point point) {
        return (int) (Math.abs(point.blockX() - this.getXShiftAtZ(point.blockZ())) / 1.5);
    }

    public int getXShiftAtZ(int z) {
        return (int) ((this.curves.getNoise(z) * 32 + this.largeCurves.getNoise(z) * 64) * this.xShiftMultiplier.apply(z) + this.xShiftOffset.apply(z));
    }

    public void setXShiftMultiplier(Function<Integer, Double> xShiftMultiplier) {
        this.xShiftMultiplier = xShiftMultiplier;
    }

    public void setXShiftOffset(Function<Integer, Double> xShiftOffset) {
        this.xShiftOffset = xShiftOffset;
    }
}
