package net.minecraft.block;

import com.google.common.collect.Maps;
import java.util.Map;
import java.util.Random;
import net.minecraft.block.material.MapColor;
import net.minecraft.block.material.Material;
import net.minecraft.block.properties.IProperty;
import net.minecraft.block.properties.PropertyBool;
import net.minecraft.block.properties.PropertyInteger;
import net.minecraft.block.state.BlockState;
import net.minecraft.block.state.IBlockState;
import net.minecraft.init.Blocks;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.util.BlockPos;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumParticleTypes;
import net.minecraft.util.EnumWorldBlockLayer;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import net.minecraft.world.WorldProviderEnd;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;

public class BlockFire extends Block
{
    public static final PropertyInteger field_176543_a = PropertyInteger.create("age", 0, 15);
    public static final PropertyBool field_176540_b = PropertyBool.create("flip");
    public static final PropertyBool field_176544_M = PropertyBool.create("alt");
    public static final PropertyBool field_176545_N = PropertyBool.create("north");
    public static final PropertyBool field_176546_O = PropertyBool.create("east");
    public static final PropertyBool field_176541_P = PropertyBool.create("south");
    public static final PropertyBool field_176539_Q = PropertyBool.create("west");
    public static final PropertyInteger field_176542_R = PropertyInteger.create("upper", 0, 2);
    private final Map field_149849_a = Maps.newIdentityHashMap();
    private final Map field_149848_b = Maps.newIdentityHashMap();
    private static final String __OBFID = "CL_00000245";

    /**
     * Get the actual Block state of this Block at the given position. This applies properties not visible in the
     * metadata, such as fence connections.
     */
    public IBlockState getActualState(IBlockState state, IBlockAccess worldIn, BlockPos pos)
    {
        int i = pos.getX();
        int j = pos.getY();
        int k = pos.getZ();

        if (!World.doesBlockHaveSolidTopSurface(worldIn, pos.offsetDown()) && !Blocks.fire.canCatchFire(worldIn, pos.offsetDown(), EnumFacing.UP))
        {
            boolean flag = (i + j + k & 1) == 1;
            boolean flag1 = (i / 2 + j / 2 + k / 2 & 1) == 1;
            int l = 0;

            if (this.canCatchFire(worldIn, pos.offsetUp(), EnumFacing.DOWN))
            {
                l = flag ? 1 : 2;
            }

            return state.withProperty(field_176545_N, Boolean.valueOf(this.canCatchFire(worldIn, pos.offsetNorth(), EnumFacing.SOUTH)))
                        .withProperty(field_176546_O, Boolean.valueOf(this.canCatchFire(worldIn, pos.offsetEast(),  EnumFacing.EAST )))
                        .withProperty(field_176541_P, Boolean.valueOf(this.canCatchFire(worldIn, pos.offsetSouth(), EnumFacing.NORTH)))
                        .withProperty(field_176539_Q, Boolean.valueOf(this.canCatchFire(worldIn, pos.offsetWest(),  EnumFacing.EAST )))
                        .withProperty(field_176542_R, Integer.valueOf(l))
                        .withProperty(field_176540_b, Boolean.valueOf(flag1))
                        .withProperty(field_176544_M, Boolean.valueOf(flag));
        }
        else
        {
            return this.getDefaultState();
        }
    }

    protected BlockFire()
    {
        super(Material.fire);
        this.setDefaultState(this.blockState.getBaseState().withProperty(field_176543_a, Integer.valueOf(0)).withProperty(field_176540_b, Boolean.valueOf(false)).withProperty(field_176544_M, Boolean.valueOf(false)).withProperty(field_176545_N, Boolean.valueOf(false)).withProperty(field_176546_O, Boolean.valueOf(false)).withProperty(field_176541_P, Boolean.valueOf(false)).withProperty(field_176539_Q, Boolean.valueOf(false)).withProperty(field_176542_R, Integer.valueOf(0)));
        this.setTickRandomly(true);
    }

    public static void func_149843_e()
    {
        Blocks.fire.func_180686_a(Blocks.planks, 5, 20);
        Blocks.fire.func_180686_a(Blocks.double_wooden_slab, 5, 20);
        Blocks.fire.func_180686_a(Blocks.wooden_slab, 5, 20);
        Blocks.fire.func_180686_a(Blocks.oak_fence_gate, 5, 20);
        Blocks.fire.func_180686_a(Blocks.spruce_fence_gate, 5, 20);
        Blocks.fire.func_180686_a(Blocks.birch_fence_gate, 5, 20);
        Blocks.fire.func_180686_a(Blocks.jungle_fence_gate, 5, 20);
        Blocks.fire.func_180686_a(Blocks.dark_oak_fence_gate, 5, 20);
        Blocks.fire.func_180686_a(Blocks.acacia_fence_gate, 5, 20);
        Blocks.fire.func_180686_a(Blocks.oak_fence, 5, 20);
        Blocks.fire.func_180686_a(Blocks.spruce_fence, 5, 20);
        Blocks.fire.func_180686_a(Blocks.birch_fence, 5, 20);
        Blocks.fire.func_180686_a(Blocks.jungle_fence, 5, 20);
        Blocks.fire.func_180686_a(Blocks.dark_oak_fence, 5, 20);
        Blocks.fire.func_180686_a(Blocks.acacia_fence, 5, 20);
        Blocks.fire.func_180686_a(Blocks.oak_stairs, 5, 20);
        Blocks.fire.func_180686_a(Blocks.birch_stairs, 5, 20);
        Blocks.fire.func_180686_a(Blocks.spruce_stairs, 5, 20);
        Blocks.fire.func_180686_a(Blocks.jungle_stairs, 5, 20);
        Blocks.fire.func_180686_a(Blocks.log, 5, 5);
        Blocks.fire.func_180686_a(Blocks.log2, 5, 5);
        Blocks.fire.func_180686_a(Blocks.leaves, 30, 60);
        Blocks.fire.func_180686_a(Blocks.leaves2, 30, 60);
        Blocks.fire.func_180686_a(Blocks.bookshelf, 30, 20);
        Blocks.fire.func_180686_a(Blocks.tnt, 15, 100);
        Blocks.fire.func_180686_a(Blocks.tallgrass, 60, 100);
        Blocks.fire.func_180686_a(Blocks.double_plant, 60, 100);
        Blocks.fire.func_180686_a(Blocks.yellow_flower, 60, 100);
        Blocks.fire.func_180686_a(Blocks.red_flower, 60, 100);
        Blocks.fire.func_180686_a(Blocks.deadbush, 60, 100);
        Blocks.fire.func_180686_a(Blocks.wool, 30, 60);
        Blocks.fire.func_180686_a(Blocks.vine, 15, 100);
        Blocks.fire.func_180686_a(Blocks.coal_block, 5, 5);
        Blocks.fire.func_180686_a(Blocks.hay_block, 60, 20);
        Blocks.fire.func_180686_a(Blocks.carpet, 60, 20);
    }

    public void func_180686_a(Block p_180686_1_, int p_180686_2_, int p_180686_3_)
    {
        if (p_180686_1_ == Blocks.air) throw new IllegalArgumentException("Tried to set air on fire... This is bad.");
        this.field_149849_a.put(p_180686_1_, Integer.valueOf(p_180686_2_));
        this.field_149848_b.put(p_180686_1_, Integer.valueOf(p_180686_3_));
    }

    public AxisAlignedBB getCollisionBoundingBox(World worldIn, BlockPos pos, IBlockState state)
    {
        return null;
    }

    public boolean isOpaqueCube()
    {
        return false;
    }

    public boolean isFullCube()
    {
        return false;
    }

    /**
     * Returns the quantity of items to drop on block destruction.
     */
    public int quantityDropped(Random random)
    {
        return 0;
    }

    /**
     * How many world ticks before ticking
     */
    public int tickRate(World worldIn)
    {
        return 30;
    }

    public void updateTick(World worldIn, BlockPos pos, IBlockState state, Random rand)
    {
        if (worldIn.getGameRules().getGameRuleBooleanValue("doFireTick"))
        {
            if (!this.canPlaceBlockAt(worldIn, pos))
            {
                worldIn.setBlockToAir(pos);
            }

            Block block = worldIn.getBlockState(pos.offsetDown()).getBlock();
            boolean flag = block.isFireSource(worldIn, pos.offsetDown(), EnumFacing.UP);

            if (!flag && worldIn.isRaining() && this.func_176537_d(worldIn, pos))
            {
                worldIn.setBlockToAir(pos);
            }
            else
            {
                int i = ((Integer)state.getValue(field_176543_a)).intValue();

                if (i < 15)
                {
                    state = state.withProperty(field_176543_a, Integer.valueOf(i + rand.nextInt(3) / 2));
                    worldIn.setBlockState(pos, state, 4);
                }

                worldIn.scheduleUpdate(pos, this, this.tickRate(worldIn) + rand.nextInt(10));

                if (!flag)
                {
                    if (!this.func_176533_e(worldIn, pos))
                    {
                        if (!World.doesBlockHaveSolidTopSurface(worldIn, pos.offsetDown()) || i > 3)
                        {
                            worldIn.setBlockToAir(pos);
                        }

                        return;
                    }

                    if (!this.canCatchFire(worldIn, pos.offsetDown(), EnumFacing.UP) && i == 15 && rand.nextInt(4) == 0)
                    {
                        worldIn.setBlockToAir(pos);
                        return;
                    }
                }

                boolean flag1 = worldIn.func_180502_D(pos);
                byte b0 = 0;

                if (flag1)
                {
                    b0 = -50;
                }

                this.tryCatchFire(worldIn, pos.offsetEast(), 300 + b0, rand, i, EnumFacing.WEST);
                this.tryCatchFire(worldIn, pos.offsetWest(), 300 + b0, rand, i, EnumFacing.EAST);
                this.tryCatchFire(worldIn, pos.offsetDown(), 250 + b0, rand, i, EnumFacing.UP);
                this.tryCatchFire(worldIn, pos.offsetUp(), 250 + b0, rand, i, EnumFacing.DOWN);
                this.tryCatchFire(worldIn, pos.offsetNorth(), 300 + b0, rand, i, EnumFacing.SOUTH);
                this.tryCatchFire(worldIn, pos.offsetSouth(), 300 + b0, rand, i, EnumFacing.NORTH);

                for (int j = -1; j <= 1; ++j)
                {
                    for (int k = -1; k <= 1; ++k)
                    {
                        for (int l = -1; l <= 4; ++l)
                        {
                            if (j != 0 || l != 0 || k != 0)
                            {
                                int i1 = 100;

                                if (l > 1)
                                {
                                    i1 += (l - 1) * 100;
                                }

                                BlockPos blockpos1 = pos.add(j, l, k);
                                int j1 = this.func_176538_m(worldIn, blockpos1);

                                if (j1 > 0)
                                {
                                    int k1 = (j1 + 40 + worldIn.getDifficulty().getDifficultyId() * 7) / (i + 30);

                                    if (flag1)
                                    {
                                        k1 /= 2;
                                    }

                                    if (k1 > 0 && rand.nextInt(i1) <= k1 && (!worldIn.isRaining() || !this.func_176537_d(worldIn, blockpos1)))
                                    {
                                        int l1 = i + rand.nextInt(5) / 4;

                                        if (l1 > 15)
                                        {
                                            l1 = 15;
                                        }

                                        worldIn.setBlockState(blockpos1, state.withProperty(field_176543_a, Integer.valueOf(l1)), 3);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    protected boolean func_176537_d(World worldIn, BlockPos p_176537_2_)
    {
        return worldIn.func_175727_C(p_176537_2_) || worldIn.func_175727_C(p_176537_2_.offsetWest()) || worldIn.func_175727_C(p_176537_2_.offsetEast()) || worldIn.func_175727_C(p_176537_2_.offsetNorth()) || worldIn.func_175727_C(p_176537_2_.offsetSouth());
    }

    public boolean requiresUpdates()
    {
        return false;
    }

    @Deprecated // Use Block.getFlammability
    public int func_176532_c(Block p_176532_1_)
    {
        Integer integer = (Integer)this.field_149848_b.get(p_176532_1_);
        return integer == null ? 0 : integer.intValue();
    }

    @Deprecated // Use Block.getFlammability
    public int func_176534_d(Block p_176534_1_)
    {
        Integer integer = (Integer)this.field_149849_a.get(p_176534_1_);
        return integer == null ? 0 : integer.intValue();
    }

    @Deprecated // Use tryCatchFire with face below
    private void func_176536_a(World worldIn, BlockPos p_176536_2_, int p_176536_3_, Random p_176536_4_, int p_176536_5_)
    {
        this.tryCatchFire(worldIn, p_176536_2_, p_176536_3_, p_176536_4_, p_176536_5_, EnumFacing.UP);
    }

    private void tryCatchFire(World worldIn, BlockPos p_176536_2_, int p_176536_3_, Random p_176536_4_, int p_176536_5_, EnumFacing face)
    {
        int k = worldIn.getBlockState(p_176536_2_).getBlock().getFlammability(worldIn, p_176536_2_, face);

        if (p_176536_4_.nextInt(p_176536_3_) < k)
        {
            IBlockState iblockstate = worldIn.getBlockState(p_176536_2_);

            if (p_176536_4_.nextInt(p_176536_5_ + 10) < 5 && !worldIn.func_175727_C(p_176536_2_))
            {
                int l = p_176536_5_ + p_176536_4_.nextInt(5) / 4;

                if (l > 15)
                {
                    l = 15;
                }

                worldIn.setBlockState(p_176536_2_, this.getDefaultState().withProperty(field_176543_a, Integer.valueOf(l)), 3);
            }
            else
            {
                worldIn.setBlockToAir(p_176536_2_);
            }

            if (iblockstate.getBlock() == Blocks.tnt)
            {
                Blocks.tnt.onBlockDestroyedByPlayer(worldIn, p_176536_2_, iblockstate.withProperty(BlockTNT.EXPLODE_PROP, Boolean.valueOf(true)));
            }
        }
    }

    private boolean func_176533_e(World worldIn, BlockPos p_176533_2_)
    {
        EnumFacing[] aenumfacing = EnumFacing.values();
        int i = aenumfacing.length;

        for (int j = 0; j < i; ++j)
        {
            EnumFacing enumfacing = aenumfacing[j];

            if (this.canCatchFire(worldIn, p_176533_2_.offset(enumfacing), enumfacing.getOpposite()))
            {
                return true;
            }
        }

        return false;
    }

    private int func_176538_m(World worldIn, BlockPos p_176538_2_)
    {
        if (!worldIn.isAirBlock(p_176538_2_))
        {
            return 0;
        }
        else
        {
            int i = 0;
            EnumFacing[] aenumfacing = EnumFacing.values();
            int j = aenumfacing.length;

            for (int k = 0; k < j; ++k)
            {
                EnumFacing enumfacing = aenumfacing[k];
                i = Math.max(worldIn.getBlockState(p_176538_2_.offset(enumfacing)).getBlock().getFlammability(worldIn, p_176538_2_.offset(enumfacing), enumfacing.getOpposite()), i);
            }

            return i;
        }
    }

    /**
     * Returns if this block is collidable (only used by Fire). Args: x, y, z
     */
    public boolean isCollidable()
    {
        return false;
    }

    @Deprecated // Use canCatchFire with face sensitive version below
    public boolean func_176535_e(IBlockAccess p_176535_1_, BlockPos p_176535_2_)
    {
        return canCatchFire(p_176535_1_, p_176535_2_, EnumFacing.UP);
    }

    public boolean canPlaceBlockAt(World worldIn, BlockPos pos)
    {
        return World.doesBlockHaveSolidTopSurface(worldIn, pos.offsetDown()) || this.func_176533_e(worldIn, pos);
    }

    public void onNeighborBlockChange(World worldIn, BlockPos pos, IBlockState state, Block neighborBlock)
    {
        if (!World.doesBlockHaveSolidTopSurface(worldIn, pos.offsetDown()) && !this.func_176533_e(worldIn, pos))
        {
            worldIn.setBlockToAir(pos);
        }
    }

    public void onBlockAdded(World worldIn, BlockPos pos, IBlockState state)
    {
        if (worldIn.provider.getDimensionId() > 0 || !Blocks.portal.func_176548_d(worldIn, pos))
        {
            if (!World.doesBlockHaveSolidTopSurface(worldIn, pos.offsetDown()) && !this.func_176533_e(worldIn, pos))
            {
                worldIn.setBlockToAir(pos);
            }
            else
            {
                worldIn.scheduleUpdate(pos, this, this.tickRate(worldIn) + worldIn.rand.nextInt(10));
            }
        }
    }

    @SideOnly(Side.CLIENT)
    public void randomDisplayTick(World worldIn, BlockPos pos, IBlockState state, Random rand)
    {
        if (rand.nextInt(24) == 0)
        {
            worldIn.playSound((double)((float)pos.getX() + 0.5F), (double)((float)pos.getY() + 0.5F), (double)((float)pos.getZ() + 0.5F), "fire.fire", 1.0F + rand.nextFloat(), rand.nextFloat() * 0.7F + 0.3F, false);
        }

        int i;
        double d0;
        double d1;
        double d2;

        if (!World.doesBlockHaveSolidTopSurface(worldIn, pos.offsetDown()) && !Blocks.fire.canCatchFire(worldIn, pos.offsetDown(), EnumFacing.UP))
        {
            if (Blocks.fire.canCatchFire(worldIn, pos.offsetWest(), EnumFacing.EAST))
            {
                for (i = 0; i < 2; ++i)
                {
                    d0 = (double)pos.getX() + rand.nextDouble() * 0.10000000149011612D;
                    d1 = (double)pos.getY() + rand.nextDouble();
                    d2 = (double)pos.getZ() + rand.nextDouble();
                    worldIn.spawnParticle(EnumParticleTypes.SMOKE_LARGE, d0, d1, d2, 0.0D, 0.0D, 0.0D, new int[0]);
                }
            }

            if (Blocks.fire.canCatchFire(worldIn, pos.offsetEast(), EnumFacing.WEST))
            {
                for (i = 0; i < 2; ++i)
                {
                    d0 = (double)(pos.getX() + 1) - rand.nextDouble() * 0.10000000149011612D;
                    d1 = (double)pos.getY() + rand.nextDouble();
                    d2 = (double)pos.getZ() + rand.nextDouble();
                    worldIn.spawnParticle(EnumParticleTypes.SMOKE_LARGE, d0, d1, d2, 0.0D, 0.0D, 0.0D, new int[0]);
                }
            }

            if (Blocks.fire.canCatchFire(worldIn, pos.offsetNorth(), EnumFacing.SOUTH))
            {
                for (i = 0; i < 2; ++i)
                {
                    d0 = (double)pos.getX() + rand.nextDouble();
                    d1 = (double)pos.getY() + rand.nextDouble();
                    d2 = (double)pos.getZ() + rand.nextDouble() * 0.10000000149011612D;
                    worldIn.spawnParticle(EnumParticleTypes.SMOKE_LARGE, d0, d1, d2, 0.0D, 0.0D, 0.0D, new int[0]);
                }
            }

            if (Blocks.fire.canCatchFire(worldIn, pos.offsetSouth(), EnumFacing.NORTH))
            {
                for (i = 0; i < 2; ++i)
                {
                    d0 = (double)pos.getX() + rand.nextDouble();
                    d1 = (double)pos.getY() + rand.nextDouble();
                    d2 = (double)(pos.getZ() + 1) - rand.nextDouble() * 0.10000000149011612D;
                    worldIn.spawnParticle(EnumParticleTypes.SMOKE_LARGE, d0, d1, d2, 0.0D, 0.0D, 0.0D, new int[0]);
                }
            }

            if (Blocks.fire.canCatchFire(worldIn, pos.offsetUp(), EnumFacing.DOWN))
            {
                for (i = 0; i < 2; ++i)
                {
                    d0 = (double)pos.getX() + rand.nextDouble();
                    d1 = (double)(pos.getY() + 1) - rand.nextDouble() * 0.10000000149011612D;
                    d2 = (double)pos.getZ() + rand.nextDouble();
                    worldIn.spawnParticle(EnumParticleTypes.SMOKE_LARGE, d0, d1, d2, 0.0D, 0.0D, 0.0D, new int[0]);
                }
            }
        }
        else
        {
            for (i = 0; i < 3; ++i)
            {
                d0 = (double)pos.getX() + rand.nextDouble();
                d1 = (double)pos.getY() + rand.nextDouble() * 0.5D + 0.5D;
                d2 = (double)pos.getZ() + rand.nextDouble();
                worldIn.spawnParticle(EnumParticleTypes.SMOKE_LARGE, d0, d1, d2, 0.0D, 0.0D, 0.0D, new int[0]);
            }
        }
    }

    /**
     * Get the MapColor for this Block and the given BlockState
     */
    public MapColor getMapColor(IBlockState state)
    {
        return MapColor.tntColor;
    }

    @SideOnly(Side.CLIENT)
    public EnumWorldBlockLayer getBlockLayer()
    {
        return EnumWorldBlockLayer.CUTOUT;
    }

    /**
     * Convert the given metadata into a BlockState for this Block
     */
    public IBlockState getStateFromMeta(int meta)
    {
        return this.getDefaultState().withProperty(field_176543_a, Integer.valueOf(meta));
    }

    /**
     * Convert the BlockState into the correct metadata value
     */
    public int getMetaFromState(IBlockState state)
    {
        return ((Integer)state.getValue(field_176543_a)).intValue();
    }

    protected BlockState createBlockState()
    {
        return new BlockState(this, new IProperty[] {field_176543_a, field_176545_N, field_176546_O, field_176541_P, field_176539_Q, field_176542_R, field_176540_b, field_176544_M});
    }

    /*================================= Forge Start ======================================*/
    /**
     * Side sensitive version that calls the block function.
     *
     * @param world The current world
     * @param pos Block position
     * @param face The side the fire is coming from
     * @return True if the face can catch fire.
     */
    public boolean canCatchFire(IBlockAccess world, BlockPos pos, EnumFacing face)
    {
        return world.getBlockState(pos).getBlock().isFlammable(world, pos, face);
    }
    /*================================= Forge Start ======================================*/
}