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

package com.hypixel.hytale.procedurallib.logic;

import javax.annotation.Nonnull;
import com.hypixel.hytale.procedurallib.NoiseFunction;

public class PerlinNoise implements NoiseFunction
{
    protected final GeneralNoise.InterpolationFunction interpolationFunction;
    
    public PerlinNoise(final GeneralNoise.InterpolationFunction interpolationFunction) {
        this.interpolationFunction = interpolationFunction;
    }
    
    public GeneralNoise.InterpolationFunction getInterpolationFunction() {
        return this.interpolationFunction;
    }
    
    @Override
    public double get(final int seed, final int offsetSeed, final double x, final double y) {
        final int x2 = GeneralNoise.fastFloor(x);
        final int y2 = GeneralNoise.fastFloor(y);
        final int x3 = x2 + 1;
        final int y3 = y2 + 1;
        final double xs = this.interpolationFunction.interpolate(x - x2);
        final double ys = this.interpolationFunction.interpolate(y - y2);
        final double xd0 = x - x2;
        final double yd0 = y - y2;
        final double xd2 = xd0 - 1.0;
        final double yd2 = yd0 - 1.0;
        final double xf0 = GeneralNoise.lerp(GeneralNoise.gradCoord2D(offsetSeed, x2, y2, xd0, yd0), GeneralNoise.gradCoord2D(offsetSeed, x3, y2, xd2, yd0), xs);
        final double xf2 = GeneralNoise.lerp(GeneralNoise.gradCoord2D(offsetSeed, x2, y3, xd0, yd2), GeneralNoise.gradCoord2D(offsetSeed, x3, y3, xd2, yd2), xs);
        return GeneralNoise.lerp(xf0, xf2, ys);
    }
    
    @Override
    public double get(final int seed, final int offsetSeed, final double x, final double y, final double z) {
        final int x2 = GeneralNoise.fastFloor(x);
        final int y2 = GeneralNoise.fastFloor(y);
        final int z2 = GeneralNoise.fastFloor(z);
        final int x3 = x2 + 1;
        final int y3 = y2 + 1;
        final int z3 = z2 + 1;
        final double xs = this.interpolationFunction.interpolate(x - x2);
        final double ys = this.interpolationFunction.interpolate(y - y2);
        final double zs = this.interpolationFunction.interpolate(z - z2);
        final double xd0 = x - x2;
        final double yd0 = y - y2;
        final double zd0 = z - z2;
        final double xd2 = xd0 - 1.0;
        final double yd2 = yd0 - 1.0;
        final double zd2 = zd0 - 1.0;
        final double xf00 = GeneralNoise.lerp(GeneralNoise.gradCoord3D(offsetSeed, x2, y2, z2, xd0, yd0, zd0), GeneralNoise.gradCoord3D(offsetSeed, x3, y2, z2, xd2, yd0, zd0), xs);
        final double xf2 = GeneralNoise.lerp(GeneralNoise.gradCoord3D(offsetSeed, x2, y3, z2, xd0, yd2, zd0), GeneralNoise.gradCoord3D(offsetSeed, x3, y3, z2, xd2, yd2, zd0), xs);
        final double xf3 = GeneralNoise.lerp(GeneralNoise.gradCoord3D(offsetSeed, x2, y2, z3, xd0, yd0, zd2), GeneralNoise.gradCoord3D(offsetSeed, x3, y2, z3, xd2, yd0, zd2), xs);
        final double xf4 = GeneralNoise.lerp(GeneralNoise.gradCoord3D(offsetSeed, x2, y3, z3, xd0, yd2, zd2), GeneralNoise.gradCoord3D(offsetSeed, x3, y3, z3, xd2, yd2, zd2), xs);
        final double yf0 = GeneralNoise.lerp(xf00, xf2, ys);
        final double yf2 = GeneralNoise.lerp(xf3, xf4, ys);
        return GeneralNoise.lerp(yf0, yf2, zs);
    }
    
    @Nonnull
    @Override
    public String toString() {
        return "PerlinNoise{interpolationFunction=" + String.valueOf(this.interpolationFunction);
    }
}
