package pneumaticCraft.common.tileentity;
import java.util.ArrayList;
import java.util.List;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Items;
import net.minecraft.inventory.ISidedInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.Facing;
import net.minecraftforge.common.util.ForgeDirection;
import pneumaticCraft.common.block.Blockss;
import pneumaticCraft.common.network.DescSynced;
import pneumaticCraft.common.network.FilteredSynced;
import pneumaticCraft.common.network.GuiSynced;
import pneumaticCraft.common.network.LazySynced;
import pneumaticCraft.common.util.PneumaticCraftUtils;
import pneumaticCraft.lib.GuiConstants;
import pneumaticCraft.lib.PneumaticValues;
import pneumaticCraft.lib.Sounds;
public class TileEntityPressureChamberInterface extends TileEntityPressureChamberWall implements ISidedInventory,
IGUITextFieldSensitive, IRedstoneControlled{
@DescSynced
@FilteredSynced(index = 0)
private ItemStack[] inventory = new ItemStack[14];
@DescSynced
@LazySynced
public int inputProgress;
public int oldInputProgress;
@DescSynced
@LazySynced
public int outputProgress;
public int oldOutputProgress;
public static final int MAX_PROGRESS = 40;
private static final int UPGRADE_SLOT_START = 1;
private static final int UPGRADE_SLOT_END = 4;
@GuiSynced
public EnumInterfaceMode interfaceMode = EnumInterfaceMode.NONE;
@GuiSynced
private boolean enoughAir = true;
@DescSynced
public EnumFilterMode filterMode = EnumFilterMode.ITEM;
@GuiSynced
public int creativeTabID;
@DescSynced
public String itemNameFilter = "";
private boolean isOpeningI;//used to determine sounds.
private boolean isOpeningO;//used to determine sounds.
@DescSynced
private boolean shouldOpenInput, shouldOpenOutput;
@GuiSynced
public int redstoneMode;
private int inputTimeOut;
private int oldItemCount;
public enum EnumInterfaceMode{
NONE, IMPORT, EXPORT;
}
public enum EnumFilterMode{
ITEM, CREATIVE_TAB, NAME_BEGINS, NAME_CONTAINS;
}
public TileEntityPressureChamberInterface(){
setUpgradeSlots(new int[]{UPGRADE_SLOT_START, 2, 3, UPGRADE_SLOT_END});
}
@Override
public void updateEntity(){
super.updateEntity();
boolean wasOpeningI = isOpeningI;
boolean wasOpeningO = isOpeningO;
oldInputProgress = inputProgress;
oldOutputProgress = outputProgress;
TileEntityPressureChamberValve core = getCore();
if(!worldObj.isRemote) {
int itemCount = inventory[0] != null ? inventory[0].stackSize : 0;
if(oldItemCount != itemCount) {
oldItemCount = itemCount;
inputTimeOut = 0;
}
interfaceMode = getInterfaceMode(core);
enoughAir = true;
if(interfaceMode != EnumInterfaceMode.NONE) {
if(inventory[0] != null && ++inputTimeOut > 10) {
shouldOpenInput = false;
if(inputProgress == 0) {
shouldOpenOutput = true;
if(outputProgress == MAX_PROGRESS) {
if(interfaceMode == EnumInterfaceMode.IMPORT) {
outputInChamber();
} else {
exportToInventory();
}
}
}
} else {
shouldOpenOutput = false;
if(outputProgress == 0) {
shouldOpenInput = true;
if(interfaceMode == EnumInterfaceMode.EXPORT && inputProgress == MAX_PROGRESS && redstoneAllows()) {
importFromChamber(core);
}
}
}
} else {
shouldOpenInput = false;
shouldOpenOutput = false;
}
}
int speed = (int)getSpeedMultiplierFromUpgrades(getUpgradeSlots());
if(shouldOpenInput) {
inputProgress = Math.min(inputProgress + speed, MAX_PROGRESS);
isOpeningI = true;
} else {
inputProgress = Math.max(inputProgress - speed, 0);
isOpeningI = false;
}
if(shouldOpenOutput) {
outputProgress = Math.min(outputProgress + speed, MAX_PROGRESS);
isOpeningO = true;
} else {
outputProgress = Math.max(outputProgress - speed, 0);
isOpeningO = false;
}
if(worldObj.isRemote && (wasOpeningI != isOpeningI || wasOpeningO != isOpeningO)) {
worldObj.playSound(xCoord + 0.5, yCoord + 0.5, zCoord + 0.5, Sounds.INTERFACE_DOOR, 0.1F, 1.0F, true);
}
}
private void exportToInventory(){
ForgeDirection facing = ForgeDirection.getOrientation(getBlockMetadata());
TileEntity te = worldObj.getTileEntity(xCoord + facing.offsetX, yCoord + facing.offsetY, zCoord + facing.offsetZ);
if(te != null) {
ForgeDirection side = facing.getOpposite();
ItemStack leftoverStack = PneumaticCraftUtils.exportStackToInventory(te, inventory[0], side);
if(leftoverStack == null || leftoverStack.stackSize == 0) {
inventory[0] = null;
}
}
}
private void importFromChamber(TileEntityPressureChamberValve core){
ItemStack[] chamberStacks = core.getStacksInChamber();
for(ItemStack chamberStack : chamberStacks) {
if((inventory[0] == null || inventory[0].isItemEqual(chamberStack)) && isItemValidForSlot(0, chamberStack)) {
int maxAllowedItems = Math.abs(core.currentAir) / PneumaticValues.USAGE_CHAMBER_INTERFACE;
if(maxAllowedItems > 0) {
if(inventory[0] != null) maxAllowedItems = Math.min(maxAllowedItems, chamberStack.getMaxStackSize() - inventory[0].stackSize);
int transferedItems = Math.min(chamberStack.stackSize, maxAllowedItems);
core.addAir((core.currentAir > 0 ? -1 : 1) * transferedItems * PneumaticValues.USAGE_CHAMBER_INTERFACE, ForgeDirection.UNKNOWN);
ItemStack transferedStack = chamberStack.copy().splitStack(transferedItems);
ItemStack insertedStack = transferedStack.copy();
if(inventory[0] != null) insertedStack.stackSize += inventory[0].stackSize;
setInventorySlotContents(0, insertedStack);
core.clearStacksInChamber(transferedStack);
}
}
}
}
private void outputInChamber(){
TileEntityPressureChamberValve valve = getCore();
if(valve != null) {
for(int i = 0; i < 6; i++) {
int x = xCoord + Facing.offsetsXForSide[i];
int y = yCoord + Facing.offsetsYForSide[i];
int z = zCoord + Facing.offsetsZForSide[i];
if(valve.isCoordWithinChamber(worldObj, x, y, z)) {
enoughAir = Math.abs(valve.currentAir) > inventory[0].stackSize * PneumaticValues.USAGE_CHAMBER_INTERFACE;
if(enoughAir) {
valve.addAir((valve.currentAir > 0 ? -1 : 1) * inventory[0].stackSize * PneumaticValues.USAGE_CHAMBER_INTERFACE, ForgeDirection.UNKNOWN);
EntityItem item = new EntityItem(worldObj, x + 0.5D, y + 0.5D, z + 0.5D, inventory[0].copy());
worldObj.spawnEntityInWorld(item);
setInventorySlotContents(0, null);
break;
}
}
}
}
}
/*
* public void setCore(TileEntityPressureChamberValve core){ boolean
* wasNotNull = teValve != null; super.setCore(core); if(worldObj.isRemote)
* return; if(core != null) modeNeedsChecking = true; else if(wasNotNull)
* modeNeedsChecking = true; }
*/
// figure out whether the Interface is exporting or importing.
private EnumInterfaceMode getInterfaceMode(TileEntityPressureChamberValve core){
if(core != null) {
boolean xMid = xCoord != core.multiBlockX && xCoord != core.multiBlockX + core.multiBlockSize - 1;
boolean yMid = yCoord != core.multiBlockY && yCoord != core.multiBlockY + core.multiBlockSize - 1;
boolean zMid = zCoord != core.multiBlockZ && zCoord != core.multiBlockZ + core.multiBlockSize - 1;
int meta = getBlockMetadata();
if(xMid && yMid && meta == 2 || xMid && zMid && meta == 0 || yMid && zMid && meta == 4) {
if(xCoord == core.multiBlockX || yCoord == core.multiBlockY || zCoord == core.multiBlockZ) {
return EnumInterfaceMode.EXPORT;
} else {
return EnumInterfaceMode.IMPORT;
}
} else if(xMid && yMid && meta == 3 || xMid && zMid && meta == 1 || yMid && zMid && meta == 5) {
if(xCoord == core.multiBlockX || yCoord == core.multiBlockY || zCoord == core.multiBlockZ) {
return EnumInterfaceMode.IMPORT;
} else {
return EnumInterfaceMode.EXPORT;
}
}
}
return EnumInterfaceMode.NONE;
}
public List<String> getProblemStat(){
List<String> textList = new ArrayList<String>();
if(interfaceMode == EnumInterfaceMode.NONE) {
textList.addAll(PneumaticCraftUtils.convertStringIntoList("\u00a77The Interface can't work.", GuiConstants.maxCharPerLineLeft));
textList.addAll(PneumaticCraftUtils.convertStringIntoList("\u00a70-The Interface is not in a properly formed Pressure Chamber, and/or", GuiConstants.maxCharPerLineLeft));
textList.addAll(PneumaticCraftUtils.convertStringIntoList("\u00a70-The Interface is not adjacent to an air block of the Pressure Chamber, and/or", GuiConstants.maxCharPerLineLeft));
textList.addAll(PneumaticCraftUtils.convertStringIntoList("\u00a70-The Interface isn't orientated right.", GuiConstants.maxCharPerLineLeft));
} else if(!redstoneAllows()) {
textList.add("gui.tab.problems.redstoneDisallows");
} else if(!enoughAir) {
textList.addAll(PneumaticCraftUtils.convertStringIntoList("\u00a77There's not enough pressure in the Pressure Chamber to move the items.", GuiConstants.maxCharPerLineLeft));
textList.addAll(PneumaticCraftUtils.convertStringIntoList("\u00a70Apply more pressure to the Pressure Chamber. The required pressure is dependent on the amount of items being transported.", GuiConstants.maxCharPerLineLeft));
}
return textList;
}
public boolean hasEnoughPressure(){
return enoughAir;
}
@Override
public boolean redstoneAllows(){
switch(redstoneMode){
case 0:
return true;
case 1:
return worldObj.isBlockIndirectlyGettingPowered(xCoord, yCoord, zCoord);
case 2:
return !worldObj.isBlockIndirectlyGettingPowered(xCoord, yCoord, zCoord);
}
return false;
}
// INVENTORY METHODS- && NBT
// ------------------------------------------------------------
@Override
public void readFromNBT(NBTTagCompound tag){
super.readFromNBT(tag);
// Read in the ItemStacks in the inventory from NBT
NBTTagList tagList = tag.getTagList("Items", 10);
inventory = new ItemStack[getSizeInventory()];
for(int i = 0; i < tagList.tagCount(); i++) {
NBTTagCompound tagCompound = tagList.getCompoundTagAt(i);
byte slot = tagCompound.getByte("Slot");
if(slot >= 0 && slot < inventory.length) {
inventory[slot] = ItemStack.loadItemStackFromNBT(tagCompound);
}
}
outputProgress = tag.getInteger("outputProgress");
inputProgress = tag.getInteger("inputProgress");
interfaceMode = EnumInterfaceMode.values()[tag.getInteger("interfaceMode")];
filterMode = EnumFilterMode.values()[tag.getInteger("filterMode")];
creativeTabID = tag.getInteger("creativeTabID");
itemNameFilter = tag.getString("itemNameFilter");
redstoneMode = tag.getInteger("redstoneMode");
}
@Override
public void writeToNBT(NBTTagCompound tag){
super.writeToNBT(tag);
// Write the ItemStacks in the inventory to NBT
NBTTagList tagList = new NBTTagList();
for(int i = 0; i < inventory.length; i++)
if(inventory[i] != null) {
NBTTagCompound tagCompound = new NBTTagCompound();
tagCompound.setByte("Slot", (byte)i);
inventory[i].writeToNBT(tagCompound);
tagList.appendTag(tagCompound);
}
tag.setTag("Items", tagList);
tag.setInteger("outputProgress", outputProgress);
tag.setInteger("inputProgress", inputProgress);
tag.setInteger("interfaceMode", interfaceMode.ordinal());
tag.setInteger("filterMode", filterMode.ordinal());
tag.setInteger("creativeTabID", creativeTabID);
tag.setString("itemNameFilter", itemNameFilter);
tag.setInteger("redstoneMode", redstoneMode);
}
/**
* Returns the number of slots in the inventory.
*/
@Override
public int getSizeInventory(){
return 14;
}
/**
* Returns the stack in slot i
*/
@Override
public ItemStack getStackInSlot(int slot){
return inventory[slot];
}
@Override
public ItemStack decrStackSize(int slot, int amount){
ItemStack itemStack = getStackInSlot(slot);
if(itemStack != null) {
if(itemStack.stackSize <= amount) {
setInventorySlotContents(slot, null);
} else {
itemStack = itemStack.splitStack(amount);
if(itemStack.stackSize == 0) {
setInventorySlotContents(slot, null);
}
}
}
return itemStack;
}
@Override
public ItemStack getStackInSlotOnClosing(int slot){
ItemStack itemStack = getStackInSlot(slot);
if(itemStack != null) {
setInventorySlotContents(slot, null);
}
return itemStack;
}
@Override
public void setInventorySlotContents(int slot, ItemStack itemStack){
inventory[slot] = itemStack;
if(itemStack != null && itemStack.stackSize > getInventoryStackLimit()) {
itemStack.stackSize = getInventoryStackLimit();
}
if(!worldObj.isRemote && slot == 0) {
sendDescriptionPacket();
}
}
@Override
public int getInventoryStackLimit(){
return 64;
}
@Override
public String getInventoryName(){
return Blockss.pressureChamberInterface.getUnlocalizedName();
}
@Override
public void openInventory(){}
@Override
public void closeInventory(){}
@Override
public boolean isItemValidForSlot(int slot, ItemStack iStack){
if(iStack == null) return false;
switch(filterMode){
case ITEM:
boolean filterEmpty = true;
for(int i = 0; i < 9; i++) {
ItemStack filterStack = getStackInSlot(i + 5);
if(filterStack != null) {
filterEmpty = false;
if(iStack.isItemEqual(filterStack)) {
return true;
}
}
}
return filterEmpty;
case CREATIVE_TAB:
try {
int itemCreativeTabIndex = iStack.getItem().getCreativeTab() != null ? iStack.getItem().getCreativeTab().getTabIndex() : -1;
if(itemCreativeTabIndex == creativeTabID) {
return true;
}
} catch(Throwable e) {//when we are SMP getCreativeTab() is client only.
filterMode = EnumFilterMode.NAME_BEGINS;
}
return false;
case NAME_BEGINS:
return iStack.getDisplayName().toLowerCase().startsWith(itemNameFilter.toLowerCase());
case NAME_CONTAINS:
return iStack.getDisplayName().toLowerCase().contains(itemNameFilter.toLowerCase());
}
return false;
}
@Override
public boolean isUseableByPlayer(EntityPlayer entityplayer){
return true;
}
@Override
public boolean isGuiUseableByPlayer(EntityPlayer par1EntityPlayer){
return worldObj.getTileEntity(xCoord, yCoord, zCoord) != this ? false : par1EntityPlayer.getDistanceSq(xCoord + 0.5D, yCoord + 0.5D, zCoord + 0.5D) <= 64.0D;
}
@Override
public int[] getAccessibleSlotsFromSide(int var1){
return new int[]{0};
}
@Override
public boolean canInsertItem(int i, ItemStack itemstack, int j){
return inputProgress == MAX_PROGRESS && j == getRotation().getOpposite().ordinal() && redstoneAllows();
}
@Override
public boolean canExtractItem(int i, ItemStack itemstack, int j){
return outputProgress == MAX_PROGRESS && j == getRotation().ordinal();
}
@Override
public void handleGUIButtonPress(int guiID, EntityPlayer player){
if(guiID == 1) {
if(filterMode.ordinal() >= EnumFilterMode.values().length - 1) {
filterMode = EnumFilterMode.ITEM;
} else {
filterMode = EnumFilterMode.values()[filterMode.ordinal() + 1];
}
isItemValidForSlot(0, new ItemStack(Items.stick));//when an SideOnly exception is thrown this method automatically will set the filter mode to Item.
} else if(guiID == 2) {
creativeTabID++;
if(creativeTabID == 5 || creativeTabID == 11) creativeTabID++;
if(creativeTabID >= CreativeTabs.creativeTabArray.length) {
creativeTabID = 0;
}
} else if(guiID == 0) {
redstoneMode++;
if(redstoneMode > 2) redstoneMode = 0;
}
}
@Override
public void setText(int textFieldID, String text){
itemNameFilter = text;
}
@Override
public String getText(int textFieldID){
return itemNameFilter;
}
@Override
public boolean hasCustomInventoryName(){
return false;
}
@Override
public int getRedstoneMode(){
return redstoneMode;
}
}