package micdoodle8.mods.galacticraft.core.tile;
import micdoodle8.mods.galacticraft.api.entity.ICargoEntity;
import micdoodle8.mods.galacticraft.api.entity.ICargoEntity.EnumCargoLoadingState;
import micdoodle8.mods.galacticraft.api.entity.ICargoEntity.RemovalResult;
import micdoodle8.mods.galacticraft.api.tile.ILandingPadAttachable;
import micdoodle8.mods.galacticraft.api.tile.ILockable;
import micdoodle8.mods.galacticraft.api.vector.BlockVec3;
import micdoodle8.mods.galacticraft.core.blocks.BlockCargoLoader;
import micdoodle8.mods.galacticraft.core.energy.item.ItemElectricBase;
import micdoodle8.mods.galacticraft.core.energy.tile.TileBaseElectricBlockWithInventory;
import micdoodle8.mods.galacticraft.core.util.GCCoreUtil;
import micdoodle8.mods.miccore.Annotations.NetworkedField;
import net.minecraft.inventory.ISidedInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.*;
import net.minecraft.world.IBlockAccess;
import net.minecraftforge.fml.relauncher.Side;
public class TileEntityCargoLoader extends TileBaseElectricBlockWithInventory implements ISidedInventory, ILandingPadAttachable, ILockable
{
private ItemStack[] containingItems = new ItemStack[15];
public boolean outOfItems;
@NetworkedField(targetSide = Side.CLIENT)
public boolean targetFull;
@NetworkedField(targetSide = Side.CLIENT)
public boolean targetNoInventory;
@NetworkedField(targetSide = Side.CLIENT)
public boolean noTarget;
@NetworkedField(targetSide = Side.CLIENT)
public boolean locked;
public ICargoEntity attachedFuelable;
public TileEntityCargoLoader()
{
this.storage.setMaxExtract(45);
}
@Override
public void update()
{
super.update();
if (!this.worldObj.isRemote)
{
if (this.ticks % 100 == 0)
{
this.checkForCargoEntity();
}
if (this.attachedFuelable != null)
{
this.noTarget = false;
ItemStack stack = this.removeCargo(false).resultStack;
if (stack != null)
{
this.outOfItems = false;
EnumCargoLoadingState state = this.attachedFuelable.addCargo(stack, false);
this.targetFull = state == EnumCargoLoadingState.FULL;
this.targetNoInventory = state == EnumCargoLoadingState.NOINVENTORY;
this.noTarget = state == EnumCargoLoadingState.NOTARGET;
if (this.ticks % (this.poweredByTierGC > 1 ? 9 : 15) == 0 && state == EnumCargoLoadingState.SUCCESS && !this.disabled && this.hasEnoughEnergyToRun)
{
this.attachedFuelable.addCargo(this.removeCargo(true).resultStack, true);
}
}
else
{
this.outOfItems = true;
}
}
else
{
this.noTarget = true;
}
}
}
public void checkForCargoEntity()
{
boolean foundFuelable = false;
for (final EnumFacing dir : EnumFacing.VALUES)
{
final TileEntity pad = new BlockVec3(this).getTileEntityOnSide(this.worldObj, dir);
if (pad != null && pad instanceof TileEntityMulti)
{
final TileEntity mainTile = ((TileEntityMulti) pad).getMainBlockTile();
if (mainTile instanceof ICargoEntity)
{
this.attachedFuelable = (ICargoEntity) mainTile;
foundFuelable = true;
break;
}
}
else if (pad != null && pad instanceof ICargoEntity)
{
this.attachedFuelable = (ICargoEntity) pad;
foundFuelable = true;
break;
}
}
if (!foundFuelable)
{
this.attachedFuelable = null;
}
}
@Override
public void readFromNBT(NBTTagCompound par1NBTTagCompound)
{
super.readFromNBT(par1NBTTagCompound);
this.containingItems = this.readStandardItemsFromNBT(par1NBTTagCompound);
this.locked = par1NBTTagCompound.getBoolean("locked");
}
@Override
public void writeToNBT(NBTTagCompound par1NBTTagCompound)
{
super.writeToNBT(par1NBTTagCompound);
this.writeStandardItemsToNBT(par1NBTTagCompound);
par1NBTTagCompound.setBoolean("locked", this.locked);
}
@Override
protected ItemStack[] getContainingItems()
{
return this.containingItems;
}
@Override
public String getName()
{
return GCCoreUtil.translate("container.cargoloader.name");
}
@Override
public boolean hasCustomName()
{
return true;
}
@Override
public IChatComponent getDisplayName()
{
return (this.hasCustomName() ? new ChatComponentText(this.getName()) : new ChatComponentTranslation(this.getName(), new Object[0]));
}
// ISidedInventory Implementation:
@Override
public int[] getSlotsForFace(EnumFacing side)
{
return side != this.getElectricInputDirection() ? new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 } : new int[] { };
}
@Override
public boolean canInsertItem(int slotID, ItemStack itemstack, EnumFacing side)
{
if (side != this.getElectricInputDirection())
{
if (slotID == 0)
{
return ItemElectricBase.isElectricItem(itemstack.getItem());
}
else
{
return true;
}
}
return false;
}
@Override
public boolean canExtractItem(int slotID, ItemStack itemstack, EnumFacing side)
{
return false;
}
@Override
public boolean isItemValidForSlot(int slotID, ItemStack itemstack)
{
if (slotID == 0)
{
return ItemElectricBase.isElectricItem(itemstack.getItem());
}
else
{
return true;
}
}
@Override
public boolean shouldUseEnergy()
{
return !this.getDisabled(0);
}
public EnumCargoLoadingState addCargo(ItemStack stack, boolean doAdd)
{
int count = 1;
for (count = 1; count < this.containingItems.length; count++)
{
ItemStack stackAt = this.containingItems[count];
if (stackAt != null && stackAt.getItem() == stack.getItem() && stackAt.getItemDamage() == stack.getItemDamage() && stackAt.stackSize < stackAt.getMaxStackSize())
{
if (stackAt.stackSize + stack.stackSize <= stackAt.getMaxStackSize())
{
if (doAdd)
{
this.containingItems[count].stackSize += stack.stackSize;
this.markDirty();
}
return EnumCargoLoadingState.SUCCESS;
}
else
{
//Part of the stack can fill this slot but there will be some left over
int origSize = stackAt.stackSize;
int surplus = origSize + stack.stackSize - stackAt.getMaxStackSize();
if (doAdd)
{
this.containingItems[count].stackSize = stackAt.getMaxStackSize();
this.markDirty();
}
stack.stackSize = surplus;
if (this.addCargo(stack, doAdd) == EnumCargoLoadingState.SUCCESS)
{
return EnumCargoLoadingState.SUCCESS;
}
this.containingItems[count].stackSize = origSize;
return EnumCargoLoadingState.FULL;
}
}
}
for (count = 1; count < this.containingItems.length; count++)
{
ItemStack stackAt = this.containingItems[count];
if (stackAt == null)
{
if (doAdd)
{
this.containingItems[count] = stack;
this.markDirty();
}
return EnumCargoLoadingState.SUCCESS;
}
}
return EnumCargoLoadingState.FULL;
}
public RemovalResult removeCargo(boolean doRemove)
{
for (int i = 1; i < this.containingItems.length; i++)
{
ItemStack stackAt = this.containingItems[i];
if (stackAt != null)
{
ItemStack resultStack = stackAt.copy();
resultStack.stackSize = 1;
if (doRemove && --stackAt.stackSize <= 0)
{
this.containingItems[i] = null;
}
if (doRemove)
{
this.markDirty();
}
return new RemovalResult(EnumCargoLoadingState.SUCCESS, resultStack);
}
}
return new RemovalResult(EnumCargoLoadingState.EMPTY, null);
}
@Override
public boolean canAttachToLandingPad(IBlockAccess world, BlockPos pos)
{
return true;
}
@Override
public EnumFacing getFront()
{
return this.worldObj.getBlockState(getPos()).getValue(BlockCargoLoader.FACING);
}
@Override
public EnumFacing getElectricInputDirection()
{
return getFront().rotateY();
}
@Override
public void clearLockedInventory()
{
for (int i = 1; i < 15; i++)
{
this.containingItems[i] = null;
}
}
@Override
public boolean getLocked()
{
return this.locked;
}
}