package mcjty.immcraft.api.generic;

import mcjty.immcraft.api.handles.HandleSelector;
import mcjty.immcraft.api.handles.HandleSupport;
import mcjty.immcraft.api.handles.IInterfaceHandle;
import mcjty.immcraft.api.helpers.IntersectionTools;
import mcjty.immcraft.api.helpers.NBTHelper;
import mcjty.immcraft.api.input.KeyType;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.NetworkManager;
import net.minecraft.network.play.server.SPacketUpdateTileEntity;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;

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


public class GenericTE extends TileEntity {

    protected HandleSupport handleSupport = new HandleSupport();

    public GenericBlock getBlock() {
        return (GenericBlock) getBlockType();
    }

    public List<String> getIngredients() {
        return Collections.emptyList();
    }

    public List<String> getMissingIngredients() {
        return Collections.emptyList();
    }

    // Client side
    public void setIngredients(List<String> ingredients, List<String> missingIngredients) {

    }

    public void calculateIngredients(List<String> ingredients, List<String> missingIngredients, EntityPlayer player) {
    }


    @Override
    public boolean shouldRefresh(World world, BlockPos pos, IBlockState oldState, IBlockState newState) {
        return oldState.getBlock() != newState.getBlock();
    }

    @Override
    public NBTTagCompound getUpdateTag() {
        return writeToNBT(new NBTTagCompound());
    }

    @Nullable
    @Override
    public SPacketUpdateTileEntity getUpdatePacket() {
        NBTTagCompound nbtTag = new NBTTagCompound();
        this.writeToNBT(nbtTag);
        return new SPacketUpdateTileEntity(getPos(), 1, nbtTag);
    }

    public void markDirtyQuick() {
        if (getWorld() != null) {
            getWorld().markChunkDirty(this.pos, this);
        }
    }

    public void markDirtyClient() {
        markDirtyQuick();
        if (getWorld() != null) {
            IBlockState state = getWorld().getBlockState(getPos());
            getWorld().notifyBlockUpdate(getPos(), state, state, 3);
        }
    }

    @Override
    public void onDataPacket(NetworkManager net, SPacketUpdateTileEntity packet) {
        this.readFromNBT(packet.getNbtCompound());
    }

    public void addInterfaceHandle(IInterfaceHandle handle) {
        handleSupport.addInterfaceHandle(handle);
    }

    public List<IInterfaceHandle> getInterfaceHandles() {
        return handleSupport.getInterfaceHandles();
    }

    public boolean onClick(EntityPlayer player) {
        IInterfaceHandle handle = getHandle(player);
        if (handle != null) {
            return handleSupport.handleClick(this, player, handle);
        }

        return false;
    }

    /**
     * Should be called server side on activation.
     */
    public boolean onActivate(EntityPlayer player) {
        IInterfaceHandle handle = getHandle(player);
        if (handle != null) {
            return handleSupport.handleActivate(this, player, handle);
        }

        return false;
    }

    public IInterfaceHandle getHandle(EntityPlayer player) {
        IInterfaceHandle handle = null;
        RayTraceResult traceResult = IntersectionTools.getMovingObjectPositionFromPlayer(getWorld(), player, true);
        if (traceResult != null && traceResult.hitInfo instanceof HandleSelector) {
            HandleSelector selector = (HandleSelector) traceResult.hitInfo;
            handle = handleSupport.getHandleWithID(selector.getId());
        }
        return handle;
    }


    /**
     * Called server side on keypress
     */
    public void onKeyPress(KeyType keyType, EntityPlayer player, EnumFacing worldSide, EnumFacing side, Vec3d hitVec) {
        IInterfaceHandle handle = getHandle(player);
        if (handle != null) {
            handle.onKeyPress(this, keyType, player);
        }
    }

    @Override
    public NBTTagCompound writeToNBT(NBTTagCompound tagCompound) {
        super.writeToNBT(tagCompound);
        writeToNBT(NBTHelper.create(tagCompound));
        return tagCompound;
    }

    protected void writeToNBT(NBTHelper helper) {
    }
}

@@ -331,45 +331,42 @@
 ort 
-net.minecraft.block.state.IBlockState
+mcjty.lib.entity.GenericTileEntity
 ;%0Aim
@@ -478,219 +478,23 @@
 aft.
-network.NetworkManager;%0Aimport net.minecraft.network.play.server.SPacketUpdateTileEntity;%0Aimport net.minecraft.tileentity.TileEntity;%0Aimport net.minecraft.util.EnumFacing;%0Aimport net.minecraft.util.math.BlockPos
+util.EnumFacing
 ;%0Aim
@@ -580,76 +580,8 @@
 3d;%0A
-import net.minecraft.world.World;%0A%0Aimport javax.annotation.Nullable;
 %0Aimp
@@ -663,16 +663,23 @@
 extends 
+Generic
 TileEnti
@@ -1277,1095 +1277,8 @@
 %7D%0A%0A%0A
-    @Override%0A    public boolean shouldRefresh(World world, BlockPos pos, IBlockState oldState, IBlockState newState) %7B%0A        return oldState.getBlock() != newState.getBlock();%0A    %7D%0A%0A    @Override%0A    public NBTTagCompound getUpdateTag() %7B%0A        return writeToNBT(new NBTTagCompound());%0A    %7D%0A%0A    @Nullable%0A    @Override%0A    public SPacketUpdateTileEntity getUpdatePacket() %7B%0A        NBTTagCompound nbtTag = new NBTTagCompound();%0A        this.writeToNBT(nbtTag);%0A        return new SPacketUpdateTileEntity(getPos(), 1, nbtTag);%0A    %7D%0A%0A    public void markDirtyQuick() %7B%0A        if (getWorld() != null) %7B%0A            getWorld().markChunkDirty(this.pos, this);%0A        %7D%0A    %7D%0A%0A    public void markDirtyClient() %7B%0A        markDirtyQuick();%0A        if (getWorld() != null) %7B%0A            IBlockState state = getWorld().getBlockState(getPos());%0A            getWorld().notifyBlockUpdate(getPos(), state, state, 3);%0A        %7D%0A    %7D%0A%0A    @Override%0A    public void onDataPacket(NetworkManager net, SPacketUpdateTileEntity packet) %7B%0A        this.readFromNBT(packet.getNbtCompound());%0A    %7D%0A%0A
     

Use McJtyLib GenericTileEntity