package org.cyclops.integrateddynamics.api.part;

import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import org.apache.commons.lang3.tuple.Pair;
import org.cyclops.cyclopscore.datastructure.DimPos;
import org.cyclops.cyclopscore.helper.TileHelpers;
import org.cyclops.integrateddynamics.api.network.IPartNetwork;
import org.cyclops.integrateddynamics.api.tileentity.ITileCableNetwork;

/**
 * Object holder to refer to a block side and position.
 * @author rubensworks
 */
public class PartPos {

    private final DimPos pos;
    private final EnumFacing side;

    public static PartPos of(World world, BlockPos pos, EnumFacing side) {
        return of(DimPos.of(world, pos), side);
    }

    public static PartPos of(DimPos pos, EnumFacing side) {
        return new PartPos(pos, side);
    }

    private PartPos(DimPos pos, EnumFacing side) {
        this.pos = pos;
        this.side = side;
    }

    public DimPos getPos() {
        return pos;
    }

    public EnumFacing getSide() {
        return side;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || !(o instanceof PartPos)) return false;

        PartPos partPos = (PartPos) o;

        if (!pos.equals(partPos.pos)) return false;
        return side == partPos.side;

    }

    @Override
    public int hashCode() {
        int result = pos.hashCode();
        result = 31 * result + side.hashCode();
        return result;
    }

    @Override
    public String toString() {
        return "PartPos{" +
                "pos=" + pos +
                ", side=" + side +
                '}';
    }

    /**
     * Get part data from the given position.
     * @param pos The part position.
     * @return A pair of part type and part state or null if not found.
     */
    public static Pair<IPartType, IPartState> getPartData(PartPos pos) {
        IPartContainer partContainer = TileHelpers.getSafeTile(pos.getPos().getWorld(), pos.getPos().getBlockPos(), IPartContainer.class);
        if(partContainer != null) {
            IPartType partType = partContainer.getPart(pos.getSide());
            IPartState partState = partContainer.getPartState(pos.getSide());
            if(partType != null && partState != null) {
                return Pair.of(partType, partState);
            }
        }
        return null;
    }

    /**
     * Get the network at the given position.
     * @param pos The part position.
     * @return The network or null if not found.
     */
    public static IPartNetwork getNetwork(PartPos pos) {
        ITileCableNetwork cableNetwork = TileHelpers.getSafeTile(pos.getPos().getWorld(), pos.getPos().getBlockPos(), ITileCableNetwork.class);
        return cableNetwork.getNetwork();
    }

}

@@ -257,59 +257,8 @@
 os;%0A
-import org.cyclops.cyclopscore.helper.TileHelpers;%0A
 impo
@@ -388,16 +388,80 @@
 Network;
+%0Aimport org.cyclops.integrateddynamics.core.helper.CableHelpers;
 %0A%0A/**%0A *
@@ -1973,16 +1973,22 @@
 ontainer
+Facade
  partCon
@@ -1993,21 +1993,28 @@
 ontainer
- = Ti
+Facade = Cab
 leHelper
@@ -2014,32 +2014,199 @@
 eHelpers.get
-SafeTile
+Interface(pos.getPos(), IPartContainerFacade.class);%0A        if (partContainerFacade != null) %7B%0A            IPartContainer partContainer = partContainerFacade.getPartContainer
 (pos.getPos(
@@ -2249,30 +2249,8 @@
 os()
-, IPartContainer.class
 );%0A 
@@ -2252,26 +2252,31 @@
 ));%0A        
+    
 if
+ 
 (partContain
@@ -2281,32 +2281,36 @@
 iner != null) %7B%0A
+    
             IPar
@@ -2372,24 +2372,28 @@
             
+    
 IPartState p
@@ -2438,32 +2438,36 @@
 pos.getSide());%0A
+    
             if(p
@@ -2464,16 +2464,17 @@
       if
+ 
 (partTyp
@@ -2519,24 +2519,28 @@
             
+    
 return Pair.
@@ -2560,24 +2560,42 @@
 partState);%0A
+                %7D%0A
             
@@ -2880,18 +2880,19 @@
 twork = 
-Ti
+Cab
 leHelper
@@ -2900,63 +2900,25 @@
 .get
-SafeTile(pos.getPos().getWorld(), pos.getPos().getBlock
+Interface(pos.get
 Pos(

Fix multipart crash on aspects with properties