package stucuk.mcicraft.api.v4;

/*
 * MCI Craft API
 * Version: 3.0
 * Authors: Stuart "Stucuk" Carey
 * 
 * Copyright (c) <2014> <Stuart Carey>
 * 
 * This file is provided 'as-is', without any express or implied
 * warranty. In no event will the authors be held liable for any damages
 * arising from the use of this file.
 *
 * Permission is granted to anyone to use this file for any purpose,
 * including commercial applications, and to alter it and redistribute it
 * freely, subject to the following restrictions:
 *
 * 1. The origin of this file must not be misrepresented; you must not
 * claim that you wrote the original file.
 *
 * 2. Altered versions must be plainly marked as such, and must not be
 * misrepresented as being the original file.
 *
 * 3. This notice may not be removed or altered.
 * 
 */

//NOTE: Each version will use a different path(If the file has changed) so that 
//      there is no collisions when two mods include different versions of the
//      same file. This however will mean that mods which use different versions
//      of interfaces will not be able to interface with each other (Though
//      its better than crashing).


import stucuk.mcicraft.api.interfaces.IMCIRedstone64In;
import stucuk.mcicraft.api.interfaces.IMCIRedstone64Out;
import stucuk.mcicraft.core.MCICraft;
import net.minecraft.block.Block;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.Direction;
import net.minecraft.util.EnumFacing;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import net.minecraftforge.common.util.ForgeDirection;

public class MCIAPI {	
	// maximum hops in a single tick
	public static int maxHops = 16;
	public static String version = "4.0";
	
	private static MCIAPI API = new MCIAPI(); //Just used to display version(s)
	
	public MCIAPI() {
		super();
	    System.out.println("MCIAPI v"+version);
	}
	
	// Allows us to work out if we need to check for a redstone signal 
	// or if we can rely on a R64 signal to be sent(So we don't need to do anything if true).
	public static boolean isR64Out(Block block)
	{
		return (block instanceof IMCIRedstone64Out);
	}
	
	public static boolean isR64In(Block block)
	{
		return (block instanceof IMCIRedstone64In);
	}
	
	public static boolean isR64In(World world, int x, int y, int z, int dir)
	{
		return isR64In(world.getBlock(x+Direction.offsetX[dir],y,z+Direction.offsetZ[dir]));
	}
	
	public static boolean isR64Out(World world, int x, int y, int z, int dir)
	{
		return isR64Out(world.getBlock(x+Direction.offsetX[dir],y,z+Direction.offsetZ[dir]));
	}
	
	//V2
	public static boolean isR64In(IBlockAccess world, int x, int y, int z, int dir)
	{
		return isR64In(world.getBlock(x+Direction.offsetX[dir],y,z+Direction.offsetZ[dir]));
	}
	
	//V2
	public static boolean isR64Out(IBlockAccess world, int x, int y, int z, int dir)
	{
		return isR64Out(world.getBlock(x+Direction.offsetX[dir],y,z+Direction.offsetZ[dir]));
	}
	
	public static ForgeDirection DirToForgeDir(int dir)
	{
		//"SOUTH", "WEST", "NORTH", "EAST"
		switch (dir) {
		case 0:
			return ForgeDirection.SOUTH;
		case 1:
			return ForgeDirection.WEST;
		case 2:
			return ForgeDirection.NORTH;
		case 3:
			return ForgeDirection.EAST;
		default:
			return ForgeDirection.UNKNOWN;
		}
	}
	
	public static ForgeDirection FacingToForgeDir(EnumFacing dir)
	{
		//D, U, N, S, E, W
		
		switch (dir.ordinal()) {
		case 0:
			return ForgeDirection.DOWN;
		case 1:
			return ForgeDirection.UP;
		case 2:
			return ForgeDirection.NORTH;
		case 3:
			return ForgeDirection.SOUTH;
		case 4:
			return ForgeDirection.WEST;
		case 5:
			return ForgeDirection.EAST;
		default:
			return ForgeDirection.UNKNOWN;
		}
	}
	
	public static ForgeDirection FacingToForgeDir2(EnumFacing dir)
	{
		//D, U, N, S, E, W
		
		switch (dir.ordinal()) {
		case 0:
			return ForgeDirection.DOWN;
		case 1:
			return ForgeDirection.UP;
		case 2:
			return ForgeDirection.NORTH;
		case 3:
			return ForgeDirection.SOUTH;
		case 4:
			return ForgeDirection.EAST;
		case 5:
			return ForgeDirection.WEST;
		default:
			return ForgeDirection.UNKNOWN;
		}
	}
	
	// Safe way to send a R64 Signal. If this fails then we can try a normal 
	// redstone block notification (If we support redstone signals).
	public static boolean sendR64toBlock(World world, int x, int y, int z, long value, ForgeDirection dir, byte hop)
	{
		Block block = world.getBlock(x,y,z);
		if (block == null || !(block instanceof IMCIRedstone64In))
			return false;
		
		//MCICraft.Print("R64: " + value);
		
		hop++;
		((IMCIRedstone64In) block).recieveR64Value(world,x,y,z,value,dir,hop);
		return true;
	}
	
	public static boolean sendR64toBlock(World world, int x, int y, int z, long value, ForgeDirection dir)
	{
		return sendR64toBlock(world,x,y,z,value,dir,(byte) 0);
	}
	
	// Calls the above. Allows input as a tile entity + direction.
	public static boolean sendR64toBlock(World world, TileEntity tile, ForgeDirection dir, long value, byte hop)
	{
		int x,y,z;
		x = tile.xCoord+dir.offsetX;
		y = tile.yCoord+dir.offsetY;
		z = tile.zCoord+dir.offsetZ;
		return sendR64toBlock(world,x,y,z,value,dir,hop);
	}
	
	public static boolean sendR64toBlock(World world, TileEntity tile, ForgeDirection dir, long value)
	{		
		return sendR64toBlock(world,tile,dir,value,(byte) 0);
	}
}
