package refinedstorage.apiimpl.storage;

import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import refinedstorage.RefinedStorageUtils;
import refinedstorage.api.network.INetworkMaster;
import refinedstorage.api.storage.IGroupedStorage;
import refinedstorage.api.storage.IStorage;

import java.util.Collection;
import java.util.List;

public class GroupedStorage implements IGroupedStorage {
    private INetworkMaster network;
    private Multimap<Item, ItemStack> stacks = ArrayListMultimap.create();

    public GroupedStorage(INetworkMaster network) {
        this.network = network;
    }

    @Override
    public void rebuild(List<IStorage> storages) {
        stacks.clear();

        for (IStorage storage : storages) {
            for (ItemStack stack : storage.getItems()) {
                add(stack);
            }
        }

        network.sendStorageToClient();
    }

    @Override
    public void add(ItemStack stack) {
        for (ItemStack otherStack : stacks.get(stack.getItem())) {
            if (RefinedStorageUtils.compareStackNoQuantity(otherStack, stack)) {
                otherStack.stackSize += stack.stackSize;

                network.sendStorageToClient();
                
                return;
            }
        }

        stacks.put(stack.getItem(), stack.copy());

        network.sendStorageToClient();
    }

    @Override
    public void remove(ItemStack stack) {
        for (ItemStack otherStack : stacks.get(stack.getItem())) {
            if (RefinedStorageUtils.compareStackNoQuantity(otherStack, stack)) {
                otherStack.stackSize -= stack.stackSize;

                if (otherStack.stackSize == 0) {
                    stacks.remove(otherStack.getItem(), otherStack);
                }

                network.sendStorageToClient();

                return;
            }
        }
    }

    @Override
    public ItemStack get(ItemStack stack, int flags) {
        for (ItemStack otherStack : stacks.get(stack.getItem())) {
            if (RefinedStorageUtils.compareStack(otherStack, stack, flags)) {
                return otherStack;
            }
        }

        return null;
    }

    @Override
    public Collection<ItemStack> getStacks() {
        return stacks.values();
    }
}

@@ -241,16 +241,73 @@
 eUtils;%0A
+import refinedstorage.api.autocrafting.ICraftingPattern;%0A
 import r
@@ -348,16 +348,16 @@
 Master;%0A
-
 import r
@@ -993,32 +993,317 @@
    %7D%0A        %7D%0A%0A
+        for (ICraftingPattern pattern : network.getPatterns()) %7B%0A            for (ItemStack output : pattern.getOutputs()) %7B%0A                ItemStack patternStack = output.copy();%0A                patternStack.stackSize = 0;%0A                add(patternStack);%0A            %7D%0A        %7D%0A%0A
         network.
@@ -1638,32 +1638,16 @@
 ient();%0A
-                
 %0A       

Add patterns to grouped storage