001package com.fs.starfarer.api.impl.campaign.rulecmd;
002
003import java.util.ArrayList;
004import java.util.Collections;
005import java.util.Comparator;
006import java.util.List;
007import java.util.Map;
008
009import com.fs.starfarer.api.Global;
010import com.fs.starfarer.api.campaign.InteractionDialogAPI;
011import com.fs.starfarer.api.campaign.rules.ExpressionAPI;
012import com.fs.starfarer.api.campaign.rules.MemoryAPI;
013import com.fs.starfarer.api.campaign.rules.Option;
014import com.fs.starfarer.api.campaign.rules.RuleAPI;
015import com.fs.starfarer.api.campaign.rules.RulesAPI;
016import com.fs.starfarer.api.impl.campaign.DevMenuOptions;
017import com.fs.starfarer.api.util.Misc;
018import com.fs.starfarer.api.util.Misc.Token;
019import com.fs.starfarer.api.util.Misc.VarAndMemory;
020
021public class FireAll extends BaseCommandPlugin {
022
023        public static class OptionAdder {
024                private Option option;
025                private ExpressionAPI expression;
026                public OptionAdder(ExpressionAPI expression) {
027                        this.expression = expression;
028                }
029                public OptionAdder(Option option) {
030                        this.option = option;
031                }
032                
033                public int getOrder(Map<String, MemoryAPI> memoryMap) {
034                        if (option != null) {
035                                return (int) option.order;
036                        }
037                        if (expression != null) {
038                                return expression.getOptionOrder(memoryMap);
039                        }
040                        return 0;
041                }
042                
043                public void add(String ruleId, InteractionDialogAPI dialog, List<Token> params, Map<String, MemoryAPI> memoryMap) {
044                        if (option != null) {
045                                //String text = Misc.replaceTokensFromMemory(option.text, memoryMap);
046                                String text = Global.getSector().getRules().performTokenReplacement(ruleId, option.text, dialog.getInteractionTarget(), memoryMap);
047                                
048                                dialog.getOptionPanel().addOption(text, option.id, null);
049                        } else if (expression != null) {
050                                expression.execute(ruleId, dialog, memoryMap);
051                        }
052                }
053        }
054        
055        public static boolean fire(String ruleId, InteractionDialogAPI dialog, Map<String, MemoryAPI> memoryMap, String params) {
056                return new FireAll().execute(ruleId, dialog, Misc.tokenize(params), memoryMap);
057        }
058
059        private InteractionDialogAPI dialog;
060        private Map<String, MemoryAPI> memoryMap;
061
062        public boolean execute(String ruleId, InteractionDialogAPI dialog, List<Token> params, final Map<String, MemoryAPI> memoryMap) {
063                
064                this.dialog = dialog;
065                this.memoryMap = memoryMap;
066                String trigger = params.get(0).string;
067                if (params.get(0).isVariable()) {
068                        VarAndMemory var = params.get(0).getVarNameAndMemory(memoryMap);
069                        trigger = var.memory.getString(var.name);
070                }
071                
072                
073                MemoryAPI mem = getEntityMemory(memoryMap);
074                mem.set("$fireAllTrigger", trigger, 0);
075                boolean intercepted = FireBest.fire(null, dialog, memoryMap, "FireAllIntercept");
076                if (intercepted) {
077                        return true; // we did *something*, so: return true
078                }
079                
080                
081                RulesAPI rules = Global.getSector().getRules();
082                List<RuleAPI> matches = rules.getAllMatching(ruleId, trigger, dialog, memoryMap);
083                if (matches.isEmpty()) return false;
084                
085                List<OptionAdder> options = new ArrayList<OptionAdder>();
086                for (RuleAPI rule : matches) {
087                        //options.addAll(rule.getOptions());
088                        for (Option option : rule.getOptions()) {
089                                if (option.id.startsWith("(dev)") && !Global.getSettings().isDevMode()) continue;
090                                options.add(new OptionAdder(option));
091                        }
092                        
093                        // this actually doesn't work I think? since rule gets applied regardless
094                        // and so the expression gets executed twice
095                        for (ExpressionAPI e : rule.getScriptCopy()) {
096                                if (e.doesCommandAddOptions()) {
097                                        options.add(new OptionAdder(e));
098                                }
099                        }
100                }
101                
102                if (!options.isEmpty()) {
103                        Collections.sort(options, new Comparator<OptionAdder>() {
104                                public int compare(OptionAdder o1, OptionAdder o2) {
105                                        float diff = o1.getOrder(memoryMap) - o2.getOrder(memoryMap);
106                                        if (diff < 0) return -1;
107                                        if (diff > 0) return 1;
108                                        return 0;
109                                }
110                        });
111                        
112                        dialog.getOptionPanel().clearOptions();
113                        for (OptionAdder option : options) {
114                                //dialog.getOptionPanel().addOption(option.text, option.id, null);
115                                option.add(ruleId, dialog, params, memoryMap);
116                        }
117                        if (Global.getSettings().isDevMode()) {
118                                DevMenuOptions.addOptions(dialog);
119                        }
120                }
121                
122                for (RuleAPI rule : matches) {
123                        applyRule(rule);
124                }
125                
126                return true;
127        }
128        
129        private void applyRule(RuleAPI rule) {
130                addText(rule.getId(), rule.pickText());
131                rule.runScript(dialog, memoryMap);
132        }
133        
134        private void addText(String ruleId, String text) {
135                if (text == null || text.isEmpty()) return;
136                
137                text = Global.getSector().getRules().performTokenReplacement(ruleId, text, dialog.getInteractionTarget(), memoryMap);
138//              Map<String, String> tokens = Global.getSector().getRules().getTokenReplacements(ruleId, dialog.getInteractionTarget(), memoryMap);
139//              for (String token : tokens.keySet()) {
140//                      String value = tokens.get(token);
141//                      text = text.replaceAll("(?s)\\" + token, value);
142//              }
143//              
144//              text = Misc.replaceTokensFromMemory(text, memoryMap);
145                
146                dialog.getTextPanel().addParagraph(text);
147        }
148        
149        
150        
151        
152        
153
154}