package com.elmakers.mine.bukkit.spell.builtin;

import com.elmakers.mine.bukkit.utility.CompatibilityUtils;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Ageable;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.PigZombie;
import org.bukkit.entity.Player;
import org.bukkit.entity.Skeleton;
import org.bukkit.entity.Skeleton.SkeletonType;
import org.bukkit.entity.Slime;
import org.bukkit.entity.Zombie;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;

import com.elmakers.mine.bukkit.api.spell.SpellResult;
import com.elmakers.mine.bukkit.spell.BlockSpell;
import com.elmakers.mine.bukkit.utility.InventoryUtils;
import com.elmakers.mine.bukkit.utility.Target;
import org.bukkit.inventory.meta.SkullMeta;

public class ShrinkSpell extends BlockSpell
{
	private int             DEFAULT_PLAYER_DAMAGE = 1;
	private int             DEFAULT_ENTITY_DAMAGE = 100;
	
	@SuppressWarnings("deprecation")
	@Override
	public SpellResult onCast(ConfigurationSection parameters) 
	{
		String giveName = parameters.getString("name");
		if (giveName != null) {
			dropHead(getLocation(), giveName, null, (byte)3);
			return SpellResult.CAST;
		}
		
		Target target = getTarget();

		if (target.hasEntity()) {
			Entity targetEntity = target.getEntity();
			if (controller.isElemental(targetEntity))
			{
				double elementalSize = controller.getElementalScale(targetEntity);
				if (elementalSize < 0.1) {
					int elementalDamage = parameters.getInt("elemental_damage", DEFAULT_ENTITY_DAMAGE);
					controller.damageElemental(targetEntity, elementalDamage, 0, mage.getCommandSender());
				} else {
					elementalSize /= 2;
					controller.setElementalScale(targetEntity, elementalSize);
				}
				
				return SpellResult.CAST;
			}
			
			if (!(targetEntity instanceof LivingEntity)) return SpellResult.NO_TARGET;
			
			// Register for undo in advance to catch entity death.
			registerForUndo();
			
			int damage =  parameters.getInt("entity_damage", DEFAULT_ENTITY_DAMAGE);

			LivingEntity li = (LivingEntity)targetEntity;
			boolean alreadyDead = li.isDead() || li.getHealth() <= 0;
			String ownerName = null;
			String itemName = null;
			byte data = 3;
			
			if (li instanceof Player)
			{
				damage = parameters.getInt("player_damage", DEFAULT_PLAYER_DAMAGE);
				ownerName = ((Player)li).getName();
			}
			else
			{
                itemName = li.getType().getName() + " Head";
				switch (li.getType()) {
					case CREEPER:
						data = 4;
						ownerName = null;
					break;
					case ZOMBIE:
						data = 2;
						ownerName = null;
					break;
					case SKELETON:
						Skeleton skeleton = (Skeleton)li;
						data = (byte)(skeleton.getSkeletonType() == SkeletonType.NORMAL ? 0 : 1);
						ownerName = null;
					break;
					default:
						ownerName = getMobSkin(li.getType());
				}
			}

            if (itemName == null && ownerName != null) {
                itemName = ownerName + "'s Head";
            }
			
			Location targetLocation = targetEntity.getLocation();
			if (li instanceof Player) {
                CompatibilityUtils.magicDamage(li, damage, mage.getEntity());
				if (ownerName != null && li.isDead() && !alreadyDead) {
					dropHead(targetEntity.getLocation(), ownerName, itemName, data);
				}
			}
			else if (li.getType() == EntityType.GIANT) {
				registerModified(li);
				li.remove();
				Entity zombie = targetLocation.getWorld().spawnEntity(targetLocation, EntityType.ZOMBIE);
				registerForUndo(zombie);
			}
			else if (li instanceof Ageable && ((Ageable)li).isAdult() && !(li instanceof Player)) {
				registerModified(li);
				((Ageable)li).setBaby();
			} else  if (li instanceof Zombie && !((Zombie)li).isBaby()) {
				registerModified(li);
				((Zombie)li).setBaby(true);
			} else  if (li instanceof PigZombie && !((PigZombie)li).isBaby()) {
				registerModified(li);
				((PigZombie)li).setBaby(true);
			} else  if (li instanceof Slime && ((Slime)li).getSize() > 1) {
				registerModified(li);
				Slime slime = (Slime)li;
				slime.setSize(slime.getSize() - 1);
			} else {
                CompatibilityUtils.magicDamage(li, damage, mage.getEntity());
				if ((ownerName != null || data != 3) && (li.isDead() || li.getHealth() == 0) && !alreadyDead) {
					dropHead(targetEntity.getLocation(), ownerName, itemName, data);
				}
			}
		} else {
			Block targetBlock = target.getBlock();
			if (targetBlock == null) {
				return SpellResult.NO_TARGET;
			}
			String blockSkin = getBlockSkin(targetBlock.getType());
			if (blockSkin == null) return SpellResult.NO_TARGET;
			
			if (!hasBuildPermission(targetBlock)) 
			{
				return SpellResult.INSUFFICIENT_PERMISSION;
			}
			if (mage.isIndestructible(targetBlock)) 
			{
				return SpellResult.NO_TARGET;
			}
			
			registerForUndo(targetBlock);		
			registerForUndo();

			dropHead(targetBlock.getLocation(), blockSkin, targetBlock.getType().name(), (byte)3);
			targetBlock.setType(Material.AIR);
		}
		
		return SpellResult.CAST;
	}
	
	@SuppressWarnings("deprecation")
	protected void dropHead(Location location, String ownerName, String itemName, byte data) {
        ItemStack shrunkenHead = new ItemStack(Material.SKULL_ITEM, 1, (short)0, (byte)data);
        ItemMeta meta = shrunkenHead.getItemMeta();
        if (itemName != null) {
            meta.setDisplayName(itemName);
        }
        if (meta instanceof SkullMeta) {
            SkullMeta skullData = (SkullMeta)meta;
            skullData.setOwner(ownerName);
        }
        shrunkenHead.setItemMeta(meta);
        if (ownerName != null) {
            shrunkenHead = InventoryUtils.getCopy(shrunkenHead);
            ItemMeta itemMeta = shrunkenHead.getItemMeta();

            shrunkenHead.setItemMeta(itemMeta);
            InventoryUtils.setMeta(shrunkenHead, "SkullOwner", ownerName);
        }
        location.getWorld().dropItemNaturally(location, shrunkenHead);
	}
}

@@ -5563,20 +5563,41 @@
 kullMeta
+ && ownerName != null
 ) %7B%0A
-
         
@@ -5684,32 +5684,32 @@
 ame);%0A        %7D%0A
+
         shrunken
@@ -5736,300 +5736,8 @@
 a);%0A
-        if (ownerName != null) %7B%0A            shrunkenHead = InventoryUtils.getCopy(shrunkenHead);%0A            ItemMeta itemMeta = shrunkenHead.getItemMeta();%0A%0A            shrunkenHead.setItemMeta(itemMeta);%0A            InventoryUtils.setMeta(shrunkenHead, %22SkullOwner%22, ownerName);%0A        %7D%0A
     

Clean up ShrinkSpell