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

package com.hypixel.hytale.procedurallib.logic;

import javax.annotation.Nonnull;

public final class GeneralNoise
{
    public static final int X_PRIME = 1619;
    public static final int Y_PRIME = 31337;
    public static final int Z_PRIME = 6971;
    private static final DoubleArray.Double2[] GRAD_2D;
    private static final DoubleArray.Double3[] GRAD_3D;
    
    private GeneralNoise() {
        throw new UnsupportedOperationException();
    }
    
    public static int fastFloor(final double f) {
        return (f >= 0.0) ? ((int)f) : ((int)f - 1);
    }
    
    public static int fastCeil(final double f) {
        return (f >= 0.0) ? ((int)f + 1) : ((int)f);
    }
    
    public static double lerp(final double a, final double b, final double t) {
        return a + t * (b - a);
    }
    
    public static int hash2D(final int seed, final int x, final int y) {
        int hash = seed;
        hash ^= 1619 * x;
        hash ^= 31337 * y;
        hash = hash * hash * hash * 60493;
        hash ^= hash >> 13;
        return hash;
    }
    
    public static int hash3D(final int seed, final int x, final int y, final int z) {
        int hash = seed;
        hash ^= 1619 * x;
        hash ^= 31337 * y;
        hash ^= 6971 * z;
        hash = hash * hash * hash * 60493;
        hash ^= hash >> 13;
        return hash;
    }
    
    public static double gradCoord2D(final int seed, final int x, final int y, final double xd, final double yd) {
        final int hash = hash2D(seed, x, y);
        final DoubleArray.Double2 g = GeneralNoise.GRAD_2D[hash & 0x7];
        return xd * g.x + yd * g.y;
    }
    
    public static double gradCoord3D(final int seed, final int x, final int y, final int z, final double xd, final double yd, final double zd) {
        final int hash = hash3D(seed, x, y, z);
        final DoubleArray.Double3 g = GeneralNoise.GRAD_3D[hash & 0xF];
        return xd * g.x + yd * g.y + zd * g.z;
    }
    
    public static double limit(final double val) {
        if (val < 0.0) {
            return 0.0;
        }
        if (val > 1.0) {
            return 1.0;
        }
        return val;
    }
    
    static {
        GRAD_2D = new DoubleArray.Double2[] { new DoubleArray.Double2(-1.0, -1.0), new DoubleArray.Double2(1.0, -1.0), new DoubleArray.Double2(-1.0, 1.0), new DoubleArray.Double2(1.0, 1.0), new DoubleArray.Double2(0.0, -1.0), new DoubleArray.Double2(-1.0, 0.0), new DoubleArray.Double2(0.0, 1.0), new DoubleArray.Double2(1.0, 0.0) };
        GRAD_3D = new DoubleArray.Double3[] { new DoubleArray.Double3(1.0, 1.0, 0.0), new DoubleArray.Double3(-1.0, 1.0, 0.0), new DoubleArray.Double3(1.0, -1.0, 0.0), new DoubleArray.Double3(-1.0, -1.0, 0.0), new DoubleArray.Double3(1.0, 0.0, 1.0), new DoubleArray.Double3(-1.0, 0.0, 1.0), new DoubleArray.Double3(1.0, 0.0, -1.0), new DoubleArray.Double3(-1.0, 0.0, -1.0), new DoubleArray.Double3(0.0, 1.0, 1.0), new DoubleArray.Double3(0.0, -1.0, 1.0), new DoubleArray.Double3(0.0, 1.0, -1.0), new DoubleArray.Double3(0.0, -1.0, -1.0), new DoubleArray.Double3(1.0, 1.0, 0.0), new DoubleArray.Double3(0.0, -1.0, 1.0), new DoubleArray.Double3(-1.0, 1.0, 0.0), new DoubleArray.Double3(0.0, -1.0, -1.0) };
    }
    
    public enum InterpolationMode
    {
        LINEAR((InterpolationFunction)new InterpolationFunction() {
            @Override
            public double interpolate(final double t) {
                return t;
            }
            
            @Nonnull
            @Override
            public String toString() {
                return "LinearInterpolationFunction{}";
            }
        }), 
        HERMITE((InterpolationFunction)new InterpolationFunction() {
            @Override
            public double interpolate(final double t) {
                return t * t * (3.0 - 2.0 * t);
            }
            
            @Nonnull
            @Override
            public String toString() {
                return "HermiteInterpolationFunction{}";
            }
        }), 
        QUINTIC((InterpolationFunction)new InterpolationFunction() {
            @Override
            public double interpolate(final double t) {
                return t * t * t * (t * (t * 6.0 - 15.0) + 10.0);
            }
            
            @Nonnull
            @Override
            public String toString() {
                return "QuinticInterpolationFunction{}";
            }
        });
        
        public final InterpolationFunction function;
        
        private InterpolationMode(final InterpolationFunction function) {
            this.function = function;
        }
        
        public InterpolationFunction getFunction() {
            return this.function;
        }
    }
    
    @FunctionalInterface
    public interface InterpolationFunction
    {
        double interpolate(final double p0);
    }
}
