001package com.fs.starfarer.api.impl.campaign.intel.punitive;
002
003import java.awt.Color;
004import java.util.Map;
005
006import org.lwjgl.input.Keyboard;
007
008import com.fs.starfarer.api.Global;
009import com.fs.starfarer.api.campaign.CampaignFleetAPI;
010import com.fs.starfarer.api.campaign.FactionAPI;
011import com.fs.starfarer.api.campaign.InteractionDialogAPI;
012import com.fs.starfarer.api.campaign.InteractionDialogPlugin;
013import com.fs.starfarer.api.campaign.OptionPanelAPI;
014import com.fs.starfarer.api.campaign.RepLevel;
015import com.fs.starfarer.api.campaign.TextPanelAPI;
016import com.fs.starfarer.api.campaign.VisualPanelAPI;
017import com.fs.starfarer.api.campaign.ReputationActionResponsePlugin.ReputationAdjustmentResult;
018import com.fs.starfarer.api.campaign.rules.MemoryAPI;
019import com.fs.starfarer.api.combat.EngagementResultAPI;
020import com.fs.starfarer.api.impl.campaign.CoreReputationPlugin;
021import com.fs.starfarer.api.impl.campaign.CoreReputationPlugin.CustomRepImpact;
022import com.fs.starfarer.api.impl.campaign.CoreReputationPlugin.RepActionEnvelope;
023import com.fs.starfarer.api.impl.campaign.CoreReputationPlugin.RepActions;
024import com.fs.starfarer.api.impl.campaign.ids.Factions;
025import com.fs.starfarer.api.impl.campaign.ids.Sounds;
026import com.fs.starfarer.api.impl.campaign.intel.punitive.PunitiveExpeditionIntel.PunExOutcome;
027import com.fs.starfarer.api.impl.campaign.intel.punitive.PunitiveExpeditionManager.PunExData;
028import com.fs.starfarer.api.impl.campaign.rulecmd.AddRemoveCommodity;
029import com.fs.starfarer.api.impl.campaign.rulecmd.SetStoryOption;
030import com.fs.starfarer.api.ui.IntelUIAPI;
031import com.fs.starfarer.api.ui.TooltipMakerAPI;
032import com.fs.starfarer.api.util.Misc;
033
034public class PEAvertInteractionDialogPluginImpl implements InteractionDialogPlugin {
035
036        private static enum OptionId {
037                INIT,
038                USE_CONNECTIONS,
039                BRIBE,
040                LEAVE,
041                
042                CONFIRM,
043                CANCEL,
044        }
045        
046        //public static float BRIBE_BASE = 0;
047        public static int BRIBE_MULT = 10000;
048        public static int BRIBE_MAX = 100000;
049        
050        public static RepLevel MIN_REP = RepLevel.WELCOMING;
051        public static float REP_COST  = 0.2f;
052        
053        protected InteractionDialogAPI dialog;
054        protected TextPanelAPI textPanel;
055        protected OptionPanelAPI options;
056        protected VisualPanelAPI visual;
057        
058        protected CampaignFleetAPI playerFleet;
059
060        protected PunitiveExpeditionIntel intel;
061        protected IntelUIAPI ui;
062        
063        public PEAvertInteractionDialogPluginImpl(PunitiveExpeditionIntel intel, IntelUIAPI ui) {
064                this.intel = intel;
065                this.ui = ui;
066        }
067
068        public void init(InteractionDialogAPI dialog) {
069                this.dialog = dialog;
070                textPanel = dialog.getTextPanel();
071                options = dialog.getOptionPanel();
072                visual = dialog.getVisualPanel();
073
074                playerFleet = Global.getSector().getPlayerFleet();
075                
076                visual.setVisualFade(0.25f, 0.25f);
077                //visual.showImagePortion("illustrations", "quartermaster", 640, 400, 0, 0, 480, 300);
078                visual.showPlanetInfo(intel.getTarget().getPrimaryEntity());
079        
080                dialog.setOptionOnEscape("Leave", OptionId.LEAVE);
081                
082                optionSelected(null, OptionId.INIT);
083        }
084        
085        public Map<String, MemoryAPI> getMemoryMap() {
086                return null;
087        }
088        
089        public void backFromEngagement(EngagementResultAPI result) {
090                // no combat here, so this won't get called
091        }
092        
093        protected int computeBribeAmount() {
094                PunExData data = PunitiveExpeditionManager.getInstance().getDataFor(intel.getFaction());
095                int numAttempts = 1;
096                if (data != null) numAttempts = data.numAttempts;
097                
098                int bribe = (int) (Math.pow(2, numAttempts) * BRIBE_MULT);
099                if (bribe > BRIBE_MAX) bribe = BRIBE_MAX;
100                return bribe;
101//              int bribe = (int) Math.round(BRIBE_BASE + data.threshold * BRIBE_MULT);
102//              return bribe;
103        }
104        
105        protected void printOptionDesc(OptionId option) {
106                Color tc = Misc.getTextColor();
107                FactionAPI faction = intel.getFaction();
108                
109                switch (option) {
110                case BRIBE:
111                        int bribe = computeBribeAmount();
112                        textPanel.addPara("Sufficient funding allocated to proper official and unofficial actors should " +
113                                        "ensure that the expedition does not go beyond the planning stages.");
114                        
115                        int credits = (int) playerFleet.getCargo().getCredits().get();
116                        Color costColor = Misc.getHighlightColor();
117                        if (bribe > credits) costColor = Misc.getNegativeHighlightColor();
118                        
119                        textPanel.addPara("A total of %s should be enough to get the job done, and will also " +
120                                        "ensure that your standing with " + faction.getDisplayNameWithArticle() + 
121                                        " does not suffer.",
122                                        costColor,
123                                        Misc.getDGSCredits(bribe));
124                        
125                        textPanel.addPara("You have %s available.", Misc.getHighlightColor(),
126                                        Misc.getDGSCredits(credits));
127                        
128                        break;
129                case USE_CONNECTIONS:
130                        boolean canUseConnections = faction.isAtWorst(Factions.PLAYER, MIN_REP);
131                        if (canUseConnections) {
132                                textPanel.addPara("You can use your connections to pull a few strings and ensure the operation " +
133                                                "never gets beyond the planning stages.");
134                        } else {
135                                textPanel.addPara("You do not have sufficient connections with " + faction.getPersonNamePrefix() + 
136                                                " officials to stall out this kind of an operation.");
137                                CoreReputationPlugin.addRequiredStanding(faction, MIN_REP, null, textPanel, null, tc, 0, true);
138                        }
139                        
140                        CoreReputationPlugin.addCurrentStanding(faction, null, textPanel, null, tc, 0f);
141                        
142                        if (canUseConnections) {
143                                textPanel.addPara("Calling in these favors will reduce your " +
144                                                         "standing with " + faction.getDisplayNameWithArticle() + " by %s points.", 
145                                                         Misc.getHighlightColor(), "" + (int) Math.round(REP_COST * 100f));
146                        }
147                        
148                        break;
149                }
150        }
151        
152        protected void addChoiceOptions() {
153                options.clearOptions();
154
155                options.addOption("Allocate sufficient funds for bribes and other means of disrupting the planning", OptionId.BRIBE, null);
156                options.addOption("Use your connections to disrupt the planning", OptionId.USE_CONNECTIONS, null);
157                
158                dialog.setOptionColor(OptionId.BRIBE, Misc.getStoryOptionColor());
159                
160                options.addOption("Dismiss", OptionId.LEAVE, null);
161                options.setShortcut(OptionId.LEAVE, Keyboard.KEY_ESCAPE, false, false, false, true);
162        }
163        
164        protected void addDismissOption() {
165                options.clearOptions();
166                options.addOption("Dismiss", OptionId.LEAVE, null);
167                options.setShortcut(OptionId.LEAVE, Keyboard.KEY_ESCAPE, false, false, false, true);
168        }
169        
170        protected OptionId beingConfirmed = null;
171        protected void addConfirmOptions() {
172                if (beingConfirmed == null) return;
173                
174                options.clearOptions();
175                
176                printOptionDesc(beingConfirmed);
177                
178                options.addOption("Take the necessary actions", OptionId.CONFIRM, null);
179                options.addOption("Never mind", OptionId.CANCEL, null);
180                options.setShortcut(OptionId.CANCEL, Keyboard.KEY_ESCAPE, false, false, false, true);
181
182                if (beingConfirmed == OptionId.BRIBE) {
183
184                        SetStoryOption.set(dialog, 1, OptionId.CONFIRM, "bribePunitiveExpedition", Sounds.STORY_POINT_SPEND_INDUSTRY,
185                                        "Issued bribe to avert " + intel.getFaction().getDisplayName() + " punitive expedition");
186                        
187                        int bribe = computeBribeAmount();
188                        if (bribe > playerFleet.getCargo().getCredits().get()) {
189                                options.setEnabled(OptionId.CONFIRM, false);
190                                options.setTooltip(OptionId.CONFIRM, "Not enough credits.");
191                        }
192                } else if (beingConfirmed == OptionId.USE_CONNECTIONS) {
193                        FactionAPI faction = intel.getFaction();
194                        boolean canUseConnections = faction.isAtWorst(Factions.PLAYER, MIN_REP);
195                        if (!canUseConnections) {
196                                options.setEnabled(OptionId.CONFIRM, false);
197                                options.setTooltip(OptionId.CONFIRM, "Standing not high enough.");
198                        }
199                }
200        }
201        
202        
203        public void printInit() {
204                TooltipMakerAPI info = textPanel.beginTooltip();
205                info.setParaSmallInsignia();
206                intel.addInitialDescSection(info, 0);
207                textPanel.addTooltip();
208                
209                textPanel.addPara("The operation is still in the planning stages, " +
210                                "and you have several options at your disposal to ensure it never gets off the ground.");
211        }
212        
213        public void optionSelected(String text, Object optionData) {
214                if (optionData == null) return;
215                
216                OptionId option = (OptionId) optionData;
217                
218                if (text != null) {
219                        //textPanel.addParagraph(text, Global.getSettings().getColor("buttonText"));
220                        dialog.addOptionSelectedText(option);
221                }
222                
223                switch (option) {
224                case INIT:
225                        printInit();
226                        addChoiceOptions();
227                        break;
228                case BRIBE:
229                        beingConfirmed = OptionId.BRIBE;
230                        addConfirmOptions();
231                        break;
232                case USE_CONNECTIONS:
233                        beingConfirmed = OptionId.USE_CONNECTIONS;
234                        addConfirmOptions();
235                        break;
236                case CONFIRM:
237                        if (beingConfirmed == OptionId.BRIBE) {
238                                int bribe = computeBribeAmount();
239                                AddRemoveCommodity.addCreditsLossText(bribe, textPanel);
240                                playerFleet.getCargo().getCredits().subtract(bribe);
241                        } else if (beingConfirmed == OptionId.USE_CONNECTIONS) {
242                                CustomRepImpact impact = new CustomRepImpact();
243                                impact.delta = -REP_COST;
244                                ReputationAdjustmentResult repResult = Global.getSector().adjustPlayerReputation(
245                                                new RepActionEnvelope(RepActions.CUSTOM, 
246                                                                impact, null, textPanel, false, true),
247                                                                intel.getFaction().getId());
248                        }
249                        intel.getOrganizeStage().abort();
250                        intel.setOutcome(PunExOutcome.AVERTED);
251                        intel.forceFail(false);
252                        intel.sendUpdate(PunitiveExpeditionIntel.OUTCOME_UPDATE, textPanel);
253                        addDismissOption();
254                        break;
255                case CANCEL:
256                        addChoiceOptions();
257                        break;
258                case LEAVE:
259                        leave();
260                        break;
261                }
262        }
263        
264        protected void leave() {
265                dialog.dismiss();
266                ui.updateUIForItem(intel);      
267        }
268        
269        public void optionMousedOver(String optionText, Object optionData) {
270
271        }
272        
273        public void advance(float amount) {
274                
275        }
276        
277        public Object getContext() {
278                return null;
279        }
280}
281
282
283