package com.elmakers.mine.bukkit.spell;

import com.elmakers.mine.bukkit.action.ActionHandler;
import com.elmakers.mine.bukkit.api.spell.SpellResult;
import org.bukkit.configuration.ConfigurationSection;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

public class ActionSpell extends BrushSpell
{
    private Map<String, ActionHandler> actions = new HashMap<String, ActionHandler>();
    private boolean undoable = false;
    private boolean requiresBuildPermission = false;

    @Override
    public SpellResult onCast(ConfigurationSection parameters)
    {
        if (undoable)
        {
            registerForUndo();
        }
        ActionHandler downHandler = actions.get("alternate_down");
        if (downHandler != null && isLookingDown())
        {
            return SpellResult.ALTERNATE_DOWN.max(downHandler.perform(this, parameters));
        }
        ActionHandler upHandler = actions.get("alternate_up");
        if (upHandler != null && isLookingUp())
        {
            return SpellResult.ALTERNATE_UP.max(upHandler.perform(this, parameters));
        }
        ActionHandler sneakHandler = actions.get("alternate_sneak");
        if (sneakHandler != null && mage.isSneaking())
        {
            return SpellResult.ALTERNATE_SNEAK.max(sneakHandler.perform(this, parameters));
        }

        ActionHandler castHandler = actions.get("cast");
        if (castHandler != null)
        {
            return castHandler.perform(this, parameters);
        }

        // Allow for effect-only spells
        return SpellResult.CAST;
    }

    @Override
    public void load(ConfigurationSection data)
    {
        for (ActionHandler handler : actions.values())
        {
            handler.loadData(getMage(), data);
        }
    }

    @Override
    public void save(ConfigurationSection data)
    {
        for (ActionHandler handler : actions.values())
        {
            handler.saveData(getMage(), data);
        }
    }

    @Override
    protected void loadTemplate(ConfigurationSection template)
    {
        usesBrush = false;
        undoable = false;
        requiresBuildPermission = false;
        castOnNoTarget = true;
        if (template.contains("actions"))
        {
            ConfigurationSection parameters = template.getConfigurationSection("parameters");
            ConfigurationSection actionsNode = template.getConfigurationSection("actions");
            Collection<String> actionKeys = actionsNode.getKeys(false);
            for (String actionKey : actionKeys)
            {
                ActionHandler handler = new ActionHandler();
                handler.load(actionsNode, actionKey);
                handler.initialize(parameters);
                usesBrush = usesBrush || handler.usesBrush();
                undoable = undoable || handler.isUndoable();
                requiresBuildPermission = requiresBuildPermission || handler.requiresBuildPermission();
                actions.put(actionKey, handler);
            }
        }
        undoable = template.getBoolean("undoable", undoable);
        super.loadTemplate(template);
    }

    @Override
    public boolean isUndoable()
    {
        return undoable;
    }

    @Override
    public void getParameters(Collection<String> parameters) {
        super.getParameters(parameters);
        for (ActionHandler handler : actions.values()) {
            handler.getParameterNames(parameters);
        }
    }

    @Override
    public void getParameterOptions(Collection<String> examples, String parameterKey) {
        super.getParameterOptions(examples, parameterKey);
        for (ActionHandler handler : actions.values()) {
            handler.getParameterOptions(examples, parameterKey);
        }
    }

    @Override
    public String getMessage(String messageKey, String def) {
        String message = super.getMessage(messageKey, def);
        for (ActionHandler handler : actions.values()) {
            message = handler.transformMessage(message);
        }
        return message;
    }

    @Override
    public boolean requiresBuildPermission() {
        return requiresBuildPermission;
    }
}

@@ -669,63 +669,295 @@
     
-ActionHandler downHandler = actions.get(%22alternate_down
+SpellResult result = SpellResult.CAST;%0A        ActionHandler handler = actions.get(%22cast%22);%0A        ActionHandler downHandler = actions.get(%22alternate_down%22);%0A        ActionHandler upHandler = actions.get(%22alternate_up%22);%0A        ActionHandler sneakHandler = actions.get(%22alternate_sneak
 %22);%0A
@@ -1024,36 +1024,38 @@
 %7B%0A            re
-turn
+sult =
  SpellResult.ALT
@@ -1069,51 +1069,8 @@
 DOWN
-.max(downHandler.perform(this, parameters))
 ;%0A  
@@ -1078,73 +1078,45 @@
     
- %7D%0A
      
-   ActionH
+h
 andler 
-up
+= down
 Handler
- = actions.get(%22alternate_up%22);
+;%0A        %7D
 %0A   
@@ -1116,24 +1116,29 @@
   %7D%0A        
+else 
 if (upHandle
@@ -1181,36 +1181,38 @@
 %7B%0A            re
-turn
+sult =
  SpellResult.ALT
@@ -1224,49 +1224,8 @@
 E_UP
-.max(upHandler.perform(this, parameters))
 ;%0A  
@@ -1233,79 +1233,43 @@
     
- %7D%0A
      
-   ActionH
+h
 andler 
-sneak
+= up
 Handler
- = actions.get(%22alternate_sneak%22);
+;%0A        %7D
 %0A   
@@ -1269,24 +1269,29 @@
   %7D%0A        
+else 
 if (sneakHan
@@ -1341,36 +1341,38 @@
 %7B%0A            re
-turn
+sult =
  SpellResult.ALT
@@ -1387,19 +1387,136 @@
 NEAK
-.max(sneakH
+;%0A            handler = sneakHandler;%0A        %7D%0A%0A        if (handler != null)%0A        %7B%0A            SpellResult actionResult = h
 andl
@@ -1543,17 +1543,16 @@
 ameters)
-)
 ;%0A      
@@ -1557,68 +1557,180 @@
     
-%7D%0A%0A
     
-    ActionHandler castHandler = actions.get(%22cast%22);%0A
+result = result.max(actionResult);%0A            if (!result.isSuccess())%0A            %7B%0A                handler = actions.get(actionResult.name().toLowerCase());%0A        
     
@@ -1737,21 +1737,17 @@
     if (
-castH
+h
 andler !
@@ -1746,32 +1746,40 @@
 andler != null)%0A
+        
         %7B%0A      
@@ -1788,20 +1788,17 @@
     
-return castH
+        h
 andl
@@ -1808,34 +1808,78 @@
 perform(
-this, parameters);
+getCurrentCast(), parameters);%0A                %7D%0A            %7D
 %0A       

Allow for failure action handlers (e.g. actions on fizzle)