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

package com.hypixel.hytale.math.vector;

import it.unimi.dsi.fastutil.objects.ObjectIterator;
import com.hypixel.hytale.function.consumer.IntTriObjectConsumer;
import com.hypixel.hytale.function.consumer.IntBiObjectConsumer;
import com.hypixel.hytale.function.consumer.IntObjectConsumer;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import java.util.Iterator;
import com.hypixel.fastutil.FastCollection;
import com.hypixel.hytale.function.consumer.TriConsumer;
import java.util.function.BiConsumer;
import javax.annotation.Nonnull;
import java.util.function.Function;
import java.util.function.Consumer;

public class VectorSphereUtil
{
    public static void forEachVector(final Iterable<Vector3d> vectors, final double originX, final double originY, final double originZ, final double radius, final Consumer<Vector3d> consumer) {
        forEachVector(vectors, originX, originY, originZ, radius, radius, radius, consumer);
    }
    
    public static void forEachVector(final Iterable<Vector3d> vectors, final double originX, final double originY, final double originZ, final double radiusX, final double radiusY, final double radiusZ, final Consumer<Vector3d> consumer) {
        forEachVector((Iterable<Object>)vectors, (Function<Object, Vector3d>)Function.identity(), originX, originY, originZ, radiusX, radiusY, radiusZ, (Consumer<Object>)consumer);
    }
    
    public static <T> void forEachVector(final Iterable<T> input, @Nonnull final Function<T, Vector3d> func, final double originX, final double originY, final double originZ, final double radius, final Consumer<T> consumer) {
        forEachVector(input, func, originX, originY, originZ, radius, radius, radius, consumer);
    }
    
    public static <T> void forEachVector(final Iterable<T> input, @Nonnull final Function<T, Vector3d> func, final double originX, final double originY, final double originZ, final double radiusX, final double radiusY, final double radiusZ, final Consumer<T> consumer) {
        forEachVector(input, func, originX, originY, originZ, radiusX, radiusY, radiusZ, (t, c, n0) -> c.accept(t), consumer, null);
    }
    
    public static <T, V> void forEachVector(final Iterable<T> input, @Nonnull final Function<T, Vector3d> func, final double originX, final double originY, final double originZ, final double radius, final BiConsumer<T, V> consumer, final V objV) {
        forEachVector(input, func, originX, originY, originZ, radius, radius, radius, consumer, objV);
    }
    
    public static <T, V> void forEachVector(final Iterable<T> input, @Nonnull final Function<T, Vector3d> func, final double originX, final double originY, final double originZ, final double radiusX, final double radiusY, final double radiusZ, final BiConsumer<T, V> consumer, final V objV) {
        forEachVector(input, func, originX, originY, originZ, radiusX, radiusY, radiusZ, (t, c, objV2) -> c.accept(t, objV2), consumer, objV);
    }
    
    public static <T, V1, V2> void forEachVector(final Iterable<T> input, @Nonnull final Function<T, Vector3d> func, final double originX, final double originY, final double originZ, final double radius, @Nonnull final TriConsumer<T, V1, V2> consumer, final V1 objV1, final V2 objV2) {
        forEachVector(input, func, originX, originY, originZ, radius, radius, radius, consumer, objV1, objV2);
    }
    
    public static <T, V1, V2> void forEachVector(final Iterable<T> input, @Nonnull final Function<T, Vector3d> func, final double originX, final double originY, final double originZ, final double radiusX, final double radiusY, final double radiusZ, @Nonnull final TriConsumer<T, V1, V2> consumer, final V1 objV1, final V2 objV2) {
        if (input instanceof final FastCollection collection) {
            final FastCollection<T> fastCollection = collection;
            final T obj;
            fastCollection.forEach((obj, _func, _originX, _originY, _originZ, _radiusX, _radiusY, _radiusZ, _consumer, _objV1, _objV2) -> {
                final Vector3d vector2 = _func.apply(obj);
                if (isInside(_originX, _originY, _originZ, _radiusX, _radiusY, _radiusZ, vector2)) {
                    _consumer.accept(obj, _objV1, _objV2);
                }
            }, func, originX, originY, originZ, radiusX, radiusY, radiusZ, consumer, objV1, objV2);
        }
        else {
            for (final T obj : input) {
                final Vector3d vector = func.apply(obj);
                if (isInside(originX, originY, originZ, radiusX, radiusY, radiusZ, vector)) {
                    consumer.accept(obj, objV1, objV2);
                }
            }
        }
    }
    
    public static <T> void forEachVector(@Nonnull final Int2ObjectMap<T> input, @Nonnull final Function<T, Vector3d> func, final double originX, final double originY, final double originZ, final double radius, final IntObjectConsumer<T> consumer) {
        forEachVector(input, func, originX, originY, originZ, radius, radius, radius, consumer);
    }
    
    public static <T> void forEachVector(@Nonnull final Int2ObjectMap<T> input, @Nonnull final Function<T, Vector3d> func, final double originX, final double originY, final double originZ, final double radiusX, final double radiusY, final double radiusZ, final IntObjectConsumer<T> consumer) {
        forEachVector(input, func, originX, originY, originZ, radiusX, radiusY, radiusZ, (i, t, c, n0) -> c.accept(i, t), consumer, null);
    }
    
    public static <T, V> void forEachVector(@Nonnull final Int2ObjectMap<T> input, @Nonnull final Function<T, Vector3d> func, final double originX, final double originY, final double originZ, final double radius, final IntBiObjectConsumer<T, V> consumer, final V objV) {
        forEachVector(input, func, originX, originY, originZ, radius, radius, radius, consumer, objV);
    }
    
    public static <T, V> void forEachVector(@Nonnull final Int2ObjectMap<T> input, @Nonnull final Function<T, Vector3d> func, final double originX, final double originY, final double originZ, final double radiusX, final double radiusY, final double radiusZ, final IntBiObjectConsumer<T, V> consumer, final V objV) {
        forEachVector(input, func, originX, originY, originZ, radiusX, radiusY, radiusZ, (i, t, objV1, c) -> c.accept(i, t, objV1), objV, consumer);
    }
    
    public static <T, V1, V2> void forEachVector(@Nonnull final Int2ObjectMap<T> input, @Nonnull final Function<T, Vector3d> func, final double originX, final double originY, final double originZ, final double radius, @Nonnull final IntTriObjectConsumer<T, V1, V2> consumer, final V1 objV1, final V2 objV2) {
        forEachVector(input, func, originX, originY, originZ, radius, radius, radius, consumer, objV1, objV2);
    }
    
    public static <T, V1, V2> void forEachVector(@Nonnull final Int2ObjectMap<T> input, @Nonnull final Function<T, Vector3d> func, final double originX, final double originY, final double originZ, final double radiusX, final double radiusY, final double radiusZ, @Nonnull final IntTriObjectConsumer<T, V1, V2> consumer, final V1 objV1, final V2 objV2) {
        for (final Int2ObjectMap.Entry<T> next : input.int2ObjectEntrySet()) {
            final int key = next.getIntKey();
            final T value = next.getValue();
            final Vector3d vector = func.apply(value);
            if (isInside(originX, originY, originZ, radiusX, radiusY, radiusZ, vector)) {
                consumer.accept(key, value, objV1, objV2);
            }
        }
    }
    
    public static boolean isInside(final double originX, final double originY, final double originZ, final double radius, @Nonnull final Vector3d vector) {
        return isInside(originX, originY, originZ, radius, radius, radius, vector);
    }
    
    public static boolean isInside(final double originX, final double originY, final double originZ, final double radiusX, final double radiusY, final double radiusZ, @Nonnull final Vector3d vector) {
        final double x = vector.getX() - originX;
        final double y = vector.getY() - originY;
        final double z = vector.getZ() - originZ;
        final double xRatio = x / radiusX;
        final double yRatio = y / radiusY;
        final double zRatio = z / radiusZ;
        return xRatio * xRatio + yRatio * yRatio + zRatio * zRatio <= 1.0;
    }
}
