package mcjty.rftools.blocks.crafter;

import mcjty.lib.container.*;
import mcjty.rftools.RFTools;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ResourceLocation;

public class CrafterContainer extends GenericContainer {
    public static final String CONTAINER_INVENTORY = "container";

    public static final int SLOT_CRAFTINPUT = 0;
    public static final int SLOT_CRAFTOUTPUT = 9;
    public static final int SLOT_BUFFER = 10;
    public static final int BUFFER_SIZE = (13*2);
    public static final int SLOT_BUFFEROUT = SLOT_BUFFER + BUFFER_SIZE;
    public static final int BUFFEROUT_SIZE = 4;
    public static final int SLOT_FILTER_MODULE = SLOT_BUFFEROUT + BUFFEROUT_SIZE;

    private final CrafterBaseTE crafterBaseTE;

    public CrafterBaseTE getCrafterTE() {
        return crafterBaseTE;
    }

    public static final ContainerFactory CONTAINER_FACTORY = new ContainerFactory(new ResourceLocation(RFTools.MODID, "gui/crafter.gui"));

    public CrafterContainer(EntityPlayer player, IInventory containerInventory) {
        super(CONTAINER_FACTORY);
        this.crafterBaseTE = (CrafterBaseTE)containerInventory; // TODO once this method is no longer reflectively called, refactor to remove this cast
        addInventory(CONTAINER_INVENTORY, containerInventory);
        addInventory(ContainerFactory.CONTAINER_PLAYER, player.inventory);
        generateSlots();
    }

    @Override
    protected Slot createSlot(SlotFactory slotFactory, IInventory inventory, int index, int x, int y, SlotType slotType) {
        if (index >= SLOT_BUFFER && index < SLOT_BUFFEROUT && slotType == SlotType.SLOT_INPUT) {
            return new BaseSlot(inventory, index, x, y) {
                @Override
                public boolean isItemValid(ItemStack stack) {
                    if (!crafterBaseTE.isItemValidForSlot(getSlotIndex(), stack)) {
                        return false;
                    }
                    return super.isItemValid(stack);
                }

                @Override
                public void onSlotChanged() {
                    crafterBaseTE.noRecipesWork = false;
                    super.onSlotChanged();
                }
            };
        } else if (index >= SLOT_BUFFEROUT && index < SLOT_FILTER_MODULE) {
            return new BaseSlot(inventory, index, x, y) {
                @Override
                public boolean isItemValid(ItemStack stack) {
                    if (!crafterBaseTE.isItemValidForSlot(getSlotIndex(), stack)) {
                        return false;
                    }
                    return super.isItemValid(stack);
                }

                @Override
                public void onSlotChanged() {
                    crafterBaseTE.noRecipesWork = false;
                    super.onSlotChanged();
                }
            };
        }
        return super.createSlot(slotFactory, inventory, index, x, y, slotType);
    }
}

@@ -62,16 +62,54 @@
 iner.*;%0A
+import mcjty.lib.varia.ItemStackList;%0A
 import m
@@ -179,16 +179,58 @@
 Player;%0A
+import net.minecraft.inventory.ClickType;%0A
 import n
@@ -3149,11 +3149,985 @@
 );%0A    %7D
+%0A%0A    @Override%0A    public ItemStack slotClick(int index, int button, ClickType mode, EntityPlayer player) %7B%0A        // Allow replacing input slot ghost items by shift-clicking.%0A        if (mode == ClickType.QUICK_MOVE &&%0A            index %3E= CrafterContainer.SLOT_BUFFER &&%0A            index %3C CrafterContainer.SLOT_BUFFEROUT) %7B%0A%0A            int offset = index - CrafterContainer.SLOT_BUFFER;%0A            ItemStackList ghostSlots = crafterBaseTE.getGhostSlots();%0A            ItemStack ghostSlot = ghostSlots.get(offset);%0A            ItemStack clickedWith = player.inventory.getItemStack();%0A            if (!ghostSlot.isEmpty() && !ghostSlot.isItemEqual(clickedWith)) %7B%0A                ItemStack copy = clickedWith.copy();%0A                copy.setCount(1);%0A                ghostSlots.set(offset, copy);%0A                detectAndSendChanges();%0A                return ItemStack.EMPTY;%0A            %7D%0A        %7D%0A%0A        return super.slotClick(index, button, mode, player);%0A    %7D
 %0A%7D%0A

Allow shift-click to replace crafter input ghost items