package ncrashed.warp;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

import ncrashed.warp.api.IWarpCore;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.world.World;
import net.minecraftforge.event.ForgeSubscribe;
import net.minecraftforge.event.world.WorldEvent;

public class CoreRegistry 
{	
	protected  HashMap<World, HashMap<Integer, IWarpCore> > coreMap;
	protected  int coreIdCounter;
	
	public CoreRegistry()
	{
		coreMap = new HashMap<World, HashMap<Integer, IWarpCore> >();
		coreIdCounter = 0;
	}
	
	public void registerNewCore(IWarpCore core)
	{
		core.setCoreID(coreIdCounter++);

		if(!coreMap.containsKey(core.getCoreWorld()))
		{
			coreMap.put(core.getCoreWorld(), new HashMap<Integer, IWarpCore>());
		}
		coreMap.get(core.getCoreWorld()).put(core.getCoreID(), core);
		System.out.println("Created new core with id " + core.getCoreID());
	}
	
	public void registerOldCore(IWarpCore core)
	{
		if(core.getCoreID() >= coreIdCounter) coreIdCounter = core.getCoreID()+1;
		if(coreMap.containsKey(core.getCoreID()))
		{
			core.setCoreID(coreIdCounter++);
		}
		if(!coreMap.containsKey(core.getCoreWorld()))
		{
			coreMap.put(core.getCoreWorld(), new HashMap<Integer, IWarpCore>());
		}
		
		coreMap.get(core.getCoreWorld()).put(core.getCoreID(), core);
		
		System.out.println("Loaded core wit id " + core.getCoreID());
	}
	
	public List<IWarpCore> getCoresInBox(World world, AxisAlignedBB box, boolean onlyIncomplite)
	{
		ArrayList<IWarpCore> list = new ArrayList<IWarpCore>();
		Iterator<IWarpCore> iter = coreMap.get(world).values().iterator();
		while(iter.hasNext())
		{
			IWarpCore core = iter.next();
			if(core != null && isVecInsideBox(box, core.getCoreX(), core.getCoreY(), core.getCoreZ()))
			{
				if(onlyIncomplite && core.isConstructed()) continue;
				list.add(core);
			}
		}
		
		return list;
	}
	
	public IWarpCore getClosestCore(World world, int x, int y, int z, double maxdist, boolean onlyIncomplite)
	{
		IWarpCore bestInfo = null;
		double bestDist = maxdist;
		if(!coreMap.containsKey(world)) return null;
		
		Iterator<IWarpCore> iter = coreMap.get(world).values().iterator();
		while(iter.hasNext())
		{
			IWarpCore core = iter.next();
			double dist = getDistToEntity(core, x, y, z);
			if(core != null && dist < bestDist)
			{
				if(onlyIncomplite && core.isConstructed()) continue;
				
				bestInfo = core;
				bestDist = dist;
			}
		}
		
		return bestInfo;
	}
	
	public IWarpCore getCoreByID(World world, int id)
	{
		if(!coreMap.containsKey(world)) return null;
		if(!coreMap.get(world).containsKey(id)) return null;
		return coreMap.get(world).get(id);
	}
	
	private boolean isVecInsideBox(AxisAlignedBB box, int x, int y, int z)
	{
		return x >= box.minX && x <= box.maxX && y >= box.minY && y <= box.maxY && z >= box.minZ && z <= box.maxZ;
	}
	
	private double getDistToEntity(IWarpCore entity, int x, int y, int z)
	{
		return (entity.getCoreX()-x)*(entity.getCoreX()-x) + (entity.getCoreY()-y)*(entity.getCoreY()-y) + (entity.getCoreZ()-z)*(entity.getCoreZ()-z);
	}
}
