package net.minecraft.block.state.pattern;

import com.google.common.base.Predicate;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.LoadingCache;
import java.util.Iterator;
import net.minecraft.block.state.BlockWorldState;
import net.minecraft.util.BlockPos;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.Vec3i;
import net.minecraft.world.World;

public class BlockPattern
{
    private final Predicate[][][] field_177689_a;
    private final int field_177687_b;
    private final int field_177688_c;
    private final int field_177686_d;
    private static final String __OBFID = "CL_00002024";

    public BlockPattern(Predicate[][][] p_i45657_1_)
    {
        this.field_177689_a = p_i45657_1_;
        this.field_177687_b = p_i45657_1_.length;

        if (this.field_177687_b > 0)
        {
            this.field_177688_c = p_i45657_1_[0].length;

            if (this.field_177688_c > 0)
            {
                this.field_177686_d = p_i45657_1_[0][0].length;
            }
            else
            {
                this.field_177686_d = 0;
            }
        }
        else
        {
            this.field_177688_c = 0;
            this.field_177686_d = 0;
        }
    }

    public int func_177685_b()
    {
        return this.field_177688_c;
    }

    public int func_177684_c()
    {
        return this.field_177686_d;
    }

    private BlockPattern.PatternHelper func_177682_a(BlockPos p_177682_1_, EnumFacing p_177682_2_, EnumFacing p_177682_3_, LoadingCache p_177682_4_)
    {
        for (int i = 0; i < this.field_177686_d; ++i)
        {
            for (int j = 0; j < this.field_177688_c; ++j)
            {
                for (int k = 0; k < this.field_177687_b; ++k)
                {
                    if (!this.field_177689_a[k][j][i].apply(p_177682_4_.getUnchecked(func_177683_a(p_177682_1_, p_177682_2_, p_177682_3_, i, j, k))))
                    {
                        return null;
                    }
                }
            }
        }

        return new BlockPattern.PatternHelper(p_177682_1_, p_177682_2_, p_177682_3_, p_177682_4_);
    }

    public BlockPattern.PatternHelper func_177681_a(World worldIn, BlockPos p_177681_2_)
    {
        LoadingCache loadingcache = CacheBuilder.newBuilder().build(new BlockPattern.CacheLoader(worldIn));
        int i = Math.max(Math.max(this.field_177686_d, this.field_177688_c), this.field_177687_b);
        Iterator iterator = BlockPos.getAllInBox(p_177681_2_, p_177681_2_.add(i - 1, i - 1, i - 1)).iterator();

        while (iterator.hasNext())
        {
            BlockPos blockpos1 = (BlockPos)iterator.next();
            EnumFacing[] aenumfacing = EnumFacing.values();
            int j = aenumfacing.length;

            for (int k = 0; k < j; ++k)
            {
                EnumFacing enumfacing = aenumfacing[k];
                EnumFacing[] aenumfacing1 = EnumFacing.values();
                int l = aenumfacing1.length;

                for (int i1 = 0; i1 < l; ++i1)
                {
                    EnumFacing enumfacing1 = aenumfacing1[i1];

                    if (enumfacing1 != enumfacing && enumfacing1 != enumfacing.getOpposite())
                    {
                        BlockPattern.PatternHelper patternhelper = this.func_177682_a(blockpos1, enumfacing, enumfacing1, loadingcache);

                        if (patternhelper != null)
                        {
                            return patternhelper;
                        }
                    }
                }
            }
        }

        return null;
    }

    protected static BlockPos func_177683_a(BlockPos p_177683_0_, EnumFacing p_177683_1_, EnumFacing p_177683_2_, int p_177683_3_, int p_177683_4_, int p_177683_5_)
    {
        if (p_177683_1_ != p_177683_2_ && p_177683_1_ != p_177683_2_.getOpposite())
        {
            Vec3i vec3i = new Vec3i(p_177683_1_.getFrontOffsetX(), p_177683_1_.getFrontOffsetY(), p_177683_1_.getFrontOffsetZ());
            Vec3i vec3i1 = new Vec3i(p_177683_2_.getFrontOffsetX(), p_177683_2_.getFrontOffsetY(), p_177683_2_.getFrontOffsetZ());
            Vec3i vec3i2 = vec3i.crossProduct(vec3i1);
            return p_177683_0_.add(vec3i1.getX() * -p_177683_4_ + vec3i2.getX() * p_177683_3_ + vec3i.getX() * p_177683_5_, vec3i1.getY() * -p_177683_4_ + vec3i2.getY() * p_177683_3_ + vec3i.getY() * p_177683_5_, vec3i1.getZ() * -p_177683_4_ + vec3i2.getZ() * p_177683_3_ + vec3i.getZ() * p_177683_5_);
        }
        else
        {
            throw new IllegalArgumentException("Invalid forwards & up combination");
        }
    }

    static class CacheLoader extends com.google.common.cache.CacheLoader
        {
            private final World field_177680_a;
            private static final String __OBFID = "CL_00002023";

            public CacheLoader(World worldIn)
            {
                this.field_177680_a = worldIn;
            }

            public BlockWorldState func_177679_a(BlockPos p_177679_1_)
            {
                return new BlockWorldState(this.field_177680_a, p_177679_1_);
            }

            public Object load(Object p_load_1_)
            {
                return this.func_177679_a((BlockPos)p_load_1_);
            }
        }

    public static class PatternHelper
        {
            private final BlockPos field_177674_a;
            private final EnumFacing field_177672_b;
            private final EnumFacing field_177673_c;
            private final LoadingCache field_177671_d;
            private static final String __OBFID = "CL_00002022";

            public PatternHelper(BlockPos p_i45655_1_, EnumFacing p_i45655_2_, EnumFacing p_i45655_3_, LoadingCache p_i45655_4_)
            {
                this.field_177674_a = p_i45655_1_;
                this.field_177672_b = p_i45655_2_;
                this.field_177673_c = p_i45655_3_;
                this.field_177671_d = p_i45655_4_;
            }

            public EnumFacing func_177669_b()
            {
                return this.field_177672_b;
            }

            public EnumFacing func_177668_c()
            {
                return this.field_177673_c;
            }

            public BlockWorldState func_177670_a(int p_177670_1_, int p_177670_2_, int p_177670_3_)
            {
                return (BlockWorldState)this.field_177671_d.getUnchecked(BlockPattern.func_177683_a(this.field_177674_a, this.func_177669_b(), this.func_177668_c(), p_177670_1_, p_177670_2_, p_177670_3_));
            }
        }
}