From d00ed620b7adb1b3c7ffcc3becb3bf427ceda269 Mon Sep 17 00:00:00 2001
From: fullwall <fullwall25@gmail.com>
Date: Sat, 29 Sep 2012 23:54:05 +0800
Subject: [PATCH] Make a start on templates

---
 src/main/java/net/citizensnpcs/Citizens.java  |  2 +
 .../command/command/HelpCommands.java         | 18 +++++
 .../command/command/TemplateCommands.java     | 54 +++++++++++++
 .../java/net/citizensnpcs/npc/Template.java   | 80 +++++++++++++++++++
 4 files changed, 154 insertions(+)
 create mode 100644 src/main/java/net/citizensnpcs/command/command/TemplateCommands.java
 create mode 100644 src/main/java/net/citizensnpcs/npc/Template.java

diff --git a/src/main/java/net/citizensnpcs/Citizens.java b/src/main/java/net/citizensnpcs/Citizens.java
index 6c23c0c33..18cef037e 100644
--- a/src/main/java/net/citizensnpcs/Citizens.java
+++ b/src/main/java/net/citizensnpcs/Citizens.java
@@ -27,6 +27,7 @@ import net.citizensnpcs.command.command.EditorCommands;
 import net.citizensnpcs.command.command.HelpCommands;
 import net.citizensnpcs.command.command.NPCCommands;
 import net.citizensnpcs.command.command.ScriptCommands;
+import net.citizensnpcs.command.command.TemplateCommands;
 import net.citizensnpcs.command.command.TraitCommands;
 import net.citizensnpcs.command.exception.CommandException;
 import net.citizensnpcs.command.exception.CommandUsageException;
@@ -254,6 +255,7 @@ public class Citizens extends JavaPlugin implements CitizensPlugin {
         commands.register(HelpCommands.class);
         commands.register(NPCCommands.class);
         commands.register(ScriptCommands.class);
+        commands.register(TemplateCommands.class);
         commands.register(TraitCommands.class);
     }
 
diff --git a/src/main/java/net/citizensnpcs/command/command/HelpCommands.java b/src/main/java/net/citizensnpcs/command/command/HelpCommands.java
index 5b4718301..e3d91c239 100644
--- a/src/main/java/net/citizensnpcs/command/command/HelpCommands.java
+++ b/src/main/java/net/citizensnpcs/command/command/HelpCommands.java
@@ -102,4 +102,22 @@ public class HelpCommands {
         if (!paginator.sendPage(sender, page))
             throw new CommandException("The page '" + page + "' does not exist.");
     }
+
+    @Command(
+            aliases = { "template", "tpl" },
+            usage = "help (page)",
+            desc = "Template help menu",
+            modifiers = { "help" },
+            min = 1,
+            max = 2,
+            permission = "templates.help")
+    @Requirements
+    public void templatesHelp(CommandContext args, CommandSender sender, NPC npc) throws CommandException {
+        int page = args.argsLength() == 2 ? args.getInteger(1) : 1;
+        Paginator paginator = new Paginator().header("Templates Help");
+        for (String line : getLines(sender, npc, "script"))
+            paginator.addLine(line);
+        if (!paginator.sendPage(sender, page))
+            throw new CommandException("The page '" + page + "' does not exist.");
+    }
 }
\ No newline at end of file
diff --git a/src/main/java/net/citizensnpcs/command/command/TemplateCommands.java b/src/main/java/net/citizensnpcs/command/command/TemplateCommands.java
new file mode 100644
index 000000000..926fcb174
--- /dev/null
+++ b/src/main/java/net/citizensnpcs/command/command/TemplateCommands.java
@@ -0,0 +1,54 @@
+package net.citizensnpcs.command.command;
+
+import net.citizensnpcs.Citizens;
+import net.citizensnpcs.api.npc.NPC;
+import net.citizensnpcs.command.Command;
+import net.citizensnpcs.command.CommandContext;
+import net.citizensnpcs.command.Requirements;
+import net.citizensnpcs.command.exception.CommandException;
+import net.citizensnpcs.npc.Template;
+import net.citizensnpcs.npc.Template.TemplateBuilder;
+import net.citizensnpcs.util.Messaging;
+
+import org.bukkit.ChatColor;
+import org.bukkit.command.CommandSender;
+
+@Requirements(selected = true, ownership = true)
+public class TemplateCommands {
+    public TemplateCommands(Citizens plugin) {
+    }
+
+    @Command(
+            aliases = { "template", "tpl" },
+            usage = "apply (name)",
+            desc = "Applies a template to the selected NPC",
+            modifiers = { "apply" },
+            min = 2,
+            max = 2,
+            permission = "templates.apply")
+    public void apply(CommandContext args, CommandSender sender, NPC npc) throws CommandException {
+        Template template = Template.byName(args.getString(1));
+        if (template == null)
+            throw new CommandException("Template not found.");
+        template.apply(npc);
+        Messaging.send(sender, ChatColor.GREEN + "Template applied.");
+    }
+
+    @Command(
+            aliases = { "template", "tpl" },
+            usage = "create [name] (-o)",
+            desc = "Creates a template from the selected NPC",
+            modifiers = { "create" },
+            min = 2,
+            max = 2,
+            flags = "o",
+            permission = "templates.create")
+    public void create(CommandContext args, CommandSender sender, NPC npc) throws CommandException {
+        String name = args.getString(1);
+        if (Template.byName(name) != null)
+            throw new CommandException("A template by that name already exists.");
+
+        TemplateBuilder.create(name).from(npc).override(args.hasFlag('o')).buildAndSave();
+        Messaging.send(sender, ChatColor.GREEN + "Template created.");
+    }
+}
diff --git a/src/main/java/net/citizensnpcs/npc/Template.java b/src/main/java/net/citizensnpcs/npc/Template.java
new file mode 100644
index 000000000..1f1b90946
--- /dev/null
+++ b/src/main/java/net/citizensnpcs/npc/Template.java
@@ -0,0 +1,80 @@
+package net.citizensnpcs.npc;
+
+import java.util.Map;
+
+import net.citizensnpcs.api.CitizensAPI;
+import net.citizensnpcs.api.npc.NPC;
+import net.citizensnpcs.api.util.DataKey;
+import net.citizensnpcs.api.util.MemoryDataKey;
+import net.citizensnpcs.api.util.YamlStorage;
+import net.citizensnpcs.api.util.YamlStorage.YamlKey;
+
+import com.google.common.collect.Maps;
+
+public class Template {
+    private final String name;
+    private final boolean override;
+    private final Map<String, Object> replacements;
+
+    private Template(String name, Map<String, Object> replacements, boolean override) {
+        this.replacements = replacements;
+        this.override = override;
+        this.name = name;
+    }
+
+    public void apply(NPC npc) {
+    }
+
+    public static class TemplateBuilder {
+        private final String name;
+        private boolean override;
+        private final Map<String, Object> replacements = Maps.newHashMap();
+
+        private TemplateBuilder(String name) {
+            this.name = name;
+        }
+
+        public Template buildAndSave() {
+            save();
+            return new Template(name, replacements, override);
+        }
+
+        public TemplateBuilder from(NPC npc) {
+            replacements.clear();
+            MemoryDataKey key = new MemoryDataKey();
+            ((CitizensNPC) npc).save(key);
+            replacements.putAll(key.getRawTree());
+            return this;
+        }
+
+        public TemplateBuilder override(boolean override) {
+            this.override = override;
+            return this;
+        }
+
+        public void save() {
+            DataKey root = templates.getKey(name);
+            root.setBoolean("override", override);
+            root.setRaw("replacements", replacements);
+            templates.save();
+        }
+
+        public static TemplateBuilder create(String name) {
+            return new TemplateBuilder(name);
+        }
+    }
+
+    private static YamlStorage templates = new YamlStorage(CitizensAPI.getDataFolder(), "templates.yml");
+    public static Template byName(String name) {
+        if (!templates.getKey("").keyExists(name))
+            return null;
+        YamlKey key = templates.getKey(name);
+        boolean override = key.getBoolean("override", false);
+        Map<String, Object> replacements = key.getRelative("replacements").getValuesDeep();
+        return new Template(name, replacements, override);
+    }
+
+    static {
+        templates.load();
+    }
+}