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

import com.elmakers.mine.bukkit.api.action.CastContext;
import com.elmakers.mine.bukkit.api.block.MaterialAndData;
import com.elmakers.mine.bukkit.api.block.MaterialBrush;
import com.elmakers.mine.bukkit.api.magic.MageController;
import org.bukkit.Color;
import org.bukkit.Location;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Entity;
import org.bukkit.util.Vector;

/**
 * Represents a Spell that may be cast by a Mage.
 * 
 * Each Spell is based on a SpellTemplate, which are defined
 * by the spells configuration files.
 * 
 * Every spell uses a specific Class that must extend from
 * com.elmakers.mine.bukkit.plugins.magic.spell.Spell.
 * 
 * To create a new custom spell from scratch, you must also
 * implement the MageSpell interface.
 */
public interface Spell extends SpellTemplate {
    MageController getController();
    boolean cast();
    boolean cast(String[] parameters);
    boolean cast(String[] parameters, Location defaultLocation);
    boolean cast(ConfigurationSection parameters, Location defaultLocation);
    boolean cast(ConfigurationSection parameters);
    Location getLocation();
    Entity getEntity();
    Location getEyeLocation();
    void target();
    Location getTargetLocation();
    Entity getTargetEntity();
    Vector getDirection();
    boolean canTarget(Entity entity);
    boolean isActive();
    boolean hasBrushOverride();
    boolean canCast(Location location);
    void clearCooldown();
    void setRemainingCooldown(long ms);
    long getRemainingCooldown();
    CastingCost getRequiredCost();
    void messageTargets(String messageKey);
    void playEffects(String effectName);
    CastContext getCurrentCast();
    void playEffects(String effectName, CastContext context);
    void playEffects(String effectName, CastContext context, float scale);
    boolean requiresBuildPermission();
    boolean requiresBreakPermission();
    boolean isPvpRestricted();
    boolean isDisguiseRestricted();
    void sendMessage(String message);
    void castMessage(String message);
    MaterialAndData getEffectMaterial();
    String getEffectParticle();
    Color getEffectColor();
    MaterialBrush getBrush();
    boolean isCancellable();
    ConfigurationSection getWorkingParameters();
    void finish(CastContext context);
    double cancelOnDamage();
    boolean cancelOnCastOther();
    String getMessage(String messageKey);
    boolean hasHandlerParameters(String handlerKey);
    ConfigurationSection getHandlerParameters(String handlerKey);
    long getProgressLevel();
    boolean cancelOnNoPermission();


    /**
     * Signal that this spell was cancelled. Will send cancel messages
     * and play cancel FX.
     *
     * This will not actually cancel any pending spell casts (batches) of this spell,
     * for that you will need Mage.cancelPending
     *
     * @return true (for legacy reasons)
     */
    boolean cancel();

    /**
     * Cancel a selection in-progress for a two-click selection spell (like Architect magic)
     *
     * Will call cancel() if selection was cancelled.
     *
     * @return true if the spell was in the middle of selection and was cancelled.
     */
    boolean cancelSelection();
}

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

import com.elmakers.mine.bukkit.api.action.CastContext;
import com.elmakers.mine.bukkit.api.block.MaterialAndData;
import com.elmakers.mine.bukkit.api.block.MaterialBrush;
import com.elmakers.mine.bukkit.api.magic.MageController;
import org.bukkit.Color;
import org.bukkit.Location;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Entity;
import org.bukkit.util.Vector;

/**
 * Represents a Spell that may be cast by a Mage.
 * 
 * Each Spell is based on a SpellTemplate, which are defined
 * by the spells configuration files.
 * 
 * Every spell uses a specific Class that must extend from
 * com.elmakers.mine.bukkit.plugins.magic.spell.Spell.
 * 
 * To create a new custom spell from scratch, you must also
 * implement the MageSpell interface.
 */
public interface Spell extends SpellTemplate {
    MageController getController();
    boolean cast();
    boolean cast(String[] parameters);
    boolean cast(String[] parameters, Location defaultLocation);
    boolean cast(ConfigurationSection parameters, Location defaultLocation);
    boolean cast(ConfigurationSection parameters);
    Location getLocation();
    Entity getEntity();
    Location getEyeLocation();
    void target();
    Location getTargetLocation();
    Entity getTargetEntity();
    Vector getDirection();
    boolean canTarget(Entity entity);
    boolean isActive();
    boolean hasBrushOverride();
    boolean canCast(Location location);
    void clearCooldown();
    void setRemainingCooldown(long ms);
    long getRemainingCooldown();
    CastingCost getRequiredCost();
    void messageTargets(String messageKey);
    void playEffects(String effectName);
    CastContext getCurrentCast();
    void playEffects(String effectName, CastContext context);
    void playEffects(String effectName, CastContext context, float scale);
    boolean requiresBuildPermission();
    boolean requiresBreakPermission();
    boolean isPvpRestricted();
    boolean isDisguiseRestricted();
    void sendMessage(String message);
    void castMessage(String message);
    MaterialAndData getEffectMaterial();
    String getEffectParticle();
    Color getEffectColor();
    MaterialBrush getBrush();
    boolean brushIsErase();
    boolean isCancellable();
    ConfigurationSection getWorkingParameters();
    void finish(CastContext context);
    double cancelOnDamage();
    boolean cancelOnCastOther();
    String getMessage(String messageKey);
    boolean hasHandlerParameters(String handlerKey);
    ConfigurationSection getHandlerParameters(String handlerKey);
    long getProgressLevel();
    boolean cancelOnNoPermission();


    /**
     * Signal that this spell was cancelled. Will send cancel messages
     * and play cancel FX.
     *
     * This will not actually cancel any pending spell casts (batches) of this spell,
     * for that you will need Mage.cancelPending
     *
     * @return true (for legacy reasons)
     */
    boolean cancel();

    /**
     * Cancel a selection in-progress for a two-click selection spell (like Architect magic)
     *
     * Will call cancel() if selection was cancelled.
     *
     * @return true if the spell was in the middle of selection and was cancelled.
     */
    boolean cancelSelection();
}

Add ability to check if a spell is using an erase brush, important for distinction between break and build permissions.