package mekanism.common.util;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import mekanism.api.Coord4D;
import mekanism.api.transmitters.ITransmitterTile;
import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.common.util.ForgeDirection;
import net.minecraftforge.fluids.FluidRegistry;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.FluidTankInfo;
import net.minecraftforge.fluids.IFluidHandler;
public final class PipeUtils
{
public static final FluidTankInfo[] EMPTY = new FluidTankInfo[] {};
public static boolean isValidAcceptorOnSide(TileEntity tile, ForgeDirection side)
{
if(tile instanceof ITransmitterTile || !(tile instanceof IFluidHandler))
return false;
IFluidHandler container = (IFluidHandler)tile;
FluidTankInfo[] infoArray = container.getTankInfo(side.getOpposite());
if(container.canDrain(side.getOpposite(), FluidRegistry.WATER)
|| container.canFill(side.getOpposite(), FluidRegistry.WATER)) //I hesitate to pass null to these.
{
return true;
}
else if(infoArray != null && infoArray.length > 0)
{
for(FluidTankInfo info : infoArray)
{
if(info != null)
{
return true;
}
}
}
return false;
}
/**
* Gets all the acceptors around a tile entity.
* @param tileEntity - center tile entity
* @return array of IFluidHandlers
*/
public static IFluidHandler[] getConnectedAcceptors(TileEntity tileEntity)
{
IFluidHandler[] acceptors = new IFluidHandler[] {null, null, null, null, null, null};
for(ForgeDirection orientation : ForgeDirection.VALID_DIRECTIONS)
{
TileEntity acceptor = Coord4D.get(tileEntity).getFromSide(orientation).getTileEntity(tileEntity.getWorldObj());
if(acceptor instanceof IFluidHandler && !(acceptor instanceof ITransmitterTile))
{
acceptors[orientation.ordinal()] = (IFluidHandler)acceptor;
}
}
return acceptors;
}
/**
* Emits fluid from a central block by splitting the received stack among the sides given.
* @param sides - the list of sides to output from
* @param stack - the stack to output
* @param from - the TileEntity to output from
* @return the amount of gas emitted
*/
public static int emit(List<ForgeDirection> sides, FluidStack stack, TileEntity from)
{
if(stack == null)
{
return 0;
}
List<IFluidHandler> availableAcceptors = new ArrayList<IFluidHandler>();
IFluidHandler[] possibleAcceptors = getConnectedAcceptors(from);
for(int i = 0; i < possibleAcceptors.length; i++)
{
IFluidHandler handler = possibleAcceptors[i];
if(handler != null && handler.canFill(ForgeDirection.getOrientation(i).getOpposite(), stack.getFluid()))
{
availableAcceptors.add(handler);
}
}
Collections.shuffle(availableAcceptors);
int toSend = stack.amount;
int prevSending = toSend;
if(!availableAcceptors.isEmpty())
{
int divider = availableAcceptors.size();
int remaining = toSend % divider;
int sending = (toSend-remaining)/divider;
for(IFluidHandler acceptor : availableAcceptors)
{
int currentSending = sending;
if(remaining > 0)
{
currentSending++;
remaining--;
}
ForgeDirection dir = ForgeDirection.getOrientation(Arrays.asList(possibleAcceptors).indexOf(acceptor)).getOpposite();
toSend -= acceptor.fill(dir, new FluidStack(stack.getFluid(), currentSending), true);
}
}
return prevSending-toSend;
}
}