package common.block;

import java.util.List;
import java.util.Map;
import java.util.Set;

import common.collect.Sets;
import common.entity.Entity;
import common.item.Item;
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.BoundingBox;
import common.util.Facing;
import common.world.IWorldAccess;
import common.world.AWorldClient;
import common.world.State;
import common.world.World;

public class BlockFloorPortal extends Block
{
	private static final Model floor_portal = ModelProvider.getModelProvider().getModel("floor_portal")
			.add(0, 11, 0, 16, 12, 16).du().uv(0, 0, 16, 16).noCull().nswe().uv(0, 0, 16, 1);
	
	public BlockFloorPortal(Material materialIn)
    {
        super(materialIn);
        this.setLightLevel(1.0F);
    }

//    /**
//     * Returns a new instance of a block's tile entity class. Called on placing the block.
//     */
//    public TileEntity createNewTileEntity(World worldIn, int meta)
//    {
//        return new TileEntityPortal();
//    }

    public void setBlockBoundsBasedOnState(IWorldAccess worldIn, BlockPos pos)
    {
        this.setBlockBounds(0.0F, 0.6875F, 0.0F, 1.0F, 0.75F, 1.0F);
    }

//    public boolean shouldSideBeRendered(IWorldAccess worldIn, BlockPos pos, Facing side)
//    {
//        return side == Facing.DOWN ? super.shouldSideBeRendered(worldIn, pos, side) : false;
//    }

    /**
     * Add all collision boxes of this Block to the list that intersect with the given mask.
     */
    public void addCollisionBoxesToList(World worldIn, BlockPos pos, State state, BoundingBox mask, List<BoundingBox> list, Entity collidingEntity)
    {
    }

    /**
     * Used to determine ambient occlusion and culling when rebuilding chunks for render
     */
    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;
    }

    /**
     * Called When an Entity Collided with the Block
     */
    public void onEntityCollidedWithBlock(World worldIn, BlockPos pos, State state, Entity entityIn)
    {
//        if (entityIn.ridingEntity == null && entityIn.riddenByEntity == null && !worldIn.client && GameServer.getServer().getAllowEnd())
//        {
            // entityIn.travelToDimension(entityIn.dimension == 1 ? 0 : 1, null, 0.0f, 0.0f);
//        }
    	if(entityIn.getEntityBoundingBox().intersectsWith(this.getCollisionBoundingBox(worldIn, pos, state)))
    		entityIn.setFlatPortal();
    }

    public void randomDisplayTick(AWorldClient worldIn, BlockPos pos, State state, Random rand)
    {
        double d0 = (double)((float)pos.getX() + rand.floatv());
        double d1 = (double)((float)pos.getY() + 0.8F);
        double d2 = (double)((float)pos.getZ() + rand.floatv());
        double d3 = 0.0D;
        double d4 = 0.0D;
        double d5 = 0.0D;
        worldIn.spawnParticle(ParticleType.SMOKE_NORMAL, d0, d1, d2, d3, d4, d5);
    }

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

//    /**
//     * Get the MapColor for this Block and the given BlockState
//     */
//    public MapColor getMapColor(IBlockState state)
//    {
//        return MapColor.blackColor;
//    }
    
    private void destroyRecursive(World world, Set<BlockPos> positions, BlockPos pos, int limit) {
    	for(int n = 0; n < 4; n++) {
    		BlockPos npos = pos.offset(Facing.getHorizontal(n));
    		if(/* !positions.contains(npos) && */ world.getState(npos).getBlock() == this) {
    			positions.add(npos);
    			if(limit > 0)
    				destroyRecursive(world, positions, npos, limit-1);
    		}
    	}
    }

    public void onBlockDestroyedByPlayer(World worldIn, BlockPos pos, State state)
    {
    	Set<BlockPos> positions = Sets.newHashSet();
    	positions.add(pos);
    	this.destroyRecursive(worldIn, positions, pos, 10);
    	for(BlockPos bpos : positions)
			worldIn.setBlockToAir(bpos);
//    	for(int x = -2; x <= 2; x++) {
//        	for(int z = -2; z <= 2; z++) {
//        		BlockPos bpos = pos.add(x, 0, z);
//        		if((x != 0 || z != 0) && worldIn.getBlockState(bpos).getBlock() == this)
//        			worldIn.setBlockToAir(bpos);
//        	}
//    	}
    }
    
    public boolean isXrayVisible()
    {
        return true;
    }

    public Model getModel(ModelProvider provider, String name, State state) {
    	return floor_portal;
    }
    
    public void getAnimatedTextures(Map<String, Object> map) {
    	map.put("blocks/floor_portal", 5);
    }
}
