package common.block;

import common.entity.item.EntityFalling;
import common.entity.npc.EntityNPC;
import common.init.Config;
import common.material.Material;
import common.model.Model;
import common.model.ModelProvider;
import common.model.ParticleType;
import common.rng.Random;
import common.util.BlockPos;
import common.util.Facing;
import common.world.IWorldAccess;
import common.world.State;
import common.world.World;
import common.world.AWorldServer;

public class BlockDragonEgg extends Block
{
	private static final Model dragon_egg = ModelProvider.getModelProvider().getModel("dragon_egg").noOcclude()
			.add(6, 15, 6, 10, 16, 10)
				.d().uv(6, 6, 10, 10).noCull()
				.u().uv(6, 6, 10, 10).noCull()
				.n().uv(6, 15, 10, 16).noCull()
				.s().uv(6, 15, 10, 16).noCull()
				.w().uv(6, 15, 10, 16).noCull()
				.e().uv(6, 15, 10, 16).noCull()
			.add(5, 14, 5, 11, 15, 11)
				.d().uv(5, 5, 11, 11).noCull()
				.u().uv(5, 5, 11, 11).noCull()
				.n().uv(5, 14, 11, 15).noCull()
				.s().uv(5, 14, 11, 15).noCull()
				.w().uv(5, 14, 11, 15).noCull()
				.e().uv(5, 14, 11, 15).noCull()
			.add(5, 13, 5, 11, 14, 11)
				.d().uv(4, 4, 12, 12).noCull()
				.u().uv(4, 4, 12, 12).noCull()
				.n().uv(4, 13, 12, 14).noCull()
				.s().uv(4, 13, 12, 14).noCull()
				.w().uv(4, 13, 12, 14).noCull()
				.e().uv(4, 13, 12, 14).noCull()
			.add(3, 11, 3, 13, 13, 13)
				.d().uv(3, 3, 13, 13).noCull()
				.u().uv(3, 3, 13, 13).noCull()
				.n().uv(3, 11, 13, 13).noCull()
				.s().uv(3, 11, 13, 13).noCull()
				.w().uv(3, 11, 13, 13).noCull()
				.e().uv(3, 11, 13, 13).noCull()
			.add(2, 8, 2, 14, 11, 14)
				.d().uv(2, 2, 14, 14).noCull()
				.u().uv(2, 2, 14, 14).noCull()
				.n().uv(2, 8, 14, 11).noCull()
				.s().uv(2, 8, 14, 11).noCull()
				.w().uv(2, 8, 14, 11).noCull()
				.e().uv(2, 8, 14, 11).noCull()
			.add(1, 3, 1, 15, 8, 15)
				.d().uv(1, 1, 15, 15).noCull()
				.u().uv(1, 1, 15, 15).noCull()
				.n().uv(1, 3, 15, 8).noCull()
				.s().uv(1, 3, 15, 8).noCull()
				.w().uv(1, 3, 15, 8).noCull()
				.e().uv(1, 3, 15, 8).noCull()
			.add(2, 1, 2, 14, 3, 14)
				.d().uv(2, 2, 14, 14).noCull()
				.u().uv(2, 2, 14, 14).noCull()
				.n().uv(2, 1, 14, 3).noCull()
				.s().uv(2, 1, 14, 3).noCull()
				.w().uv(2, 1, 14, 3).noCull()
				.e().uv(2, 1, 14, 3).noCull()
			.add(3, 0, 3, 13, 1, 13)
				.d().uv(3, 3, 13, 13).noCull()
				.u().uv(3, 3, 13, 13).noCull()
				.n().uv(3, 0, 13, 1).noCull()
				.s().uv(3, 0, 13, 1).noCull()
				.w().uv(3, 0, 13, 1).noCull()
				.e().uv(3, 0, 13, 1).noCull()
	;
	
    public BlockDragonEgg()
    {
        super(Material.dragonEgg);
        this.setBlockBounds(0.0625F, 0.0F, 0.0625F, 0.9375F, 1.0F, 0.9375F);
    }

    public void onBlockAdded(AWorldServer worldIn, BlockPos pos, State state)
    {
        worldIn.scheduleUpdate(pos, this, this.tickRate(worldIn, pos));
    }

    /**
     * Called when a neighboring block changes.
     */
    public void onNeighborBlockChange(World worldIn, BlockPos pos, State state, Block neighborBlock)
    {
        worldIn.scheduleUpdate(pos, this, this.tickRate(worldIn, pos));
    }

    public void updateTick(AWorldServer worldIn, BlockPos pos, State state, Random rand)
    {
    	if(Config.blockGravity)
    		this.checkFall(worldIn, pos);
    }

    private void checkFall(World worldIn, BlockPos pos)
    {
        if (BlockFalling.canFallInto(worldIn, pos.down()) && pos.getY() >= 0)
        {
            int i = 32;

            if (!BlockFalling.fallInstantly && worldIn.isAreaLoaded(pos.add(-i, -i, -i), pos.add(i, i, i)))
            {
                worldIn.spawnEntityInWorld(new EntityFalling(worldIn, (double)((float)pos.getX() + 0.5F), (double)pos.getY(), (double)((float)pos.getZ() + 0.5F), this.getState()));
            }
            else
            {
                worldIn.setBlockToAir(pos);
                BlockPos blockpos;
                for(blockpos = pos; BlockFalling.canFallInto(worldIn, blockpos) && blockpos.getY() > 0; blockpos = blockpos.down()) {
                }
                if(blockpos != pos)
                	blockpos = blockpos.up();
                if(blockpos.getY() > 0)
                    worldIn.setState(blockpos, this.getState(), 2);
            }
        }
    }

    public boolean onBlockActivated(World worldIn, BlockPos pos, State state, EntityNPC playerIn, Facing side, float hitX, float hitY, float hitZ)
    {
        this.teleport(worldIn, pos);
        return true;
    }

    public void onBlockClicked(World worldIn, BlockPos pos, EntityNPC playerIn)
    {
        this.teleport(worldIn, pos);
    }

    private void teleport(World worldIn, BlockPos pos)
    {
        State iblockstate = worldIn.getState(pos);

        if (iblockstate.getBlock() == this)
        {
            for (int i = 0; i < 1000; ++i)
            {
                BlockPos blockpos = pos.add(worldIn.rand.zrange(16) - worldIn.rand.zrange(16), worldIn.rand.zrange(8) - worldIn.rand.zrange(8), worldIn.rand.zrange(16) - worldIn.rand.zrange(16));

                if (worldIn.getState(blockpos).getBlock().material == Material.air)
                {
                    if (worldIn.client)
                    {
                        for (int j = 0; j < 128; ++j)
                        {
                            double d0 = worldIn.rand.doublev();
                            float f = (worldIn.rand.floatv() - 0.5F) * 0.2F;
                            float f1 = (worldIn.rand.floatv() - 0.5F) * 0.2F;
                            float f2 = (worldIn.rand.floatv() - 0.5F) * 0.2F;
                            double d1 = (double)blockpos.getX() + (double)(pos.getX() - blockpos.getX()) * d0 + (worldIn.rand.doublev() - 0.5D) * 1.0D + 0.5D;
                            double d2 = (double)blockpos.getY() + (double)(pos.getY() - blockpos.getY()) * d0 + worldIn.rand.doublev() * 1.0D - 0.5D;
                            double d3 = (double)blockpos.getZ() + (double)(pos.getZ() - blockpos.getZ()) * d0 + (worldIn.rand.doublev() - 0.5D) * 1.0D + 0.5D;
                            worldIn.spawnParticle(ParticleType.PORTAL, d1, d2, d3, (double)f, (double)f1, (double)f2);
                        }
                    }
                    else
                    {
                        worldIn.setBlockToAir(pos);
                        if(!Config.blockGravity) {
                            BlockPos blockpos2;
	                        for(blockpos2 = blockpos; BlockFalling.canFallInto(worldIn, blockpos2) && blockpos2.getY() > 0; blockpos2 = blockpos2.down()) {
	                        }
	                        if(blockpos2 != blockpos)
	                        	blockpos = blockpos2.up();
                        }
                        worldIn.setState(blockpos, iblockstate, 2);
                    }

                    return;
                }
            }
        }
    }

    /**
     * How many world ticks before ticking
     */
    public int tickRate(World worldIn, BlockPos pos)
    {
        return 5;
    }

    /**
     * Used to determine ambient occlusion and culling when rebuilding chunks for render
     */
    public boolean isOpaqueCube()
    {
        return false;
    }

    public boolean isFullCube()
    {
        return false;
    }

    public boolean shouldSideBeRendered(IWorldAccess worldIn, BlockPos pos, Facing side)
    {
        return true;
    }

//    public Item getItem(World worldIn, BlockPos pos)
//    {
//        return null;
//    }

    public Model getModel(ModelProvider provider, String name, State state) {
    	return dragon_egg;
    }
}
