package com.amadornes.framez.movement;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import net.minecraft.block.Block;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;
import codechicken.lib.vec.BlockCoord;
import codechicken.multipart.TMultiPart;
import codechicken.multipart.TileMultipart;
import com.amadornes.framez.api.movement.IFrame;
import com.amadornes.framez.api.movement.IFrameMovementRegistry;
import com.amadornes.framez.api.movement.IMovable;
import com.amadornes.framez.api.movement.IMovementDataProvider;
import com.amadornes.framez.api.movement.IMovementHandler;
import com.amadornes.framez.api.movement.IMovingBlock;
import com.amadornes.framez.api.movement.IStickinessHandler;
import com.amadornes.framez.api.movement.ISticky;
import com.amadornes.framez.api.movement.IStickyProvider;
import com.amadornes.framez.util.SorterPriority;
public class FrameMovementRegistry implements IFrameMovementRegistry {
private static final FrameMovementRegistry instance = new FrameMovementRegistry();
public static FrameMovementRegistry instance() {
return instance;
}
private List<IMovementDataProvider> dataProviders = new ArrayList<IMovementDataProvider>();
private List<IMovementHandler> movementHandlers = new ArrayList<IMovementHandler>();
private List<IStickyProvider> stickyProviders = new ArrayList<IStickyProvider>();
private List<IStickinessHandler> stickinessHandlers = new ArrayList<IStickinessHandler>();
private boolean canRegisterMovementHandlers = true;
private boolean canRegisterStickyProviders = true;
private boolean canRegisterStickinessHandlers = true;
@Override
public void registerMovementDataProvider(IMovementDataProvider provider) {
// FIXME Change returns to throws
if (provider == null)
return;
if (dataProviders.contains(provider))
return;
dataProviders.add(provider);
}
@Override
public void registerMovementHandler(IMovementHandler handler) {
if (!canRegisterMovementHandlers)
throw new RuntimeException("All the movement handlers have already been sorted and set up. Register yours before!");
if (handler == null)
return;
if (movementHandlers.contains(handler))
return;
movementHandlers.add(handler);
}
@Override
public void registerStickyProvider(IStickyProvider provider) {
if (!canRegisterStickyProviders)
throw new RuntimeException("All the sticky providers have already been sorted and set up. Register yours before!");
if (provider == null)
return;
if (stickyProviders.contains(provider))
return;
stickyProviders.add(provider);
}
@Override
public void registerStickinessHandler(IStickinessHandler handler) {
if (!canRegisterStickinessHandlers)
throw new RuntimeException("All the stickiness handlers have already been sorted and set up. Register yours before!");
if (handler == null)
return;
if (stickinessHandlers.contains(handler))
return;
stickinessHandlers.add(handler);
}
private void sortMovementHandlersAndDisableRegistration() {
if (!canRegisterMovementHandlers)
return;
canRegisterMovementHandlers = false;
Collections.sort(movementHandlers, new SorterPriority.SorterPriorityInstance());
}
private void sortStickyProvidersAndDisableRegistration() {
if (!canRegisterStickyProviders)
return;
canRegisterStickyProviders = false;
Collections.sort(stickyProviders, new SorterPriority.SorterPriorityInstance());
}
private void sortStickinessHandlersAndDisableRegistration() {
if (!canRegisterStickinessHandlers)
return;
canRegisterStickinessHandlers = false;
Collections.sort(stickinessHandlers, new SorterPriority.SorterPriorityInstance());
}
@Override
public List<IMovable> findMovables(World world, int x, int y, int z) {
if (world == null)
return null;
sortMovementHandlersAndDisableRegistration();
List<IMovable> l = new ArrayList<IMovable>();
Block b = world.getBlock(x, y, z);
if (b instanceof IMovable)
l.add((IMovable) b);
TileEntity te = world.getTileEntity(x, y, z);
if (te != null && te instanceof IMovable)
l.add((IMovable) te);
for (IMovementHandler h : movementHandlers)
if (h.canHandle(world, x, y, z))
l.add(h);
return l;
}
@Override
public List<ISticky> findStickies(World world, int x, int y, int z) {
if (world == null)
return null;
sortStickyProvidersAndDisableRegistration();
sortStickinessHandlersAndDisableRegistration();
List<ISticky> l = new ArrayList<ISticky>();
Block b = world.getBlock(x, y, z);
if (b instanceof ISticky)
l.add((ISticky) b);
TileEntity te = world.getTileEntity(x, y, z);
if (te != null && te instanceof ISticky)
l.add((ISticky) te);
for (IStickyProvider p : stickyProviders) {
ISticky sticky = p.getStickyAt(world, x, y, z);
if (sticky != null)
l.add(sticky);
}
return l;
}
@Override
public List<IFrame> findFrames(World world, int x, int y, int z) {
if (world == null)
return null;
List<IFrame> l = new ArrayList<IFrame>();
Block b = world.getBlock(x, y, z);
if (b instanceof IFrame)
l.add((IFrame) b);
TileEntity te = world.getTileEntity(x, y, z);
if (te != null && te instanceof IFrame)
l.add((IFrame) te);
TileMultipart tmp = TileMultipart.getTile(world, new BlockCoord(x, y, z));
if (tmp != null)
for (TMultiPart p : tmp.jPartList())
if (p instanceof IFrame)
l.add((IFrame) p);// FIXME actual multipart handling
return l;
}
public List<IStickinessHandler> getStickinessHandlers() {
return stickinessHandlers;
}
public NBTTagCompound writeInfo(IMovingBlock block) {
NBTTagCompound tag = new NBTTagCompound();
if (block == null)
return tag;
NBTTagList l = new NBTTagList();
for (IMovementDataProvider p : dataProviders) {
if (p.canHandle(block)) {
NBTTagCompound t = new NBTTagCompound();
p.writeMovementInfo(block, t);
t.setString("___id", p.getID());
l.appendTag(t);
}
}
tag.setTag("info", l);
return tag;
}
public void readInfo(IMovingBlock block, NBTTagCompound tag) {
if (!tag.hasKey("info"))
return;
NBTTagList l = tag.getTagList("info", new NBTTagCompound().getId());
for (int i = 0; i < l.tagCount(); i++) {
NBTTagCompound t = l.getCompoundTagAt(i);
for (IMovementDataProvider p : dataProviders) {
if (p.getID().equals(t.getString("___id"))) {
p.readMovementInfo(block, t);
break;
}
}
}
}
}