package mcjty.rftools.blocks.itemfilter;

import mcjty.lib.container.DefaultSidedInventory;
import mcjty.lib.container.InventoryHelper;
import mcjty.lib.entity.GenericTileEntity;
import mcjty.lib.network.Argument;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.EnumFacing;

import java.util.Map;

public class ItemFilterTileEntity extends GenericTileEntity implements DefaultSidedInventory {
    public static final String CMD_SETMODE = "setMode";

    private InventoryHelper inventoryHelper = new InventoryHelper(this, ItemFilterContainer.factory, ItemFilterContainer.GHOST_SIZE + ItemFilterContainer.BUFFER_SIZE);

    public static final byte OLDMODE_INPUT_EXACT = 2;
    public static final byte OLDMODE_INPUT = 1;
    public static final byte OLDMODE_DISABLED = 0;
    public static final byte OLDMODE_OUTPUT_EXACT = -1;
    public static final byte OLDMODE_OUTPUT = -2;

    private int inputMode[] = new int[6];
    private int outputMode[] = new int[6];

    public int[] getInputMode() {
        return inputMode;
    }

    public int[] getOutputMode() {
        return outputMode;
    }

    @Override
    public InventoryHelper getInventoryHelper() {
        return inventoryHelper;
    }

    @Override
    public void readFromNBT(NBTTagCompound tagCompound) {
        super.readFromNBT(tagCompound);
    }

    @Override
    public void readRestorableFromNBT(NBTTagCompound tagCompound) {
        super.readRestorableFromNBT(tagCompound);
        readBufferFromNBT(tagCompound, inventoryHelper);
        inputMode = tagCompound.getIntArray("inputs");
        outputMode = tagCompound.getIntArray("outputs");
    }

    @Override
    public void writeToNBT(NBTTagCompound tagCompound) {
        super.writeToNBT(tagCompound);
    }

    @Override
    public void writeRestorableToNBT(NBTTagCompound tagCompound) {
        super.writeRestorableToNBT(tagCompound);
        writeBufferToNBT(tagCompound, inventoryHelper);
        tagCompound.setIntArray("inputs", inputMode);
        tagCompound.setIntArray("outputs", outputMode);
    }

    @Override
    public boolean execute(EntityPlayerMP playerMP, String command, Map<String, Argument> args) {
        boolean rc = super.execute(playerMP, command, args);
        if (rc) {
            return true;
        }
        if (CMD_SETMODE.equals(command)) {
            Integer side = args.get("side").getInteger();
            Integer slot = args.get("slot").getInteger();
            Boolean input = args.get("input").getBoolean();
            Boolean output = args.get("output").getBoolean();

            inputMode[side] &= ~(1 << slot);
            if (input) {
                inputMode[side] |= 1 << slot;
            }
            outputMode[side] &= ~(1 << slot);
            if (output) {
                outputMode[side] |= 1 << slot;
            }

            markDirtyClient();
            return true;
        }
        return false;
    }

    @Override
    public int getInventoryStackLimit() {
        return 64;
    }

    @Override
    public boolean isUseableByPlayer(EntityPlayer player) {
        return canPlayerAccess(player);
    }

    @Override
    public boolean isItemValidForSlot(int index, ItemStack stack) {
        if (index < ItemFilterContainer.SLOT_BUFFER) {
            return true;
        }
        ItemStack ghostStack = inventoryHelper.getStackInSlot(index - ItemFilterContainer.SLOT_BUFFER);
        return ghostStack == null || ghostStack.isItemEqual(stack);
    }

    @Override
    public int[] getSlotsForFace(EnumFacing side) {
        int v = ItemFilterContainer.SLOT_BUFFER;
        return new int[] { v, v+1, v+2, v+3, v+4, v+5, v+6, v+7, v+8 };
    }

    @Override
    public boolean canInsertItem(int index, ItemStack stack, EnumFacing side) {
        if (index < ItemFilterContainer.SLOT_BUFFER) {
            return false;
        }
        if (!isInputMode(side, index - ItemFilterContainer.SLOT_BUFFER)) {
            return false;
        }

        int ghostIndex = index - ItemFilterContainer.SLOT_BUFFER;

        ItemStack ghostStack = inventoryHelper.getStackInSlot(ghostIndex);
        if (ghostStack == null) {
            // First check if there are other ghosted items for this side that match.
            // In that case we don't allow input here.
            int im = inputMode[side.ordinal()];
            for (int i = ItemFilterContainer.SLOT_GHOST ; i < ItemFilterContainer.SLOT_GHOST + ItemFilterContainer.GHOST_SIZE ; i++) {
                ItemStack g = inventoryHelper.getStackInSlot(i);
                if (g != null && ((im & (1<<i)) != 0) && g.isItemEqual(stack)) {
                    return false;
                }
            }
            return true;
        }
        return ghostStack.isItemEqual(stack);
    }

    @Override
    public boolean canExtractItem(int index, ItemStack stack, EnumFacing direction) {
        if (index < ItemFilterContainer.SLOT_BUFFER) {
            return false;
        }
        return isOutputMode(direction, index - ItemFilterContainer.SLOT_BUFFER);
    }

    private boolean isInputMode(EnumFacing side, int slot) {
        return (inputMode[side.ordinal()] & (1<<slot)) != 0;
    }

    private boolean isOutputMode(EnumFacing side, int slot) {
        return (outputMode[side.ordinal()] & (1<<slot)) != 0;
    }
}

@@ -207,16 +207,62 @@
 gument;%0A
+import mcjty.lib.varia.CustomSidedInvWrapper;%0A
 import n
@@ -298,24 +298,24 @@
 tityPlayer;%0A
-
 import net.m
@@ -468,16 +468,175 @@
 mFacing;
+%0Aimport net.minecraftforge.common.capabilities.Capability;%0Aimport net.minecraftforge.items.CapabilityItemHandler;%0Aimport net.minecraftforge.items.IItemHandler;
 %0A%0Aimport
@@ -804,16 +804,16 @@
 Mode%22;%0A%0A
+
     priv
@@ -977,268 +977,8 @@
 );%0A%0A
-    public static final byte OLDMODE_INPUT_EXACT = 2;%0A    public static final byte OLDMODE_INPUT = 1;%0A    public static final byte OLDMODE_DISABLED = 0;%0A    public static final byte OLDMODE_OUTPUT_EXACT = -1;%0A    public static final byte OLDMODE_OUTPUT = -2;%0A%0A
     
@@ -5394,11 +5394,675 @@
 0;%0A    %7D
+%0A%0A    IItemHandler invHandler = new CustomSidedInvWrapper(this);%0A%0A    @Override%0A    public boolean hasCapability(Capability%3C?%3E capability, EnumFacing facing) %7B%0A        if (capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) %7B%0A            return true;%0A        %7D%0A        return super.hasCapability(capability, facing);%0A    %7D%0A%0A    @Override%0A    public %3CT%3E T getCapability(net.minecraftforge.common.capabilities.Capability%3CT%3E capability, net.minecraft.util.EnumFacing facing) %7B%0A        if (capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) %7B%0A            return (T) invHandler;%0A        %7D%0A        return super.getCapability(capability, facing);%0A    %7D
 %0A%7D%0A

Support IItemHandler in the item filter