package ncrashed.warp.cores;

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

import ncrashed.warp.ModHelper;
import ncrashed.warp.WarpMod;
import ncrashed.warp.ModHelper.BlueInfo;
import ncrashed.warp.api.BigStructure;
import ncrashed.warp.api.IBigStructure;
import ncrashed.warp.api.IBigStructure.BlockInfo;
import ncrashed.warp.api.IBigStructure.IConditionHandler;
import ncrashed.warp.api.ICoreStructure;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;
import net.minecraftforge.common.ForgeDirection;

public class LegacyCoreStructure extends BigStructure implements ICoreStructure
{
	public static final int MAX_COUNTER_DIST = 10;
	
	public LegacyCoreStructure()
	{
		super();
		HashMap<Integer, List<BlockInfo> > blockMapping = new HashMap<Integer, List<BlockInfo> >();
		
		ArrayList<BlockInfo> temp = new ArrayList<BlockInfo>();
		temp.add(new BlockInfo(WarpMod.mConfig.mRPMachine, WarpMod.mConfig.mRPMagTubeMeta));
		blockMapping.put(Integer.valueOf(1), temp);
		
		temp = new ArrayList<BlockInfo>();
		temp.add(new BlockInfo(WarpMod.mConfig.mICMFSUID, WarpMod.mConfig.mICMFSUMeta));
		blockMapping.put(Integer.valueOf(2), temp);
		
		temp = new ArrayList<BlockInfo>();
		temp.add(new BlockInfo(WarpMod.mConfig.mLegacyCoreBlockID, -1));
		blockMapping.put(Integer.valueOf(3), temp);
		
		temp = new ArrayList<BlockInfo>();
		temp.add(new BlockInfo(WarpMod.mConfig.mRPLighting, WarpMod.mConfig.mRPBlueLampMeta));
		blockMapping.put(Integer.valueOf(4), temp);
		
		addBlockMapping(blockMapping);
		
		addCondition(1, new IConditionHandler(){

			@Override
			public boolean isValidBlock(World world, int x, int y, int z,
					int recipeId) {
				ModHelper.BlueInfo info = ModHelper.rp2MeasureBlue(world, x, y, z, 0);
				if(info == null) return false;
				
				return info.voltage >= 70;
			}
			
		});
		
		addLayer(new int[][]{
			new int[]{1, 1, 1},
			new int[]{1, 2, 1},
			new int[]{1, 1, 1}
		});
		addLayer(new int[][]{
				new int[]{1, 1, 1},
				new int[]{1, 3, 1},
				new int[]{1, 1, 1}
		});
		addLayer(new int[][]{
				new int[]{1, 1, 1},
				new int[]{1, 4, 1},
				new int[]{1, 1, 1}
		});
	}
	
	public int getCoreX()
	{
		return 1;
	}
	
	public int getCoreY()
	{
		return 1;
	}
	
	public int getCoreZ()
	{
		return 1;
	}
	
	public int getStorageX()
	{
		return 1;
	}
	
	public int getStorageY()
	{
		return 0;
	}
	
	public int getStorageZ()
	{
		return 1;
	}
	
	public int getLampX()
	{
		return 1;
	}
	
	public int getLampY()
	{
		return 2;
	}
	
	public int getLampZ()
	{
		return 1;
	}

	@Override
	public boolean checkCounters(World world, int x, int y, int z) 
	{
		//mult
		boolean flag = false;
		for(int i = 0; i < MAX_COUNTER_DIST; ++i)
		{
			if(world.getBlockId(x-i, y+1, z) == WarpMod.mConfig.mRPControl && world.getBlockMetadata(x-i, y+1, z) == WarpMod.mConfig.mRPCounterMeta)
			{
				flag = true; 
				break;
			}
			if(world.getBlockId(x+i, y+1, z) == WarpMod.mConfig.mRPControl && world.getBlockMetadata(x+i, y+1, z) == WarpMod.mConfig.mRPCounterMeta)
			{
				flag = true; 
				break;
			}
			if(world.getBlockId(x, y+1, z-i) == WarpMod.mConfig.mRPControl && world.getBlockMetadata(x, y+1, z-i) == WarpMod.mConfig.mRPCounterMeta)
			{
				flag = true; 
				break;
			}
			if(world.getBlockId(x, y+1, z+i) == WarpMod.mConfig.mRPControl && world.getBlockMetadata(x, y+1, z+i) == WarpMod.mConfig.mRPCounterMeta)
			{
				flag = true; 
				break;
			}
		}
		if(!flag) return false;
		
		return true;
	}

	@Override
	public TileEntity getSidedCounter(World world, int x, int y, int z, ForgeDirection side) 
	{
		if(side.equals(ForgeDirection.NORTH))
		{
			for(int i = 0; i < MAX_COUNTER_DIST; ++i)
			{
				if(world.getBlockId(x, y, z-i) == WarpMod.mConfig.mRPControl && world.getBlockMetadata(x, y, z-i) == WarpMod.mConfig.mRPCounterMeta)
				{
					return world.getBlockTileEntity(x, y, z-i);
				}
			}			
		} else if (side.equals(ForgeDirection.SOUTH))
		{
			for(int i = 0; i < MAX_COUNTER_DIST; ++i)
			{
				if(world.getBlockId(x, y, z+i) == WarpMod.mConfig.mRPControl && world.getBlockMetadata(x, y, z+i) == WarpMod.mConfig.mRPCounterMeta)
				{
					return world.getBlockTileEntity(x, y, z+i);
				}
			}		
		} else if (side.equals(ForgeDirection.WEST))
		{
			for(int i = 0; i < MAX_COUNTER_DIST; ++i)
			{
				if(world.getBlockId(x-i, y, z) == WarpMod.mConfig.mRPControl && world.getBlockMetadata(x-i, y, z) == WarpMod.mConfig.mRPCounterMeta)
				{
					return world.getBlockTileEntity(x-i, y, z);
				}
			}		
		} else if (side.equals(ForgeDirection.EAST))
		{
			for(int i = 0; i < MAX_COUNTER_DIST; ++i)
			{
				if(world.getBlockId(x+i, y, z) == WarpMod.mConfig.mRPControl && world.getBlockMetadata(x+i, y, z) == WarpMod.mConfig.mRPCounterMeta)
				{
					return world.getBlockTileEntity(x+i, y, z);
				}
			}		
		} else if (side.equals(ForgeDirection.UP))
		{
			for(int i = 0; i < MAX_COUNTER_DIST; ++i)
			{
				if(world.getBlockId(x, y+i, z) == WarpMod.mConfig.mRPControl && world.getBlockMetadata(x, y+i, z) == WarpMod.mConfig.mRPCounterMeta)
				{
					return world.getBlockTileEntity(x, y+i, z);
				}
			}		
		} else if (side.equals(ForgeDirection.DOWN))
		{
			for(int i = 0; i < MAX_COUNTER_DIST; ++i)
			{
				if(world.getBlockId(x, y-i, z) == WarpMod.mConfig.mRPControl && world.getBlockMetadata(x, y-i, z) == WarpMod.mConfig.mRPCounterMeta)
				{
					return world.getBlockTileEntity(x, y-i, z);
				}
			}		
		}
		
		return null;
	}

	@Override
	public TileEntity getMultCounter(World world, int x, int y, int z) 
	{
		for(int i = 0; i < MAX_COUNTER_DIST; ++i)
		{
			if(world.getBlockId(x-i, y+1, z) == WarpMod.mConfig.mRPControl && world.getBlockMetadata(x-i, y+1, z) == WarpMod.mConfig.mRPCounterMeta)
			{
				return world.getBlockTileEntity(x-i, y+1, z);
			}
			if(world.getBlockId(x+i, y+1, z) == WarpMod.mConfig.mRPControl && world.getBlockMetadata(x+i, y+1, z) == WarpMod.mConfig.mRPCounterMeta)
			{
				return world.getBlockTileEntity(x+i, y+1, z);
			}
			if(world.getBlockId(x, y+1, z-i) == WarpMod.mConfig.mRPControl && world.getBlockMetadata(x, y+1, z-i) == WarpMod.mConfig.mRPCounterMeta)
			{
				return world.getBlockTileEntity(x, y+1, z-i);
			}
			if(world.getBlockId(x, y+1, z+i) == WarpMod.mConfig.mRPControl && world.getBlockMetadata(x, y+1, z+i) == WarpMod.mConfig.mRPCounterMeta)
			{
				return world.getBlockTileEntity(x, y+1, z+i);
			}
		}
		return null;
	}
	
	@Override
	public boolean checkExpanders(World world, int x, int y, int z)
	{
		return checkExpandersInner(world, x, y, z) != 0;
	}
	
	private int checkExpandersInner(World world, int x, int y, int z)
	{
		if(world.getBlockId(x-1, y-2, z) == WarpMod.mConfig.mRPFlatBase && world.getBlockMetadata(x-1, y-2, z) == WarpMod.mConfig.mRPIOExpanderMeta)
		{
			if(world.getBlockId(x+1, y-2, z) == WarpMod.mConfig.mRPFlatBase && world.getBlockMetadata(x+1, y-2, z) == WarpMod.mConfig.mRPIOExpanderMeta)
			{
				return 1;
			}
		} else if(world.getBlockId(x, y-2, z-1) == WarpMod.mConfig.mRPFlatBase && world.getBlockMetadata(x, y-2, z-1) == WarpMod.mConfig.mRPIOExpanderMeta)
		{
			if(world.getBlockId(x, y-2, z+1) == WarpMod.mConfig.mRPFlatBase && world.getBlockMetadata(x, y-2, z+1) == WarpMod.mConfig.mRPIOExpanderMeta)
			{
				return 2;
			}
		}
		
		return 0;
	}
	
	@Override
	public TileEntity getExpander(World world, int x, int y, int z, int id)
	{
		int check = checkExpandersInner(world, x, y, z);
		int dval = id == 0 ? -1 : 1;
		
		if(check == 0) return null;
		else if(check == 1)
		{
			return world.getBlockTileEntity(x+dval, y-2, z);
		} else
		{
			return world.getBlockTileEntity(x, y-2, z+dval);
		}
	}
	
	@Override
	public void setExpander(World world, int x, int y, int z, int id, int val)
	{
		ModHelper.rp2SetIOExpander(getExpander(world, x, y, z, id), val);
	}
	
	@Override
	public void setExpander(World world, int x, int y, int z, int id, int bitPos, boolean bitVal)
	{
		TileEntity expander = getExpander(world, x, y, z, id);
		if(bitVal)
		{
			ModHelper.rp2SetIOExpander(expander, ModHelper.rp2GetIOExpander(expander) | (1 << bitPos));
		} else
		{
			ModHelper.rp2SetIOExpander(expander, ModHelper.rp2GetIOExpander(expander) & (~(1 << bitPos)) );
		}
	}

	@Override
	public void zeroAllExpanders(World world, int x, int y, int z) 
	{
		setExpander(world, x, y, z, 0, 0);
		setExpander(world, x, y, z, 1, 0);
	}
}