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

package com.hypixel.hytale.builtin.hytalegenerator.density.nodes;

import com.hypixel.hytale.math.vector.Vector3d;
import javax.annotation.Nonnull;
import com.hypixel.hytale.builtin.hytalegenerator.fields.FastNoiseLite;
import javax.annotation.Nullable;
import com.hypixel.hytale.builtin.hytalegenerator.density.Density;

public class FastGradientWarpDensity extends Density
{
    private static final double HALF_PI = 1.5707963267948966;
    @Nullable
    private Density input;
    private final double warpScale;
    @Nonnull
    private final FastNoiseLite warper;
    
    public FastGradientWarpDensity(@Nonnull final Density input, final float warpLacunarity, final float warpPersistence, final int warpOctaves, final float warpScale, final float warpFactor, final int seed) {
        if (warpOctaves < 0.0) {
            throw new IllegalArgumentException();
        }
        this.warpScale = warpScale;
        this.input = input;
        (this.warper = new FastNoiseLite()).setSeed(seed);
        this.warper.SetFractalGain(warpPersistence);
        this.warper.SetFractalLacunarity(warpLacunarity);
        this.warper.setDomainWarpType(FastNoiseLite.DomainWarpType.OpenSimplex2);
        this.warper.setFractalOctaves(warpOctaves);
        this.warper.setDomainWarpAmp(warpFactor);
        this.warper.setDomainWarpFreq(warpScale);
    }
    
    @Override
    public double process(@Nonnull final Context context) {
        if (this.input == null) {
            return 0.0;
        }
        final FastNoiseLite.Vector3 warpedPosition = new FastNoiseLite.Vector3(context.position.x, context.position.y, context.position.z);
        this.warper.DomainWarpFractalProgressive(warpedPosition);
        final Context childContext = new Context(context);
        childContext.position = new Vector3d(warpedPosition.x, warpedPosition.y, warpedPosition.z);
        return this.input.process(childContext);
    }
    
    @Override
    public void setInputs(@Nonnull final Density[] inputs) {
        if (inputs.length == 1) {
            this.input = inputs[0];
        }
        else {
            this.input = null;
        }
    }
}
