package net.minecraft.src;

import java.util.Random;

import net.minecraft.src.forge.ITextureProvider;

public class PCma_BlockReplacer extends BlockContainer implements PC_ISwapTerrain, PC_IBlockType, ITextureProvider {
	private static final int TXDOWN = 109, TXTOP = 125, TXSIDE = 125, TXFRONT = 125, TXBACK = 125;

	private int blockOffset[] = { 0, 0, 0 };

	protected PCma_BlockReplacer(int par1, int par2, Material par3Material) {
		super(par1, par2, par3Material);
	}

	protected PCma_BlockReplacer(int par1, Material par2Material) {
		super(par1, par2Material);
	}

	protected PCma_BlockReplacer(int par1) {
		super(par1, Material.ground);
	}

	@Override
	public String getTerrainFile() {
		return mod_PCmachines.getImgDir() + "tiles.png";
	}

	@Override
	public String getTextureFile() {
		return getTerrainFile();
	}

	@Override
	public boolean renderAsNormalBlock() {
		return true;
	}

	@Override
	public int getRenderType() {
		return PC_Renderer.swapTerrainRenderer;
	}

	@Override
	public int getBlockTextureFromSideAndMetadata(int s, int m) {
		if (s == 1) { return TXTOP; }
		if (s == 0) {
			return TXDOWN;
		} else {
			if (m == s) return TXFRONT;
			if ((m == 2 && s == 3) || (m == 3 && s == 2) || (m == 4 && s == 5) || (m == 5 && s == 4)) return TXBACK;
			return TXSIDE;
		}
	}

	@Override
	public void onBlockPlacedBy(World world, int i, int j, int k, EntityLiving entityliving) {
		super.onBlockPlacedBy(world, i, j, k, entityliving);

		// if(entityliving instanceof EntityPlayer){
		// EntityPlayer entityplayer = (EntityPlayer)entityliving;
		// PCma_TileEntityReplacer tileentity = (PCma_TileEntityReplacer) world.getBlockTileEntity(i, j, k);
		// if (tileentity != null) {
		// ModLoader.openGUI(entityplayer, new PC_GresGui(new PCma_GuiReplacer(entityplayer.inventory, tileentity)));
		// }
		// }
	}

	@Override
	public boolean blockActivated(World world, int i, int j, int k, EntityPlayer entityplayer) {

		ItemStack ihold = entityplayer.getCurrentEquippedItem();
		if (ihold != null) {
			if (ihold.getItem() instanceof ItemBlock && ihold.getItem().shiftedIndex != blockID) {

				Block bhold = Block.blocksList[ihold.getItem().shiftedIndex];
				if (bhold instanceof PC_IBlockType) { return false; }

			}
		}

		if (world.isRemote) { return true; }

		PCma_TileEntityReplacer tileentity = (PCma_TileEntityReplacer) world.getBlockTileEntity(i, j, k);
		if (tileentity != null) {
			PC_Utils.openGres(entityplayer, new PCma_GuiReplacer(tileentity, entityplayer.inventory));
		}

		return true;
	}

	@Override
	public int tickRate() {
		return 4;
	}

	@Override
	public void onNeighborBlockChange(World world, int i, int j, int k, int l) {
		if (l > 0 && Block.blocksList[l].canProvidePower()) {
			world.scheduleBlockUpdate(i, j, k, blockID, tickRate());
		}
	}

	private boolean canHarvestBlock(World world, PC_CoordI pos) {

		int id = pos.getMeta(world);

		if (id == 0 || Block.blocksList[id] == null) return true;

		if (pos.getTileEntity(world) != null) return false;

		return true;

	}
	
	/**
	 * Check if block can be auto-placed (and is then harvestable again)
	 * @param world
	 * @param itemstack
	 * @param pos
	 * @return can be placed
	 */
	private boolean canPlaceBlock(World world, ItemStack itemstack, PC_CoordI pos) {

		if(itemstack == null) return false;
		Item item = itemstack.getItem();
		
		if(item instanceof ItemBlock){
			
			Block block = Block.blocksList[item.shiftedIndex];
			
			if(block == null) return false;
			
			if(PC_BlockUtils.isBuilderIgnored(block.blockID)) return false;
			
			if(block.isBlockContainer) return false;
			
			return true;			
			
		}else{
			return false;
		}

	}
	
	
	/**
	 * Place itemblock from stack.
	 * @param world
	 * @param itemstack
	 * @param pos
	 * @return
	 */
	private boolean placeBlockAt(World world, ItemStack itemstack, PC_CoordI pos){
		
		if(itemstack == null){
			pos.setBlock(world,0,0);
			return true;
		}
		
		if(!canPlaceBlock(world, itemstack, pos)) return false;
		
		ItemBlock iblock = (ItemBlock) itemstack.getItem();
		
		return iblock.onItemUse(itemstack, new PC_FakePlayer(world), world, pos.x, pos.y, pos.z, 0);
		
	}


	/**
	 * Get stack from a block at target coordinates.
	 * 
	 * @param world the world
	 * @param pos target position
	 * @return stack, or null if not harvested.
	 */
	private ItemStack harvestBlockAt(World world, PC_CoordI pos) {

		ItemStack loot = null;

		if (!canHarvestBlock(world, pos)) return null;

		Block block = Block.blocksList[pos.getId(world)];

		if (block == null) return null;

		if (block.canSilkHarvest()) {
			loot = block.createStackedBlock(pos.getMeta(world));
		} else {
			int dropId = block.blockID;
			int dropMeta = block.damageDropped(pos.getMeta(world));
			int dropQuant = block.quantityDropped(world.rand);
			if (dropId <= 0) {
				dropId = pos.getId(world);
			}
			if (dropQuant <= 0) {
				dropQuant = 1;
			}

			loot = new ItemStack(dropId, dropQuant, dropMeta);
		}

		return loot;
	}

	private void swapBlocks(World world, int x, int y, int z, Random random, PCma_TileEntityReplacer tileentity) {
		if (tileentity.buildBlock != null) if (!(tileentity.buildBlock.getItem() instanceof ItemBlock)) return;
		int id = world.getBlockId(x, y, z);
		int meta = world.getBlockMetadata(x, y, z);
		ItemStack newItem = null;
		if (id > 0) {
			if (canHarvestBlock(world, new PC_CoordI(x, y, z))) {

				int dropId = Block.blocksList[id].blockID;
				int dropMeta = Block.blocksList[id].damageDropped(meta);
				int dropQuant = Block.blocksList[id].quantityDropped(world.rand);
				if (dropId <= 0) {
					dropId = id;
				}
				if (dropQuant <= 0) {
					dropQuant = 1;
				}
				newItem = new ItemStack(dropId, dropQuant, dropMeta);
			} else if (canSilkHarvest()) {
				newItem = createStackedBlock(meta);
			} else return;
		}
		// if(newItem!=null)
		/*
		 * // play breaking sound and animation
		 * if (mod_PCcore.soundsEnabled) {
		 * world.playAuxSFX(2001, coord.x, coord.y, coord.z, id + (meta << 12));
		 * }
		 */
		if (tileentity.buildBlock != null) world.setBlockWithNotify(x, y, z, ((ItemBlock) (tileentity.buildBlock.getItem())).shiftedIndex);
		else world.setBlockWithNotify(x, y, z, 0);
		tileentity.buildBlock = newItem;
	}

	@Override
	public void updateTick(World world, int i, int j, int k, Random random) {
		PCma_TileEntityReplacer tileentity = (PCma_TileEntityReplacer) world.getBlockTileEntity(i, j, k);
		if (tileentity != null && !world.isRemote) {
			swapBlocks(world, i + tileentity.coordOffset[0], j + tileentity.coordOffset[1], k + tileentity.coordOffset[2], random,
					tileentity);
		}
	}

	private boolean isIndirectlyPowered(World world, int i, int j, int k) {
		if (world.isBlockGettingPowered(i, j, k)) { return true; }

		if (world.isBlockIndirectlyGettingPowered(i, j, k)) { return true; }

		if (world.isBlockGettingPowered(i, j - 1, k)) { return true; }

		if (world.isBlockIndirectlyGettingPowered(i, j - 1, k)) { return true; }
		return false;
	}

	@Override
	public TileEntity getBlockEntity() {
		return new PCma_TileEntityReplacer();
	}

	@Override
	public int getMobilityFlag() {
		return 0;
	}

	@Override
	public void onBlockRemoval(World world, int i, int j, int k) {
		PCma_TileEntityReplacer tileentity = (PCma_TileEntityReplacer) world.getBlockTileEntity(i, j, k);
		Random random = new Random();
		if (tileentity != null) if (tileentity.buildBlock != null) {
			float f = random.nextFloat() * 0.8F + 0.1F;
			float f1 = random.nextFloat() * 0.8F + 0.1F;
			float f2 = random.nextFloat() * 0.8F + 0.1F;
			EntityItem entityitem = new EntityItem(world, i + f, j + f1, k + f2, tileentity.buildBlock);
			float f3 = 0.05F;
			entityitem.motionX = (float) random.nextGaussian() * f3;
			entityitem.motionY = (float) random.nextGaussian() * f3 + 0.2F;
			entityitem.motionZ = (float) random.nextGaussian() * f3;
			world.spawnEntityInWorld(entityitem);
		}
		super.onBlockRemoval(world, i, j, k);
	}

	@Override
	public boolean isTranslucentForLaser(IBlockAccess world, PC_CoordI pos) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public boolean isHarvesterIgnored(IBlockAccess world, PC_CoordI pos) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public boolean isHarvesterDelimiter(IBlockAccess world, PC_CoordI pos) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public boolean isBuilderIgnored() {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public boolean isConveyor(IBlockAccess world, PC_CoordI pos) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public boolean isElevator(IBlockAccess world, PC_CoordI pos) {
		// TODO Auto-generated method stub
		return false;
	}
}
