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

package com.hypixel.hytale.math.block;

import javax.annotation.Nonnull;
import com.hypixel.hytale.function.predicate.TriIntObjPredicate;
import javax.annotation.Nullable;

public class BlockDiamondUtil
{
    public static <T> boolean forEachBlock(final int originX, final int originY, final int originZ, final int radiusX, final int radiusY, final int radiusZ, @Nullable final T t, @Nonnull final TriIntObjPredicate<T> consumer) {
        if (radiusX <= 0) {
            throw new IllegalArgumentException(String.valueOf(radiusX));
        }
        if (radiusY <= 0) {
            throw new IllegalArgumentException(String.valueOf(radiusY));
        }
        if (radiusZ <= 0) {
            throw new IllegalArgumentException(String.valueOf(radiusZ));
        }
        final float radiusXAdjusted = radiusX + 0.41f;
        final float radiusZAdjusted = radiusZ + 0.41f;
        for (int y = 0; y <= radiusY; ++y) {
            final float normalizedY = y / (float)radiusY;
            final float currentRadiusX = radiusXAdjusted * (1.0f - normalizedY);
            final float currentRadiusZ = radiusZAdjusted * (1.0f - normalizedY);
            final int maxX = (int)currentRadiusX;
            final int maxZ = (int)currentRadiusZ;
            for (int x = 0; x <= maxX; ++x) {
                for (int z = 0; z <= maxZ; ++z) {
                    if (Math.abs(x) <= currentRadiusX && Math.abs(z) <= currentRadiusZ && !test(originX, originY, originZ, x, y, z, t, (TriIntObjPredicate<Object>)consumer)) {
                        return false;
                    }
                }
            }
        }
        return true;
    }
    
    public static <T> boolean forEachBlock(final int originX, final int originY, final int originZ, final int radiusX, final int radiusY, final int radiusZ, final int thickness, final boolean capped, @Nullable final T t, @Nonnull final TriIntObjPredicate<T> consumer) {
        if (thickness < 1) {
            return forEachBlock(originX, originY, originZ, radiusX, radiusY, radiusZ, t, consumer);
        }
        if (radiusX <= 0) {
            throw new IllegalArgumentException(String.valueOf(radiusX));
        }
        if (radiusY <= 0) {
            throw new IllegalArgumentException(String.valueOf(radiusY));
        }
        if (radiusZ <= 0) {
            throw new IllegalArgumentException(String.valueOf(radiusZ));
        }
        final float radiusXAdjusted = radiusX + 0.41f;
        final float radiusZAdjusted = radiusZ + 0.41f;
        for (int y = 0; y <= radiusY; ++y) {
            final float normalizedY = y / (float)radiusY;
            final float currentRadiusX = radiusXAdjusted * (1.0f - normalizedY);
            final float currentRadiusZ = radiusZAdjusted * (1.0f - normalizedY);
            final float innerRadiusX = Math.max(0.0f, currentRadiusX - thickness);
            final float innerRadiusZ = Math.max(0.0f, currentRadiusZ - thickness);
            final int maxX = (int)currentRadiusX;
            final int maxZ = (int)currentRadiusZ;
            for (int x = 0; x <= maxX; ++x) {
                for (int z = 0; z <= maxZ; ++z) {
                    final boolean inOuter = Math.abs(x) <= currentRadiusX && Math.abs(z) <= currentRadiusZ;
                    if (inOuter) {
                        final boolean inInner = Math.abs(x) < innerRadiusX && Math.abs(z) < innerRadiusZ;
                        if (!inInner) {
                            if (!test(originX, originY, originZ, x, y, z, t, consumer)) {
                                return false;
                            }
                        }
                    }
                }
            }
        }
        return true;
    }
    
    private static <T> boolean test(final int originX, final int originY, final int originZ, final int x, final int y, final int z, final T context, @Nonnull final TriIntObjPredicate<T> consumer) {
        if (!consumer.test(originX + x, originY + y, originZ + z, context)) {
            return false;
        }
        if (y > 0 && !consumer.test(originX + x, originY - y, originZ + z, context)) {
            return false;
        }
        if (x > 0) {
            if (!consumer.test(originX - x, originY + y, originZ + z, context)) {
                return false;
            }
            if (y > 0 && !consumer.test(originX - x, originY - y, originZ + z, context)) {
                return false;
            }
            if (z > 0 && !consumer.test(originX - x, originY + y, originZ - z, context)) {
                return false;
            }
            if (y > 0 && z > 0 && !consumer.test(originX - x, originY - y, originZ - z, context)) {
                return false;
            }
        }
        if (z > 0) {
            if (!consumer.test(originX + x, originY + y, originZ - z, context)) {
                return false;
            }
            if (y > 0 && !consumer.test(originX + x, originY - y, originZ - z, context)) {
                return false;
            }
        }
        return true;
    }
}
