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.IntVec3;
import ncrashed.warp.ModHelper;
import ncrashed.warp.api.ICoreAction;
import ncrashed.warp.api.ICoreStructure;
import ncrashed.warp.api.IWarpBeacon;
import ncrashed.warp.api.IWarpCore;
import ncrashed.warp.cores.SimpleWarpBeacon;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.world.World;
import net.minecraftforge.common.ForgeDirection;

public class BeaconWarp extends BaseBeaconAction implements ICoreAction 
{
	private boolean isBeaconNonUniq = false;
	private boolean isDistNotEmpty = false;
	private boolean isNoBeacon = false;
	
	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;
		}
	}
	
	@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(0, 0, 0);
		int summ = (int)(box.maxX-box.minX + box.maxY-box.minY + box.maxZ-box.minZ);
		
		return (int)(Math.pow(summ, 1.5)*1100);
	}

	@Override
	public boolean performAction(IWarpCore core, int multCounter, int north,
			int south, int west, int east, int up, int down) 
	{
		isBeaconNonUniq = false;
		isDistNotEmpty = false;
		isNoBeacon = false;
		
		IntVec3 beaconPos = null;
		IWarpBeacon beacon = new SimpleWarpBeacon();
		List<IntVec3> beaconList = getBeaconList(core.getCoreWorld(), beacon);
		
		ListIterator<IntVec3> biter = beaconList.listIterator();
		while(biter.hasNext())
		{
			IntVec3 pos = biter.next();
			if(beacon.getCounterValue(core.getCoreWorld(), pos.x, pos.y, pos.z, ForgeDirection.NORTH) == north &&
					beacon.getCounterValue(core.getCoreWorld(), pos.x, pos.y, pos.z, ForgeDirection.SOUTH) == south &&
					beacon.getCounterValue(core.getCoreWorld(), pos.x, pos.y, pos.z, ForgeDirection.WEST) == west &&
					beacon.getCounterValue(core.getCoreWorld(), pos.x, pos.y, pos.z, ForgeDirection.EAST) == east)
			{
				if(beaconPos != null)
				{
					System.out.println("Beacon not uniq!");
					isBeaconNonUniq = true;
					return false;
				}
				beaconPos = pos;
			}
		}
		
		if(beaconPos ==  null)
		{
			System.out.println("Beacon not found");
			isNoBeacon = true;
			return false;
		}
		
		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>();
		
		while(iter.hasNext())
		{
			AxisAlignedBB box = iter.next();
			
			int dx = beaconPos.x - (int)(box.minX + (box.maxX - box.minX)/2);
			int dy = 255 - (int)box.maxY;
			int dz = beaconPos.z - (int)(box.minZ + (box.maxZ - box.minZ)/2);
			
			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))
			{
				System.out.println("Dist is not empty");
				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 17;
	}

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

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

	@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 0;
	}

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

	@Override
	public int getErrorBit() 
	{
		if(isDistNotEmpty) return 1;
		if(isNoBeacon) return 2;
		if(isBeaconNonUniq) return 3;
		return 4;
	}

}
