// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://www.kpdus.com/jad.html
// Decompiler options: packimports(3) braces deadcode fieldsfirst 

package net.minecraft.src;

public class PClo_TileEntityGate extends TileEntity {
	public int gateType = -1;
	public boolean prevClockState = false;
	private int counter = 10;
	
	public PClo_TileEntityGate() {
	}

	public boolean canUpdate() {
		return true;
	}
	
	boolean resetDone = false;
	
	private long lt = 0;
	
	boolean zombie = false;

	@Override
	public void updateEntity() {
		if(zombie) return;
		
		//long t = System.currentTimeMillis();
		//if(t-lt < 5) return;
		//lt = t;
		
		
		if(gateType != PClo_GType.DELAYER){
			if (counter-- <= 0) {
				counter = 6;
			} else {
				return;
			}
		}
		
		updateContainingBlockInfo();
		
		Block block = getBlockType();
		if (block == null || (block.blockID != mod_PClogic.gateOn.blockID && block.blockID != mod_PClogic.gateOff.blockID)) return;
		
		int blockID = block.blockID;

		boolean active = ((PClo_BlockGate) Block.blocksList[blockID]).active;

		if(gateType == PClo_GType.DELAYER){
			
			//"reset" input powered
			if(PClo_BlockGate.powered_from_input(worldObj, xCoord, yCoord, zCoord, getBlockMetadata(), 1)){
				if(!resetDone){
					for(int i = 0; i<dBuffer.length; i++){
						dBuffer[i] = false;
					}
					dPointer = 0;
					
					if(dOutputState){
						dOutputState = false;
						updateBlock();
					}
					
					resetDone = true;
				}
			
			//"hold" input not powered
			}else{
				
				resetDone = false;
				if(!PClo_BlockGate.powered_from_input(worldObj, xCoord, yCoord, zCoord, getBlockMetadata(), 2)){
				
					bufferPush(PClo_BlockGate.powered_from_input(worldObj, xCoord, yCoord, zCoord, getBlockMetadata(), 0));
					
					if (dOutputState != active) {
						updateBlock();
					}
				
				}
				
			}
			
		}else if (gateType == PClo_GType.DAY) {

			if (worldObj.isDaytime() != active){
				updateBlock();
			}
			
		}else if (gateType == PClo_GType.RAIN) {
			
			if (worldObj.isRaining() != active){
				updateBlock();
			}
			
		}else if (gateType == PClo_GType.CHEST_EMPTY) {

			if (isChestEmpty() != active) {
				updateBlock();
			}
			
		}else if (gateType == PClo_GType.CHEST_FULL) {

			if ( isChestFull() != active) {
				updateBlock();
			}

			
		}else if (gateType == PClo_GType.SPAWNER) {
			// disable nearby spawners.
			
			stopSpawning_stopPulsar(worldObj.getBlockTileEntity(xCoord + 1, yCoord, zCoord), active);
			stopSpawning_stopPulsar(worldObj.getBlockTileEntity(xCoord - 1, yCoord, zCoord), active);
			stopSpawning_stopPulsar(worldObj.getBlockTileEntity(xCoord, yCoord, zCoord + 1), active);
			stopSpawning_stopPulsar(worldObj.getBlockTileEntity(xCoord, yCoord, zCoord - 1), active);
			stopSpawning_stopPulsar(worldObj.getBlockTileEntity(xCoord, yCoord + 1, zCoord), active);
			stopSpawning_stopPulsar(worldObj.getBlockTileEntity(xCoord, yCoord - 1, zCoord), active);

			
		}
		
		
	}
	
	public void updateBlock() {		
		worldObj.scheduleBlockUpdate(xCoord, yCoord, zCoord, getBlockType().blockID,2);
	}

	private void stopSpawning_stopPulsar(TileEntity te, boolean active) {
		if (te != null) {
			if (te instanceof TileEntityMobSpawner) {
				((TileEntityMobSpawner) te).delay = 500;
			} else if (te != null && te instanceof PClo_TileEntityPulsar && active) {
				((PClo_TileEntityPulsar) te).paused = true;
				((PClo_TileEntityPulsar) te).active = false;
				((PClo_TileEntityPulsar) te).delayTimer = 0;
				((PClo_TileEntityPulsar) te).updateBlock();
			}
		}
	}

	@Override
	public void readFromNBT(NBTTagCompound maintag) {
		super.readFromNBT(maintag);
		gateType = maintag.getInteger("type");
		prevClockState = maintag.getBoolean("clock");
		
		if(gateType == PClo_GType.DELAYER){
			
			NBTTagList taglist = maintag.getTagList("DelayBuffer");
			
			int length = maintag.getInteger("DelayLength");
			
			dBuffer = new boolean[length];
			
			dOutputState = maintag.getBoolean("DelayState");
			
			for (int i = 0; i < length; i++) {
				NBTTagCompound booltag = (NBTTagCompound) taglist.tagAt(i);
				dBuffer[booltag.getInteger("Index")] = booltag.getBoolean("state");
			}	
		
		}
		
	}

	@Override
	public void writeToNBT(NBTTagCompound maintag) {
		super.writeToNBT(maintag);
		maintag.setInteger("type", gateType);
		maintag.setBoolean("clock", prevClockState);	
		
		if(gateType == PClo_GType.DELAYER){
		
			NBTTagList listtag = new NBTTagList();
			for (int i = 0; i < dBuffer.length; i++) {
				NBTTagCompound booltag = new NBTTagCompound();
				booltag.setInteger("Index", i);
				booltag.setBoolean("state", dBuffer[i]);
				listtag.appendTag(booltag);
			}
	
			maintag.setTag("DelayBuffer", listtag);
			maintag.setInteger("DelayLength", dBuffer.length);
			maintag.setBoolean("DelayState", dOutputState);			
		
		}
	}

	public boolean isChestFull() {
		int i1 = worldObj.getBlockMetadata(xCoord, yCoord, zCoord) & 3;

		int N0 = 0;
		int N1 = 1;
		int N2 = 2;
		int N3 = 3;

		if (i1 == N0) {
			return isFullChest(worldObj, xCoord, yCoord, zCoord + 1);
		}
		if (i1 == N1) {
			return isFullChest(worldObj, xCoord - 1, yCoord, zCoord);
		}
		if (i1 == N2) {
			return isFullChest(worldObj, xCoord, yCoord, zCoord - 1);
		}
		if (i1 == N3) {
			return isFullChest(worldObj, xCoord + 1, yCoord, zCoord);
		}
		return false;
	}

	public boolean isChestEmpty() {
		int i1 = worldObj.getBlockMetadata(xCoord, yCoord, zCoord) & 3;

		int N0 = 0;
		int N1 = 1;
		int N2 = 2;
		int N3 = 3;

		if (i1 == N0) {
			return isEmptyChest(worldObj, xCoord, yCoord, zCoord + 1);
		}
		if (i1 == N1) {
			return isEmptyChest(worldObj, xCoord - 1, yCoord, zCoord);
		}
		if (i1 == N2) {
			return isEmptyChest(worldObj, xCoord, yCoord, zCoord - 1);
		}
		if (i1 == N3) {
			return isEmptyChest(worldObj, xCoord + 1, yCoord, zCoord);
		}
		return true;
	}

	public static boolean isEmptyChest(IBlockAccess blockaccess, int i, int j, int k) {
		return isInventoryEmpty(getInventoryAt(blockaccess, i, j, k));
	}

	public static boolean isFullChest(IBlockAccess blockaccess, int i, int j, int k) {
		return isInventoryFull(getInventoryAt(blockaccess, i, j, k));
	}

	public static boolean isInventoryEmpty(IInventory inv) {
		if (inv == null) return true;

		if (inv instanceof PCco_IACT) return ((PCco_IACT) inv).reportEmpty();

		if (inv instanceof TileEntityFurnace) return inv.getStackInSlot(1) == null;

		for (int i = 0; i < inv.getSizeInventory(); i++) {
			if (inv.getStackInSlot(i) != null) {
				return false;
			}
		}
		return true;
	}

	public static boolean isInventoryFull(IInventory inv) {
		if (inv == null) return false;

		if (inv instanceof PCco_IACT) return ((PCco_IACT) inv).reportFull();

		if (inv instanceof TileEntityFurnace)
			return inv.getStackInSlot(1) != null
					&& inv.getStackInSlot(1).stackSize == Math.min(inv.getInventoryStackLimit(), inv.getStackInSlot(1).getMaxStackSize());

		for (int i = 0; i < inv.getSizeInventory(); i++) {
			if (inv.getStackInSlot(i) == null
					|| inv.getStackInSlot(i).stackSize < Math.min(inv.getInventoryStackLimit(), inv.getStackInSlot(i).getMaxStackSize())) {
				return false;
			}
		}
		return true;
	}

	public static IInventory getInventoryAt(IBlockAccess blockaccess, int i, int j, int k) {
		TileEntity tileEntity = blockaccess.getBlockTileEntity(i, j, k);
		if (tileEntity == null || !(tileEntity instanceof IInventory) || (tileEntity instanceof TileEntityBrewingStand)) {
			return null;
		}

		IInventory inventory = (IInventory) tileEntity;
		if (!(inventory instanceof TileEntityChest)) {
			return inventory;
		}

		int blockID = blockaccess.getBlockId(i, j, k);
		if (blockaccess.getBlockId(i + 1, j, k) == blockID) {
			IInventory neighbourInventory = (IInventory) blockaccess.getBlockTileEntity(i + 1, j, k);
			return new InventoryLargeChest("", inventory, neighbourInventory);
		}
		if (blockaccess.getBlockId(i - 1, j, k) == blockID) {
			IInventory neighbourInventory = (IInventory) blockaccess.getBlockTileEntity(i - 1, j, k);
			return new InventoryLargeChest("", neighbourInventory, inventory);
		}
		if (blockaccess.getBlockId(i, j, k + 1) == blockID) {
			IInventory neighbourInventory = (IInventory) blockaccess.getBlockTileEntity(i, j, k + 1);
			return new InventoryLargeChest("", inventory, neighbourInventory);
		}
		if (blockaccess.getBlockId(i, j, k - 1) == blockID) {
			IInventory neighbourInventory = (IInventory) blockaccess.getBlockTileEntity(i, j, k - 1);
			return new InventoryLargeChest("", neighbourInventory, inventory);
		}

		return inventory;
	}
	

	

	private boolean dOutputState = false;
	private boolean[] dBuffer = new boolean[20];
	private int dPointer = 0;
	
	public void bufferResize(int length){

		dBuffer = new boolean[length];
		System.gc();
		dPointer = 0;
		dOutputState = false;
		
	}
	
	private void bufferPush(boolean state){
		dOutputState = dBuffer[dPointer];
		dBuffer[dPointer] = state;
		dPointer++;
		if(dPointer >= dBuffer.length){			
			dPointer = 0;
		}
	}	
	
	public boolean getBufferOutput() {
		return dOutputState;
	}

	public int getDelayBufferLength() {
		return dBuffer.length;
	}
}
