package ncrashed.warp.cores.actions;

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

import ncrashed.warp.ChunkCopier;
import ncrashed.warp.api.ICoreAction;
import ncrashed.warp.api.IWarpCore;
import ncrashed.warp.api.volume.IVolume;
import net.minecraft.util.AxisAlignedBB;

public class LongWarp implements ICoreAction 
{
	private class TempWarp
	{
		int dx, dy, dz;
		AxisAlignedBB box;
		
		public TempWarp(AxisAlignedBB box, int dx, int dy, int dz)
		{
			this.box = box;
			this.dx = dx;
			this.dy = dy;
			this.dz = dz;
		}
	}
	
	private boolean isDistNotEmpty = false;
	
	@Override
	public int getRequiredEnergy(IWarpCore core, int multCounter, int north,
			int south, int west, int east, int up, int down) 
	{
		AxisAlignedBB box = core.getCoreVolume().getBoundingBox(core.getCoreX(), core.getCoreY(), core.getCoreZ());
		
		int dx = 4*(east-west)*multCounter;
		int dy = 255 - (int)box.maxY;
		int dz = 4*(south-north)*multCounter;
		double dist = Math.sqrt(dx*dx + dy*dy + dz*dz);
		int summ = (int)(box.maxX-box.minX + box.maxY-box.minY + box.maxZ-box.minZ);
		
		return (int)((summ * 2600) + (summ*6*dist) * (summ / (IVolume.MAX_VOLUME_SIZE*3)) * 0.7);
	}

	@Override
	public boolean performAction(IWarpCore core, int multCounter, int north,
			int south, int west, int east, int up, int down) 
	{
		AxisAlignedBB boundingBox = core.getCoreVolume().getBoundingBox(core.getCoreX(), core.getCoreY(), core.getCoreZ());
		Iterator<AxisAlignedBB> iter = core.getCoreVolume().getBoxes(core.getCoreX(), core.getCoreY(), core.getCoreZ()).iterator();
		List<TempWarp> warpBoxes = new ArrayList<TempWarp>();
		isDistNotEmpty = false;
		
		while(iter.hasNext())
		{
			AxisAlignedBB box = iter.next();
			
			int dx = 4*(east-west)*multCounter;
			int dy = 255 - (int)box.maxY;
			int dz = 4*(south-north)*multCounter;
			
			if(!ChunkCopier.isDistEmpty(core.getCoreWorld(), (int)box.minX+dx, (int)box.minY+dy, (int)box.minZ+dz, (int)box.maxX+dx, (int)box.maxY+dy, (int)box.maxZ+dz))
			{
				isDistNotEmpty = true;
				return false;
			}
			warpBoxes.add(new TempWarp(box, dx, dy, dz));
		}
		
		boolean result = true;
		ListIterator<TempWarp> tempIter = warpBoxes.listIterator();
		while(tempIter.hasNext())
		{
			TempWarp temp = tempIter.next();
			result = result && ChunkCopier.copyVolume(core.getCoreWorld(), (int)temp.box.minX, (int)temp.box.minY, (int)temp.box.minZ, 
					(int)temp.box.maxX, (int)temp.box.maxY, (int)temp.box.maxZ, temp.dx, temp.dy, temp.dz);
		}
		return result;
	}

	@Override
	public int getLowMultCounter() 
	{
		return 8;
	}

	@Override
	public int getHighMultCounter() 
	{
		return 15;
	}

	@Override
	public int getSuccessCooldown(IWarpCore core, int multCounter, int north,
			int south, int west, int east, int up, int down)
	{
		AxisAlignedBB box = core.getCoreVolume().getBoundingBox(0, 0, 0);
		int summ = (int)(box.maxX-box.minX + box.maxY-box.minY + box.maxZ-box.minZ);
	
		return (summ/1250) + 120;
	}

	@Override
	public int getFailCooldown(IWarpCore core, int multCounter, int north,
			int south, int west, int east, int up, int down) 
	{
		return 5;
	}

	@Override
	public int getMinimumCooldown(IWarpCore core, int multCounter, int north,
			int south, int west, int east, int up, int down) 
	{
		return 5;
	}

	@Override
	public boolean printActionResult() 
	{
		return true;
	}

	@Override
	public int getErrorBit() 
	{
		if(isDistNotEmpty) return 1;
		return 2;
	}

}
