package com.raoulvdberge.refinedstorage.item;

import com.raoulvdberge.refinedstorage.RSBlocks;
import com.raoulvdberge.refinedstorage.api.network.INetwork;
import com.raoulvdberge.refinedstorage.api.network.item.INetworkItemProvider;
import net.minecraft.block.Block;
import net.minecraft.client.resources.I18n;
import net.minecraft.client.util.ITooltipFlag;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.*;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.text.TextComponentTranslation;
import net.minecraft.world.World;
import net.minecraftforge.common.DimensionManager;

import javax.annotation.Nullable;
import java.util.List;

public abstract class ItemNetworkItem extends ItemEnergyItem implements INetworkItemProvider {
    private static final String NBT_CONTROLLER_X = "ControllerX";
    private static final String NBT_CONTROLLER_Y = "ControllerY";
    private static final String NBT_CONTROLLER_Z = "ControllerZ";
    private static final String NBT_DIMENSION_ID = "DimensionID";

    public ItemNetworkItem(String name) {
        super(name);

        addPropertyOverride(new ResourceLocation("connected"), (stack, world, entity) -> (entity != null && isValid(stack)) ? 1.0f : 0.0f);
    }

    @Override
    public ActionResult<ItemStack> onItemRightClick(World world, EntityPlayer player, EnumHand hand) {
        ItemStack stack = player.getHeldItem(hand);

        if (!world.isRemote) {
            if (!isValid(stack)) {
                player.sendMessage(new TextComponentTranslation("misc.refinedstorage:network_item.not_found"));
            } else {
                World networkWorld = DimensionManager.getWorld(getDimensionId(stack));

                TileEntity network;

                if (networkWorld != null && ((network = networkWorld.getTileEntity(new BlockPos(getX(stack), getY(stack), getZ(stack)))) instanceof INetwork)) {
                    ((INetwork) network).getNetworkItemHandler().onOpen(player, hand);
                } else {
                    player.sendMessage(new TextComponentTranslation("misc.refinedstorage:network_item.not_found"));
                }
            }
        }

        return ActionResult.newResult(EnumActionResult.SUCCESS, stack);
    }

    @Override
    public void addInformation(ItemStack stack, @Nullable World world, List<String> tooltip, ITooltipFlag flag) {
        super.addInformation(stack, world, tooltip, flag);

        if (isValid(stack)) {
            tooltip.add(I18n.format("misc.refinedstorage:network_item.tooltip", getX(stack), getY(stack), getZ(stack)));
        }
    }

    @Override
    public EnumActionResult onItemUse(EntityPlayer player, World world, BlockPos pos, EnumHand hand, EnumFacing facing, float hitX, float hitY, float hitZ) {
        ItemStack stack = player.getHeldItem(hand);

        Block block = world.getBlockState(pos).getBlock();

        if (block == RSBlocks.CONTROLLER) {
            NBTTagCompound tag = stack.getTagCompound();

            if (tag == null) {
                tag = new NBTTagCompound();
            }

            tag.setInteger(NBT_CONTROLLER_X, pos.getX());
            tag.setInteger(NBT_CONTROLLER_Y, pos.getY());
            tag.setInteger(NBT_CONTROLLER_Z, pos.getZ());
            tag.setInteger(NBT_DIMENSION_ID, player.dimension);

            stack.setTagCompound(tag);

            return EnumActionResult.SUCCESS;
        }

        return EnumActionResult.PASS;
    }

    public static int getDimensionId(ItemStack stack) {
        return stack.getTagCompound().getInteger(NBT_DIMENSION_ID);
    }

    public static int getX(ItemStack stack) {
        return stack.getTagCompound().getInteger(NBT_CONTROLLER_X);
    }

    public static int getY(ItemStack stack) {
        return stack.getTagCompound().getInteger(NBT_CONTROLLER_Y);
    }

    public static int getZ(ItemStack stack) {
        return stack.getTagCompound().getInteger(NBT_CONTROLLER_Z);
    }

    @Override
    public boolean shouldCauseReequipAnimation(ItemStack oldStack, ItemStack newStack, boolean slotChanged) {
        if (oldStack.getItem() == newStack.getItem()) {
            if (isValid(oldStack) && isValid(newStack)) {
                if (getX(oldStack) == getX(newStack) && getY(oldStack) == getY(newStack) && getZ(oldStack) == getZ(newStack) && getDimensionId(oldStack) == getDimensionId(newStack)) {
                    return false;
                }
            }
        }

        return super.shouldCauseReequipAnimation(oldStack, newStack, slotChanged);
    }

    public boolean isValid(ItemStack stack) {
        return stack.hasTagCompound()
            && stack.getTagCompound().hasKey(NBT_CONTROLLER_X)
            && stack.getTagCompound().hasKey(NBT_CONTROLLER_Y)
            && stack.getTagCompound().hasKey(NBT_CONTROLLER_Z)
            && stack.getTagCompound().hasKey(NBT_DIMENSION_ID);
    }
}

@@ -793,16 +793,52 @@
 il.List;
+%0Aimport java.util.function.Consumer;
 %0A%0Apublic
@@ -1619,30 +1619,102 @@
     
-if (!isValid(stack)) %7B
+applyNetwork(stack, n -%3E n.getNetworkItemHandler().onOpen(player, hand), player::sendMessage);
 %0A   
@@ -1714,32 +1714,35 @@
 e);%0A        
+%7D%0A%0A
         
 player.sendM
@@ -1729,34 +1729,284 @@
         
-player.sendMessage
+return ActionResult.newResult(EnumActionResult.SUCCESS, stack);%0A    %7D%0A%0A    public void applyNetwork(ItemStack stack, Consumer%3CINetwork%3E networkConsumer, Consumer%3CTextComponentTranslation%3E errorConsumer) %7B%0A        if (!isValid(stack)) %7B%0A            errorConsumer.accept
 (new Tex
@@ -2067,36 +2067,32 @@
 m.not_found%22));%0A
-    
         %7D else %7B
@@ -2104,20 +2104,16 @@
         
-    
 World ne
@@ -2188,20 +2188,16 @@
         
-    
 TileEnti
@@ -2217,28 +2217,24 @@
             
- 
-   
 if (networkW
@@ -2386,83 +2386,52 @@
     
-    ((INetwork) network).getNetworkItemHandler().onOpen(player, hand);%0A    
+networkConsumer.accept((INetwork) network);%0A
     
@@ -2467,30 +2467,28 @@
     
-    player.sendMessage
+errorConsumer.accept
 (new
@@ -2577,110 +2577,19 @@
     
-    %7D%0A            %7D%0A        %7D%0A%0A        return ActionResult.newResult(EnumActionResult.SUCCESS, stack);
+%7D%0A        %7D
 %0A   

Add another RS addons hook