package org.ultramine.mods.hawkeye.util;

import net.minecraft.block.Block;
import net.minecraft.event.HoverEvent;
import net.minecraft.init.Blocks;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ChatComponentText;
import net.minecraft.util.ChatComponentTranslation;
import net.minecraft.util.ChatStyle;
import net.minecraft.util.EnumChatFormatting;
import net.minecraft.util.IChatComponent;
import net.minecraft.world.World;
import net.minecraftforge.common.util.BlockSnapshot;
import net.minecraftforge.event.world.BlockEvent;

/**
 * Contains utilities for manipulating blocks without losing data
 * 
 * @author oliverw92
 */
public class HawkBlockUtil
{
	/**
	 * Gets the block in 'string form'. e.g. blockid:datavalue
	 * 
	 * @param block
	 *            BlockState of the block you wish to convert
	 * @return string representing the block
	 */
	public static String getBlockString(BlockSnapshot block)
	{
		if(block.meta != 0)
			return Block.getIdFromBlock(block.getReplacedBlock()) + ":" + block.meta;
		return Integer.toString(Block.getIdFromBlock(block.getReplacedBlock()));
	}

	public static String getBlockString(BlockEvent.PlaceEvent event)
	{
		if(event.blockMetadata != 0)
			return event.block + ":" + event.blockMetadata;
		return Integer.toString(Block.getIdFromBlock(event.block));
	}

	/**
	 * Same as getBlockString() except for ItemStack
	 * 
	 * @param stack
	 *            ItemStack you wish to convert
	 * @return string representing the item
	 */
	public static String getItemString(ItemStack stack)
	{
		if(stack.getItemDamage() != 0 && stack.getItemDamage() != 0)
			return Item.getIdFromItem(stack.getItem()) + ":" + stack.getItemDamage();
		return Integer.toString(Item.getIdFromItem(stack.getItem()));
	}

	/**
	 * Converts an item string into an ItemStack
	 * 
	 * @param itemData
	 *            item string representing the material and data
	 * @param amount
	 * @return an ItemStack
	 */
	public static ItemStack itemStringToStack(String itemData, int amount)
	{
		int splitInd = itemData.indexOf(':');
		String idS = splitInd == -1 ? itemData : itemData.substring(0, splitInd);
		Item item = Item.getItemById(Integer.parseInt(idS));
		ItemStack stack = item == null ? null : new ItemStack(item, amount, splitInd != -1 ? Integer.parseInt(itemData.substring(splitInd+1, itemData.length())) : 0);
		return stack;
	}

	/**
	 * Returns the name of the block, with its data if applicable
	 * 
	 * @param blockData
	 * @return
	 */
	public static IChatComponent getBlockComponent(String blockData)
	{
		ChatComponentText comp = new ChatComponentText(blockData);
		int id = getIdFromString(blockData);
		Block block = Block.getBlockById(id);
		if(block != null && block != Blocks.air)
		{
			ChatComponentText popup = new ChatComponentText("ID: ");
			popup.getChatStyle().setColor(EnumChatFormatting.GOLD);
			popup.appendSibling(new ChatComponentText(Block.blockRegistry.getNameForObject(block)).setChatStyle(new ChatStyle().setColor(EnumChatFormatting.YELLOW)));
			popup.appendText("\n").appendText("Internal ID: ");
			popup.appendSibling(new ChatComponentText(Integer.toString(id)).setChatStyle(new ChatStyle().setColor(EnumChatFormatting.YELLOW)));
			popup.appendText("\n").appendText("Localized name: ");
			popup.appendSibling(new ChatComponentTranslation(block.getUnlocalizedName()+".name").setChatStyle(new ChatStyle().setColor(EnumChatFormatting.GREEN)));
			popup.appendText("\n").appendText("Unlocalized name: ");
			popup.appendSibling(new ChatComponentText(block.getUnlocalizedName()).setChatStyle(new ChatStyle().setColor(EnumChatFormatting.YELLOW)));
			popup.appendText("\n").appendText("Class: ");
			popup.appendSibling(new ChatComponentText(block.getClass().getName()).setChatStyle(new ChatStyle().setColor(EnumChatFormatting.YELLOW)));

			comp.getChatStyle().setChatHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, popup));
			comp.getChatStyle().setUnderlined(true);
		}
		return comp;
	}

	/**
	 * Sets the block type and data to the inputted block string
	 * 
	 * @param block
	 *            Block to be changed
	 * @param blockData
	 *            string form of a block
	 */
	public static void setBlockString(World world, int x, int y, int z, String blockData)
	{
		int splitInd = blockData.indexOf(':');
		String idS = splitInd == -1 ? blockData : blockData.substring(0, splitInd);
		int id = Integer.parseInt(idS);
		Block block = Block.getBlockById(id);
		if(block == null)
			return;
		int metadata = 0;
		if(splitInd != -1)
			metadata = Integer.parseInt(blockData.substring(splitInd+1, blockData.length()));

		world.setBlockSilently(x, y, z, block, metadata, 2);
		world.setBlockMetadataWithNotify(x, y, z, metadata, 3);
	}

	/**
	 * Returns ID section of a block string
	 * 
	 * @param string
	 * @return int ID
	 */
	public static int getIdFromString(String blockData)
	{
		int splitInd = blockData.indexOf(':');
		String idS = splitInd == -1 ? blockData : blockData.substring(0, splitInd);
		if(!HawkUtil.isInteger(idS))
			return 0;
		return Integer.parseInt(idS);
	}

	/**
	 * Returns data section of a block string
	 * 
	 * @param string
	 * @return int data
	 */
	public static byte getDataFromString(String blockData)
	{
		int splitInd = blockData.indexOf(':');
		if(splitInd == -1)
			return 0;
		return (byte) Integer.parseInt(blockData.substring(splitInd+1, blockData.length()));
	}
}
