001package com.fs.starfarer.api.impl.campaign.intel.bar.events;
002
003import java.awt.Color;
004import java.util.Map;
005import java.util.Random;
006
007import com.fs.starfarer.api.Global;
008import com.fs.starfarer.api.campaign.CargoAPI;
009import com.fs.starfarer.api.campaign.InteractionDialogAPI;
010import com.fs.starfarer.api.campaign.OptionPanelAPI;
011import com.fs.starfarer.api.campaign.PersonImportance;
012import com.fs.starfarer.api.campaign.TextPanelAPI;
013import com.fs.starfarer.api.campaign.econ.CommoditySpecAPI;
014import com.fs.starfarer.api.campaign.econ.MarketAPI;
015import com.fs.starfarer.api.campaign.rules.MemoryAPI;
016import com.fs.starfarer.api.characters.PersonAPI;
017import com.fs.starfarer.api.characters.FullName.Gender;
018import com.fs.starfarer.api.impl.campaign.ids.Commodities;
019import com.fs.starfarer.api.impl.campaign.ids.Ranks;
020import com.fs.starfarer.api.impl.campaign.rulecmd.AddRemoveCommodity;
021import com.fs.starfarer.api.ui.LabelAPI;
022import com.fs.starfarer.api.util.Misc;
023import com.fs.starfarer.api.util.WeightedRandomPicker;
024
025public abstract class BaseGetCommodityBarEvent extends BaseBarEvent {
026        public static final String OPTION_CONFIRM = "confirm";
027        public static final String OPTION_CANCEL = "cancel";
028        public static final String OPTION_CONTINUE = "continue";
029        
030        protected long seed;
031        protected PersonAPI person;
032        protected int quantity;
033        protected int unitPrice;
034        protected String commodity;
035        
036        public BaseGetCommodityBarEvent() {
037                seed = Misc.random.nextLong();
038        }
039        
040        protected transient Random random;
041        
042        protected MarketAPI market = null;
043        
044        protected void regen(MarketAPI market) {
045                if (this.market == market) return;
046                this.market = market;
047                
048                random = new Random(seed + market.getId().hashCode());
049                
050                commodity = getCommodityId();
051                if (commodity == null) return;
052                
053                person = createPerson();
054                quantity = computeQuantity();
055                
056                
057                float price = market.getSupplyPrice(commodity, 1, true);
058                unitPrice = (int) (price * getPriceMult());
059                if (unitPrice > 50) {
060                        unitPrice = unitPrice / 10 * 10;
061                }
062                if (unitPrice < 1 && unitPrice > 0) {
063                        unitPrice = 1;
064                }
065        }
066        
067        protected PersonAPI createPerson() {
068                PersonAPI person = Global.getSector().getFaction(getPersonFaction()).createRandomPerson(random);
069                person.setRankId(getPersonRank());
070                person.setPostId(getPersonPost());
071                adjustPerson(person);
072                return person;
073        }
074        
075        
076        
077        protected float getPriceMult() {
078                return 0.75f;
079        }
080        protected String getCommodityId() {
081                return commodity != null ? commodity : Commodities.FOOD;
082        }
083        protected int computeQuantity() {
084                int quantity = 50 + 10 * random.nextInt(6);
085                
086                int size = market.getSize();
087                //quantity *= BaseIndustry.getSizeMult(size);
088                quantity *= Math.max(1, size - 2);
089                return quantity;
090        }
091        protected void adjustPerson(PersonAPI person) {
092                
093        }
094        protected String getPersonFaction() {
095                return market.getFactionId();
096        }
097        protected String getPersonRank() {
098                return Ranks.CITIZEN;
099        }
100        protected String getPersonPost() {
101                return Ranks.CITIZEN;
102        }
103        
104        protected String getManOrWoman() {
105                String manOrWoman = "man";
106                if (person.getGender() == Gender.FEMALE) manOrWoman = "woman";
107                return manOrWoman;
108        }
109        
110        protected String getHeOrShe() {
111                String heOrShe = "he";
112                if (person.getGender() == Gender.FEMALE) {
113                        heOrShe = "she";
114                }
115                return heOrShe;
116        }
117        
118        protected String getHimOrHer() {
119                String himOrHer = "him";
120                if (person.getGender() == Gender.FEMALE) {
121                        himOrHer = "her";
122                }
123                return himOrHer;
124        }
125        
126        protected String getHimOrHerself() {
127                String himOrHer = "himself";
128                if (person.getGender() == Gender.FEMALE) {
129                        himOrHer = "herself";
130                }
131                return himOrHer;
132        }
133        
134        protected String getHisOrHer() {
135                String hisOrHer = "his";
136                if (person.getGender() == Gender.FEMALE) {
137                        hisOrHer = "her";
138                }
139                return hisOrHer;
140        }
141
142        @Override
143        public void addPromptAndOption(InteractionDialogAPI dialog, Map<String, MemoryAPI> memoryMap) {
144                super.addPromptAndOption(dialog, memoryMap);
145                
146                regen(dialog.getInteractionTarget().getMarket());
147                
148                TextPanelAPI text = dialog.getTextPanel();
149                text.addPara(getPrompt());
150                
151                dialog.getOptionPanel().addOption(getOptionText(), this);
152        }
153        
154        protected abstract String getPrompt();
155        protected abstract String getOptionText();
156        
157        protected abstract String getConfirmText();
158        protected abstract String getCancelText();
159        
160        protected abstract String getMainText();
161        protected String [] getMainTextTokens() { return null; };
162        protected Color [] getMainTextColors() { return null; };
163        
164        protected String getMainText2() { return null; };
165        protected String [] getMainText2Tokens() { return null; };
166        protected Color [] getMainText2Colors() { return null; };
167        
168        protected String getAcceptText() { return null; };
169        protected String [] getAcceptTextTokens() { return null; };
170        protected Color [] getAcceptTextColors() { return null; };
171        
172        protected String getDeclineText() { return null; };
173        protected String [] getDeclineTextTokens() { return null; };
174        protected Color [] getDeclineTextColors() { return null; };
175
176        @Override
177        public void init(InteractionDialogAPI dialog, Map<String, MemoryAPI> memoryMap) {
178                super.init(dialog, memoryMap);
179                
180                done = false;
181                
182                dialog.getVisualPanel().showPersonInfo(person, true);
183                
184                TextPanelAPI text = dialog.getTextPanel();
185                if (getMainTextTokens() != null) {
186                        LabelAPI main = text.addPara(getMainText(), Misc.getHighlightColor(), getMainTextTokens());
187                        main.setHighlightColors(getMainTextColors());
188                        main.setHighlight(getMainTextTokens());
189                } else {
190                        text.addPara(getMainText());
191                }
192                
193                if (getMainText2() == null) {
194                        showTotalAndOptions();
195                } else {
196                        OptionPanelAPI options = dialog.getOptionPanel();
197                        options.clearOptions();
198                        options.addOption("Continue", OPTION_CONTINUE);
199                }
200        }
201        
202        protected boolean showCargoCap() {
203                return true;
204        }
205        
206        protected void showTotalAndOptions() {
207                Color h = Misc.getHighlightColor();
208                Color n = Misc.getNegativeHighlightColor();
209
210                TextPanelAPI text = dialog.getTextPanel();
211                
212                boolean canAccept = canAccept();
213                
214                if (showCargoCap() && commodity != null && quantity > 0) {
215                        CommoditySpecAPI spec = Global.getSettings().getCommoditySpec(commodity);
216                        CargoAPI cargo = Global.getSector().getPlayerFleet().getCargo();
217                        String str = "";
218                        int cap = 0;
219                        if (spec.isFuel()) {
220                                cap = cargo.getFreeFuelSpace();
221                                if (cap > 1) {
222                                        str += "Your fleet's fuel tanks can hold an additional %s units of fuel.";
223                                } else {
224                                        str += "Your fleet's fuel tanks are currently full.";
225                                }
226                        } else if (spec.isPersonnel()) {
227                                cap = cargo.getFreeCrewSpace();
228                                if (cap > 1) {
229                                        str += "Your fleet's crew quarters can accommodate an additional %s personnel.";
230                                } else {
231                                        str += "Your fleet's crew berths are currently full.";
232                                }
233                        } else {
234                                cap = (int) cargo.getSpaceLeft();
235                                if (cap > 1) {
236                                        str += "Your fleet's holds can accommodate an additional %s units of cargo.";
237                                } else {
238                                        str += "Your fleet's cargo holds are currently full.";
239                                }
240                        }
241                        text.addPara(str, h, Misc.getWithDGS(cap));
242                }
243                
244                float credits = Global.getSector().getPlayerFleet().getCargo().getCredits().get();
245                int price = unitPrice * quantity;
246                if (price > 0) {
247                        LabelAPI label = text.addPara("The total price is %s. You have %s available.",
248                                                        h,
249                                                        Misc.getDGSCredits(price),      
250                                                        Misc.getDGSCredits(credits));
251                        label.setHighlightColors(canAccept ? h : n, h);
252                        label.setHighlight(Misc.getDGSCredits(price), Misc.getDGSCredits(credits));
253                }
254                
255                
256                OptionPanelAPI options = dialog.getOptionPanel();
257                options.clearOptions();
258                options.addOption(getConfirmText(), OPTION_CONFIRM);
259                if (!canAccept) {
260                        options.setEnabled(OPTION_CONFIRM, false);
261                        String tooltip = getCanNotAcceptTooltip();
262                        if (tooltip != null) {
263                                options.setTooltip(OPTION_CONFIRM, tooltip);
264                        }
265                }
266                if (canAccept) {
267                        addStoryOption();
268                }
269                options.addOption(getCancelText(), OPTION_CANCEL);
270                //options.setShortcut(OPTION_CANCEL, Keyboard.KEY_ESCAPE, false, false, false, true);
271        }
272        
273        protected void addStoryOption() {
274                
275        }
276        
277        protected boolean canAccept() {
278                float credits = Global.getSector().getPlayerFleet().getCargo().getCredits().get();
279                int price = unitPrice * quantity;
280                boolean canAfford = credits >= price;
281                return canAfford;
282        }
283        
284        protected String getCanNotAcceptTooltip() {
285                return "You don't have enough credits.";
286        }
287        
288
289        
290        protected void doExtraConfirmActions() {
291                
292        }
293        
294        
295        protected void doConfirmActionsPreAcceptText() {
296                
297        }
298        protected void doStandardConfirmActions() {
299                int price = unitPrice * quantity;
300                CargoAPI cargo = Global.getSector().getPlayerFleet().getCargo();
301                if (price > 0) cargo.getCredits().subtract(price);
302                cargo.addCommodity(commodity, quantity);
303                
304                TextPanelAPI text = dialog.getTextPanel();
305                
306                if (price > 0) AddRemoveCommodity.addCreditsLossText(price, text);
307                AddRemoveCommodity.addCommodityGainText(commodity, quantity, text);
308        }
309        
310        @Override
311        public void optionSelected(String optionText, Object optionData) {
312                if (optionData == OPTION_CONTINUE) {
313                        TextPanelAPI text = dialog.getTextPanel();
314                        if (getMainText2Tokens() != null) {
315                                LabelAPI main = text.addPara(getMainText2(), Misc.getHighlightColor(), getMainText2Tokens());
316                                main.setHighlightColors(getMainText2Colors());
317                                main.setHighlight(getMainText2Tokens());
318                        } else {
319                                text.addPara(getMainText2());
320                        }
321                        showTotalAndOptions();
322                } else if (optionData == OPTION_CONFIRM) {
323                        done = true;
324                        BarEventManager.getInstance().notifyWasInteractedWith(this);
325                        
326                        doConfirmActionsPreAcceptText();
327                        TextPanelAPI text = dialog.getTextPanel();
328                        String acceptStr = getAcceptText();
329                        if (acceptStr != null) {
330                                if (getAcceptTextTokens() != null) {
331                                        LabelAPI accept = text.addPara(acceptStr, Misc.getHighlightColor(), getAcceptTextTokens());
332                                        accept.setHighlightColors(getAcceptTextColors());
333                                        accept.setHighlight(getAcceptTextTokens());
334                                } else {
335                                        text.addPara(acceptStr);
336                                }
337                        }
338                        
339                        doStandardConfirmActions();
340                        doExtraConfirmActions();
341                        
342                } else if (optionData == OPTION_CANCEL) {
343                        
344                        TextPanelAPI text = dialog.getTextPanel();
345                        String declineStr = getDeclineText();
346                        if (declineStr != null) {
347                                if (getDeclineTextTokens() != null) {
348                                        LabelAPI decline = text.addPara(declineStr, Misc.getHighlightColor(), getAcceptTextTokens());
349                                        decline.setHighlightColors(getDeclineTextColors());
350                                        decline.setHighlight(getDeclineTextTokens());
351                                } else {
352                                        text.addPara(declineStr);
353                                }
354                        } else {
355                                noContinue = true;
356                        }
357                        done = true;
358                }
359//              else if (optionText == getStoryOptionId() && getStoryOptionId() != null) {
360//                      
361//              }
362        }
363
364        @Override
365        public boolean isDialogFinished() {
366                return done;
367        }
368
369        public PersonAPI getPerson() {
370                return person;
371        }
372
373        public MarketAPI getMarket() {
374                return market;
375        }
376        
377        
378        public PersonImportance pickImportance() {
379                WeightedRandomPicker<PersonImportance> picker = new WeightedRandomPicker<PersonImportance>(random);
380                picker.add(PersonImportance.VERY_LOW, 1f);
381                picker.add(PersonImportance.LOW, 5f);
382                picker.add(PersonImportance.MEDIUM, 10f);
383                picker.add(PersonImportance.HIGH, 5f);
384                picker.add(PersonImportance.VERY_HIGH, 1f);
385                return picker.pick();
386        }
387        public PersonImportance pickMediumImportance() {
388                WeightedRandomPicker<PersonImportance> picker = new WeightedRandomPicker<PersonImportance>(random);
389                picker.add(PersonImportance.LOW, 5f);
390                picker.add(PersonImportance.MEDIUM, 10f);
391                picker.add(PersonImportance.HIGH, 5f);
392                return picker.pick();
393        }
394        public PersonImportance pickHighImportance() {
395                WeightedRandomPicker<PersonImportance> picker = new WeightedRandomPicker<PersonImportance>(random);
396                picker.add(PersonImportance.MEDIUM, 10f);
397                picker.add(PersonImportance.HIGH, 5f);
398                picker.add(PersonImportance.VERY_HIGH, 1f);
399                return picker.pick();
400        }
401        public PersonImportance pickLowImportance() {
402                WeightedRandomPicker<PersonImportance> picker = new WeightedRandomPicker<PersonImportance>(random);
403                picker.add(PersonImportance.VERY_LOW, 10f);
404                picker.add(PersonImportance.LOW, 5f);
405                picker.add(PersonImportance.MEDIUM, 1f);
406                return picker.pick();
407        }
408        
409
410        public String pickOne(String ... options) {
411                WeightedRandomPicker<String> picker = new WeightedRandomPicker<String>(random);
412                for (String option : options) {
413                        picker.add(option);
414                }
415                return picker.pick();
416        }
417        
418}
419
420
421
422