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

package com.hypixel.hytale.server.core.prefab.selection.buffer.impl;

import com.hypixel.hytale.server.core.prefab.PrefabWeights;
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
import com.hypixel.hytale.server.core.universe.world.storage.ChunkStore;
import com.hypixel.hytale.component.Holder;
import com.hypixel.hytale.server.core.prefab.selection.buffer.PrefabBufferCall;
import javax.annotation.Nullable;
import javax.annotation.Nonnull;
import com.hypixel.hytale.server.core.prefab.PrefabRotation;

public interface IPrefabBuffer
{
    public static final ColumnPredicate<?> ALL_COLUMNS = (x, z, blocks, o) -> true;
    
    int getAnchorX();
    
    int getAnchorY();
    
    int getAnchorZ();
    
    int getMinX(@Nonnull final PrefabRotation p0);
    
    int getMinY();
    
    int getMinZ(@Nonnull final PrefabRotation p0);
    
    int getMaxX(@Nonnull final PrefabRotation p0);
    
    int getMaxY();
    
    int getMaxZ(@Nonnull final PrefabRotation p0);
    
    default int getMinX() {
        return this.getMinX(PrefabRotation.ROTATION_0);
    }
    
    default int getMinZ() {
        return this.getMinZ(PrefabRotation.ROTATION_0);
    }
    
    default int getMaxX() {
        return this.getMaxX(PrefabRotation.ROTATION_0);
    }
    
    default int getMaxZ() {
        return this.getMaxZ(PrefabRotation.ROTATION_0);
    }
    
    int getMinYAt(@Nonnull final PrefabRotation p0, final int p1, final int p2);
    
    int getMaxYAt(@Nonnull final PrefabRotation p0, final int p1, final int p2);
    
    int getColumnCount();
    
    @Nonnull
    PrefabBuffer.ChildPrefab[] getChildPrefabs();
    
    default int getMaximumExtend() {
        int max = 0;
        for (final PrefabRotation rotation : PrefabRotation.VALUES) {
            final int x = this.getMaxX(rotation) - this.getMinX(rotation);
            if (x > max) {
                max = x;
            }
            final int z = this.getMaxZ(rotation) - this.getMinZ(rotation);
            if (z > max) {
                max = z;
            }
        }
        return max;
    }
    
     <T extends PrefabBufferCall> void forEach(@Nonnull final ColumnPredicate<T> p0, @Nonnull final BlockConsumer<T> p1, @Nullable final EntityConsumer<T> p2, @Nullable final ChildConsumer<T> p3, @Nonnull final T p4);
    
     <T> void forEachRaw(@Nonnull final ColumnPredicate<T> p0, @Nonnull final RawBlockConsumer<T> p1, @Nonnull final FluidConsumer<T> p2, @Nullable final EntityConsumer<T> p3, @Nullable final T p4);
    
     <T> boolean forEachRaw(@Nonnull final ColumnPredicate<T> p0, @Nonnull final RawBlockPredicate<T> p1, @Nonnull final FluidPredicate<T> p2, @Nullable final EntityPredicate<T> p3, @Nullable final T p4);
    
    void release();
    
    default <T extends PrefabBufferCall> boolean compare(@Nonnull final BlockComparingPredicate<T> blockComparingPredicate, @Nonnull final T t) {
        return this.forEachRaw(iterateAllColumns(), (x, y, z, blockId, chance, holder, support, rotation, filler, o) -> blockComparingPredicate.test(x, y, z, blockId, rotation, holder, o), (x, y, z, fluidId, level, o) -> true, (x, z, entityWrappers, o) -> true, t);
    }
    
    default <T extends PrefabBufferCall> boolean compare(@Nonnull final BlockComparingPrefabPredicate<T> blockComparingIterator, @Nonnull final T t, @Nonnull final IPrefabBuffer secondPrefab) {
        throw new UnsupportedOperationException("Not implemented! Please implement some inefficient default here!");
    }
    
    int getBlockId(final int p0, final int p1, final int p2);
    
    int getFiller(final int p0, final int p1, final int p2);
    
    int getRotationIndex(final int p0, final int p1, final int p2);
    
    @Nonnull
    default <T> ColumnPredicate<T> iterateAllColumns() {
        return (ColumnPredicate<T>)IPrefabBuffer.ALL_COLUMNS;
    }
    
    @FunctionalInterface
    public interface ColumnPredicate<T>
    {
        boolean test(final int p0, final int p1, final int p2, final T p3);
    }
    
    @FunctionalInterface
    public interface BlockComparingPredicate<T>
    {
        boolean test(final int p0, final int p1, final int p2, final int p3, final int p4, final Holder<ChunkStore> p5, final T p6);
    }
    
    @FunctionalInterface
    public interface RawBlockPredicate<T>
    {
        boolean test(final int p0, final int p1, final int p2, final int p3, final float p4, final Holder<ChunkStore> p5, final int p6, final int p7, final int p8, final T p9);
    }
    
    @FunctionalInterface
    public interface FluidPredicate<T>
    {
        boolean test(final int p0, final int p1, final int p2, final int p3, final byte p4, final T p5);
    }
    
    @FunctionalInterface
    public interface EntityPredicate<T>
    {
        boolean test(final int p0, final int p1, @Nonnull final Holder<EntityStore>[] p2, final T p3);
    }
    
    @FunctionalInterface
    public interface BlockComparingPrefabPredicate<T>
    {
        boolean test(final int p0, final int p1, final int p2, final int p3, final Holder<ChunkStore> p4, final float p5, final int p6, final int p7, final int p8, final Holder<ChunkStore> p9, final float p10, final int p11, final int p12, final T p13);
    }
    
    @FunctionalInterface
    public interface RawBlockConsumer<T>
    {
        void accept(final int p0, final int p1, final int p2, final int p3, final int p4, final float p5, final Holder<ChunkStore> p6, final int p7, final int p8, final int p9, final T p10);
    }
    
    @FunctionalInterface
    public interface EntityConsumer<T>
    {
        void accept(final int p0, final int p1, @Nullable final Holder<EntityStore>[] p2, final T p3);
    }
    
    @FunctionalInterface
    public interface ChildConsumer<T>
    {
        void accept(final int p0, final int p1, final int p2, final String p3, final boolean p4, final boolean p5, final boolean p6, final PrefabWeights p7, final PrefabRotation p8, final T p9);
    }
    
    @FunctionalInterface
    public interface FluidConsumer<T>
    {
        void accept(final int p0, final int p1, final int p2, final int p3, final byte p4, final T p5);
    }
    
    @FunctionalInterface
    public interface BlockConsumer<T>
    {
        void accept(final int p0, final int p1, final int p2, final int p3, @Nullable final Holder<ChunkStore> p4, final int p5, final int p6, final int p7, final T p8, final int p9, final int p10);
    }
}
