package com.elmakers.mine.bukkit.api.magic;

import java.util.Collection;
import java.util.Set;
import java.util.logging.Logger;

import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.Plugin;

import com.elmakers.mine.bukkit.api.block.BlockList;
import com.elmakers.mine.bukkit.api.block.Schematic;
import com.elmakers.mine.bukkit.api.block.UndoList;
import com.elmakers.mine.bukkit.api.spell.SpellCategory;
import com.elmakers.mine.bukkit.api.spell.SpellTemplate;
import com.elmakers.mine.bukkit.api.wand.LostWand;
import com.elmakers.mine.bukkit.api.wand.Wand;

public interface MageController {
	
	/**
	 * Retrieve the Logger for this API instance.
	 * 
	 * @return The logger being used by the API provider (usually MagicPlugin).
	 */
	public Logger getLogger();
	
	/**
	 * Check to see if the given block is part of an Automata.
	 * 
	 * This currently only works if you specify the redstone block associated
	 * with the automata, though this will hopefully be improved in the future.
	 * 
	 * @param block The block to check.
	 * @return True if this is an Automata's power source.
	 */
	public boolean isAutomata(Block block);

	/**
	 * Return a list of all known LostWand records.
	 * 
	 * @return A list of all known LostWand data.
	 */
	public Collection<LostWand> getLostWands();
	
	/**
	 * Create a new Wand from a template.
	 * 
	 * Once created, a Wand is a unique item. It "remembers" which template
	 * it was created from, but this is currently not used for anything.
	 * 
	 * @param wandKey The template key, or blank for a default wand.
	 * @return A new Wand instance, with a useable ItemStack.
	 */
	public Wand createWand(String wandKey);
	
	public SpellCategory getCategory(String key);
	public Collection<SpellCategory> getCategories();
	public Collection<SpellTemplate> getSpellTemplates();
	public SpellTemplate getSpellTemplate(String key);
	
	public void registerAutomata(Block block, String name, String message);
	public boolean unregisterAutomata(Block block);
	
	public void updateBlock(Block block);
	public void updateBlock(String worldName, int x, int y, int z);
	public void updateVolume(String worldName, int minx, int miny, int minz, int maxx, int maxy, int maxz);
	public void update(BlockList blockList);
	
	public boolean canCreateWorlds();
	public int getMaxUndoPersistSize();
	
	public Schematic loadSchematic(String name);
	public Set<Material> getMaterialSet(String name);
	
	public int getMaxY();

	public void sendToMages(String message, Location location);
	public Collection<Mage> getMages();
	
	public Plugin getPlugin();
	public String getMessagePrefix();
	
	public Set<Material> getDestructibleMaterials();
	public Set<Material> getBuildingMaterials();
	public Set<Material> getRestrictedMaterials();
	
	public Collection<String> getMaterialSets();
	
	public Collection<String> getPlayerNames();
	
	public int getMessageThrottle();
	public Mage getMage(CommandSender sender);
	
	public Collection<String> getBrushKeys();
	
	public boolean commitAll();
	
	public void disablePhysics(int interval);
	
	public boolean hasPermission(CommandSender sender, String pNode, boolean defaultValue);
	public boolean isPVPAllowed(Location location);
	
	public boolean sendMail(CommandSender sender, String fromPlayer, String toPlayer, String message);
	
	public Location getWarp(String warpName);
	
	public void giveItemToPlayer(Player player, ItemStack itemStack);
	
	public UndoList undoAny(Block target);
	public void forgetMage(Mage mage);
	
	/**
	 * Check to see if the Elementals plugin is present an enabled.
	 * 
	 * If so, Magic will work as a passthrough API.
	 * 
	 * @return
	 */
	public boolean elementalsEnabled();
	
	/**
	 * Create an Elemental of a specific type at a certain location.
	 * 
	 * @param location The location at which to create the elemental.
	 * @param templateName The name of the elemental's template description
	 * @param creator The creator of the elemental, may be null.
	 * @return False on failure, such as if there are already too many elementals in the world.
	 */
	public boolean createElemental(Location location, String templateName, CommandSender creator);
	
	/**
	 * Check to see if the given Entity is an Elemental, or part of an Elemental.
	 * 
	 * @param entity The entity to check
	 * @return true if this Entity is an Elemental, or part of one.
	 */
	public boolean isElemental(Entity entity);
	
	/**
	 * Damage the Elemental represented by the given Entity.
	 * 
	 * @param entity The entity to use to determine which Elemental to damage.
	 * @param damage The amount of damage to apply.
	 * @param fireTicks The duration of fire, if any, to apply.
	 * @param attacker The attacker, initiator of damage. May be a command block or console, or null.
	 * @return False if the entity is not a living Elemental.
	 */
	public boolean damageElemental(Entity entity, double damage, int fireTicks, CommandSender attacker);
	
	/**
	 * Change the scale of an Elemental, making it bigger or smaller.
	 * 
	 * Elementals will limit their own size within sane limits. (0.1 - 5.0 for instance).
	 * 
	 * @param entity The entity representing the Elemental to scale
	 * @param scale The new scale
	 * @return False if the entity is not an Elemental, or other failure
	 */
	public boolean setElementalScale(Entity entity, double scale);
	
	/**
	 * Get the current scale of an Elemental.
	 * 
	 * @param entity The entity representing the Elemental to interrogate
	 * @return The scale of the elemental, or 0 on error.
	 */
	public double getElementalScale(Entity entity);
}

@@ -4582,16 +4582,246 @@
 entity);
+%0A%0A    /**%0A     * Check to see if the given Entity is an NPC of any kind.%0A     *%0A     * This currently integrates with Citizens and Shopkeepers, and%0A     * relies on Entity metadata.%0A     */%0A    public boolean isNPC(Entity entity);
 %0A%09%0A%09/**%0A

Add isNPC method