package org.cyclops.integrateddynamics.core.evaluate.variable;

import net.minecraft.util.EnumFacing;
import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.IItemHandler;
import org.cyclops.cyclopscore.datastructure.DimPos;
import org.cyclops.cyclopscore.helper.TileHelpers;
import org.cyclops.cyclopscore.persist.nbt.INBTProvider;

import java.util.Iterator;

/**
 * A list proxy for an inventory at a certain position.
 */
public class ValueTypeListProxyPositionedInventory extends ValueTypeListProxyPositioned<ValueObjectTypeItemStack, ValueObjectTypeItemStack.ValueItemStack> implements INBTProvider {

    public ValueTypeListProxyPositionedInventory(DimPos pos, EnumFacing side) {
        super(ValueTypeListProxyFactories.POSITIONED_INVENTORY.getName(), ValueTypes.OBJECT_ITEMSTACK, pos, side);
    }

    public ValueTypeListProxyPositionedInventory() {
        this(null, null);
    }

    protected IItemHandler getInventory() {
        return TileHelpers.getCapability(getPos(), getSide(), CapabilityItemHandler.ITEM_HANDLER_CAPABILITY);
    }

    @Override
    public int getLength() {
        IItemHandler inventory = getInventory();
        if(inventory == null) {
            return 0;
        }
        return inventory.getSlots();
    }

    @Override
    public ValueObjectTypeItemStack.ValueItemStack get(int index) {
        return ValueObjectTypeItemStack.ValueItemStack.of(getInventory().getStackInSlot(index));
    }

    @Override
    public Iterator<ValueObjectTypeItemStack.ValueItemStack> iterator() {
        // We use a custom iterator that retrieves the itemhandler capability only once.
        // Because for large inventories, the capability would have to be retrieved for every single slot,
        // which could result in a major performance problem.
        return new ValueTypeListProxyPositionedInventory.ListFactoryIterator(getInventory());
    }

    public static class ListFactoryIterator implements Iterator<ValueObjectTypeItemStack.ValueItemStack> {

        private final IItemHandler itemHandler;
        private int index = 0;

        public ListFactoryIterator(IItemHandler itemHandler) {
            this.itemHandler = itemHandler;
        }

        @Override
        public boolean hasNext() {
            return itemHandler != null && index < itemHandler.getSlots();
        }

        @Override
        public ValueObjectTypeItemStack.ValueItemStack next() {
            return ValueObjectTypeItemStack.ValueItemStack.of(this.itemHandler.getStackInSlot(index++));
        }

        @Override
        public void remove() {
            throw new UnsupportedOperationException("remove");
        }
    }
}

@@ -57,16 +57,53 @@
 iable;%0A%0A
+import net.minecraft.item.ItemStack;%0A
 import n
@@ -132,16 +132,16 @@
 Facing;%0A
-
 import n
@@ -395,16 +395,50 @@
 vider;%0A%0A
+import javax.annotation.Nullable;%0A
 import j
@@ -987,24 +987,38 @@
 ll);%0A    %7D%0A%0A
+    @Nullable%0A
     protecte
@@ -1444,24 +1444,73 @@
 nt index) %7B%0A
+        IItemHandler inventory = getInventory();%0A
         retu
@@ -1555,28 +1555,63 @@
 tack.of(
-getI
+inventory == null ? ItemStack.EMPTY : i
 nventory
 ().getSt
@@ -1602,18 +1602,16 @@
 nventory
-()
 .getStac
@@ -2185,24 +2185,42 @@
 emStack%3E %7B%0A%0A
+        @Nullable%0A
         priv
@@ -2322,16 +2322,26 @@
 terator(
+@Nullable 
 IItemHan
@@ -2627,32 +2627,32 @@
 mStack next() %7B%0A
-
             retu
@@ -2709,24 +2709,69 @@
 .itemHandler
+ == null ? ItemStack.EMPTY : this.itemHandler
 .getStackInS

Fix crash when reading from non-existing inventory