package refinedstorage.tile.autocrafting.task;

import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.tileentity.TileEntityHopper;
import net.minecraft.util.text.TextFormatting;
import refinedstorage.RefinedStorageUtils;
import refinedstorage.tile.TileController;
import refinedstorage.tile.autocrafting.CraftingPattern;
import refinedstorage.tile.autocrafting.TileCrafter;

public class ProcessingCraftingTask implements ICraftingTask {
    public static final int ID = 1;

    public static final String NBT_INSERTED = "Inserted";
    public static final String NBT_CHILD_TASKS = "ChildTasks";
    public static final String NBT_SATISFIED = "Satisfied";

    private CraftingPattern pattern;
    private boolean inserted[];
    private boolean childTasks[];
    private boolean satisfied[];

    public ProcessingCraftingTask(CraftingPattern pattern) {
        this.pattern = pattern;
        this.inserted = new boolean[pattern.getInputs().length];
        this.childTasks = new boolean[pattern.getInputs().length];
        this.satisfied = new boolean[pattern.getOutputs().length];
    }

    public ProcessingCraftingTask(NBTTagCompound tag, CraftingPattern pattern) {
        this.pattern = pattern;
        this.inserted = RefinedStorageUtils.readBooleanArray(tag, NBT_INSERTED);
        this.childTasks = RefinedStorageUtils.readBooleanArray(tag, NBT_CHILD_TASKS);
        this.satisfied = RefinedStorageUtils.readBooleanArray(tag, NBT_SATISFIED);
    }

    @Override
    public CraftingPattern getPattern() {
        return pattern;
    }

    @Override
    public boolean update(TileController controller) {
        TileCrafter crafter = pattern.getCrafter(controller.getWorld());
        TileEntity crafterFacing = crafter.getWorld().getTileEntity(crafter.getPos().offset(crafter.getDirection()));

        if (crafterFacing instanceof IInventory) {
            for (int i = 0; i < inserted.length; ++i) {
                if (!inserted[i]) {
                    ItemStack input = pattern.getInputs()[i];
                    ItemStack took = controller.take(input);

                    if (took != null) {
                        ItemStack remaining = TileEntityHopper.putStackInInventoryAllSlots((IInventory) crafterFacing, took, crafter.getDirection().getOpposite());

                        if (remaining == null) {
                            inserted[i] = true;
                        } else {
                            controller.push(took);
                        }
                    } else if (!childTasks[i]) {
                        CraftingPattern pattern = controller.getPattern(input);

                        if (pattern != null) {
                            childTasks[i] = true;

                            controller.addCraftingTask(pattern);

                            break;
                        }
                    } else {
                        break;
                    }
                }
            }
        } else {
            return true;
        }

        for (int i = 0; i < satisfied.length; ++i) {
            if (!satisfied[i]) {
                return false;
            }
        }

        return true;
    }

    public void onPushed(ItemStack inserted) {
        for (int i = 0; i < pattern.getOutputs().length; ++i) {
            if (!satisfied[i] && RefinedStorageUtils.compareStackNoQuantity(inserted, pattern.getOutputs()[i])) {
                satisfied[i] = true;

                return;
            }
        }
    }

    @Override
    public void onDone(TileController controller) {
        // NO OP
    }

    @Override
    public void onCancelled(TileController controller) {
        // NO OP
    }

    @Override
    public void writeToNBT(NBTTagCompound tag) {
        NBTTagCompound patternTag = new NBTTagCompound();
        pattern.writeToNBT(patternTag);
        tag.setTag(CraftingPattern.NBT, patternTag);

        RefinedStorageUtils.writeBooleanArray(tag, NBT_INSERTED, inserted);
        RefinedStorageUtils.writeBooleanArray(tag, NBT_CHILD_TASKS, childTasks);
        RefinedStorageUtils.writeBooleanArray(tag, NBT_SATISFIED, satisfied);

        tag.setInteger("Type", ID);
    }

    @Override
    public String getInfo() {
        StringBuilder builder = new StringBuilder();

        builder.append(TextFormatting.YELLOW).append("{missing_items}").append(TextFormatting.RESET).append("\n");

        int missingItems = 0;

        for (int i = 0; i < pattern.getInputs().length; ++i) {
            ItemStack input = pattern.getInputs()[i];

            if (!inserted[i] && !childTasks[i]) {
                builder.append("- ").append(input.getDisplayName()).append("\n");

                missingItems++;
            }
        }

        if (missingItems == 0) {
            builder.append(TextFormatting.GRAY).append(TextFormatting.ITALIC).append("{none}").append(TextFormatting.RESET).append("\n");
        }

        builder.append(TextFormatting.YELLOW).append("{items_crafting}").append(TextFormatting.RESET).append("\n");

        int itemsCrafting = 0;

        for (int i = 0; i < pattern.getInputs().length; ++i) {
            ItemStack input = pattern.getInputs()[i];

            if (!inserted[i] && childTasks[i]) {
                builder.append("- ").append(input.getUnlocalizedName()).append(".name").append("\n");

                itemsCrafting++;
            }
        }

        if (itemsCrafting == 0) {
            builder.append(TextFormatting.GRAY).append(TextFormatting.ITALIC).append("{none}").append(TextFormatting.RESET).append("\n");
        }

        builder.append(TextFormatting.YELLOW).append("{items_processing}").append(TextFormatting.RESET).append("\n");

        int itemsProcessing = 0;

        for (int i = 0; i < pattern.getInputs().length; ++i) {
            ItemStack input = pattern.getInputs()[i];

            if (inserted[i]) {
                builder.append("- ").append(input.getDisplayName()).append("\n");

                itemsProcessing++;
            }
        }

        if (itemsProcessing == 0) {
            builder.append(TextFormatting.GRAY).append(TextFormatting.ITALIC).append("{none}").append(TextFormatting.RESET).append("\n");
        }

        return builder.toString();
    }
}

@@ -45,51 +45,8 @@
 k;%0A%0A
-import net.minecraft.inventory.IInventory;%0A
 impo
@@ -144,126 +144,78 @@
 aft.
+u
 til
-eentity.TileEntity;%0Aimport net.minecraft.tileentity.TileEntityHopper;%0Aimport net.minecraft.util.text.TextFormatting
+.text.TextFormatting;%0Aimport net.minecraftforge.items.IItemHandler
 ;%0Aim
@@ -1738,92 +1738,91 @@
     
-TileEntity crafterFacing = crafter.getWorld().getTileEntity(crafter.getPos().offset(
+IItemHandler handler = RefinedStorageUtils.getItemHandler(crafter.getFacingTile(), 
 craf
@@ -1839,16 +1839,29 @@
 ection()
+.getOpposite(
 ));%0A%0A   
@@ -1873,43 +1873,23 @@
 if (
-crafterFacing instanceof IInventory
+handler != null
 ) %7B%0A
@@ -2172,198 +2172,205 @@
     
-ItemStack remaining = TileEntityHopper.putStackInInventoryAllSlots((IInventory) crafterFacing, took, crafter.getDirection().getOpposite());%0A%0A                        if (remaining == null) %7B%0A
+for (int j = 0; j %3C handler.getSlots(); ++j) %7B%0A                            if (handler.insertItem(j, took, true) == null) %7B%0A                                handler.insertItem(j, took, false);%0A%0A    
     
@@ -2409,24 +2409,25 @@
 %5Bi%5D = true;%0A
+%0A
             
@@ -2430,38 +2430,145 @@
                 
-%7D else
+        break;%0A                            %7D%0A                        %7D%0A%0A                        if (!inserted%5Bi%5D)
  %7B%0A             

Use IItemHandler in ProcessingCraftingTask too