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

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

import javax.annotation.Nullable;
import com.hypixel.hytale.builtin.hytalegenerator.VectorUtil;
import javax.annotation.Nonnull;
import it.unimi.dsi.fastutil.doubles.Double2DoubleFunction;
import com.hypixel.hytale.math.vector.Vector3d;
import com.hypixel.hytale.builtin.hytalegenerator.density.Density;

public class PlaneDensity extends Density
{
    public static final double ZERO_DELTA = 1.0E-9;
    private static final Vector3d ZERO_VECTOR;
    @Nonnull
    private final Double2DoubleFunction distanceCurve;
    @Nonnull
    private final Vector3d planeNormal;
    private final boolean isPlaneHorizontal;
    private final boolean isAnchored;
    
    public PlaneDensity(@Nonnull final Double2DoubleFunction distanceCurve, @Nonnull final Vector3d planeNormal, final boolean isAnchored) {
        this.distanceCurve = distanceCurve;
        this.planeNormal = planeNormal;
        this.isPlaneHorizontal = (planeNormal.x == 0.0 && planeNormal.z == 0.0);
        this.isAnchored = isAnchored;
    }
    
    @Override
    public double process(@Nonnull final Context context) {
        if (this.planeNormal.length() == 0.0) {
            return 0.0;
        }
        if (this.isAnchored) {
            return this.processAnchored(context.position.x, context.position.y, context.position.z, context);
        }
        double distance = 0.0;
        if (this.isPlaneHorizontal) {
            distance = context.position.y;
        }
        else {
            final Vector3d nearestPoint = VectorUtil.nearestPointOnLine3d(context.position, PlaneDensity.ZERO_VECTOR, this.planeNormal);
            distance = nearestPoint.length();
        }
        return this.distanceCurve.get(distance);
    }
    
    private double processAnchored(final double x, final double y, final double z, @Nullable final Context context) {
        if (context == null) {
            return 0.0;
        }
        final Vector3d position = new Vector3d(x, y, z);
        final Vector3d p0 = context.densityAnchor;
        if (p0 == null) {
            return 0.0;
        }
        double distance = 0.0;
        if (this.isPlaneHorizontal) {
            distance = Math.abs(p0.y - position.y);
        }
        final Vector3d pos = position.clone().addScaled(p0, -1.0);
        final Vector3d vectorFromPlane = VectorUtil.nearestPointOnLine3d(pos, PlaneDensity.ZERO_VECTOR, this.planeNormal);
        distance = vectorFromPlane.length();
        return this.distanceCurve.get(distance);
    }
    
    static {
        ZERO_VECTOR = new Vector3d();
    }
}
