001package com.fs.starfarer.api.impl.campaign.intel;
002
003import java.util.ArrayList;
004import java.util.LinkedHashSet;
005import java.util.List;
006import java.util.Map;
007import java.util.Set;
008
009import java.awt.Color;
010
011import org.lwjgl.input.Keyboard;
012import org.lwjgl.util.vector.Vector2f;
013
014import com.fs.starfarer.api.EveryFrameScript;
015import com.fs.starfarer.api.Global;
016import com.fs.starfarer.api.campaign.CampaignClockAPI;
017import com.fs.starfarer.api.campaign.FactionAPI;
018import com.fs.starfarer.api.campaign.InteractionDialogAPI;
019import com.fs.starfarer.api.campaign.LocationAPI;
020import com.fs.starfarer.api.campaign.SectorEntityToken;
021import com.fs.starfarer.api.campaign.StoryPointActionDelegate;
022import com.fs.starfarer.api.campaign.TextPanelAPI;
023import com.fs.starfarer.api.campaign.comm.CommMessageAPI.MessageClickAction;
024import com.fs.starfarer.api.campaign.comm.IntelInfoPlugin;
025import com.fs.starfarer.api.campaign.econ.MarketAPI;
026import com.fs.starfarer.api.campaign.rules.MemoryAPI;
027import com.fs.starfarer.api.impl.campaign.CommRelayEntityPlugin.CommSnifferReadableIntel;
028import com.fs.starfarer.api.impl.campaign.ids.Tags;
029import com.fs.starfarer.api.impl.campaign.rulecmd.CallEvent.CallableEvent;
030import com.fs.starfarer.api.impl.campaign.tutorial.TutorialMissionIntel;
031import com.fs.starfarer.api.ui.ButtonAPI;
032import com.fs.starfarer.api.ui.CustomPanelAPI;
033import com.fs.starfarer.api.ui.IntelUIAPI;
034import com.fs.starfarer.api.ui.LabelAPI;
035import com.fs.starfarer.api.ui.SectorMapAPI;
036import com.fs.starfarer.api.ui.TooltipMakerAPI;
037import com.fs.starfarer.api.util.Misc;
038import com.fs.starfarer.api.util.Misc.Token;
039
040/**
041 * @author Alex Mosolov
042 *
043 * Copyright 2018 Fractal Softworks, LLC
044 */
045public class BaseIntelPlugin implements IntelInfoPlugin, CallableEvent, EveryFrameScript, CommSnifferReadableIntel {
046        
047        public static final String BULLET = "    - ";
048        public static final String INDENT = "      ";
049        
050        public static String BUTTON_DELETE = "button_delete";
051        
052        protected Boolean important;
053        protected Long timestamp;
054        protected Boolean neverClicked = true;
055        
056        transient protected Object listInfoParam = null;
057        
058        protected Boolean ended = null; 
059        protected Boolean ending = null; 
060        protected Float endingTimeRemaining = null;
061        
062        protected SectorEntityToken postingLocation = null; 
063        protected Float postingRangeLY = null;
064        
065        protected transient Set<String> tagsForSort = null;
066        
067        public BaseIntelPlugin() {
068        }
069        
070        
071        public void advance(float amount) {
072                if (isEnded()) return;
073                
074                float days = Global.getSector().getClock().convertToDays(amount);
075                if (isEnding()) {
076                        endingTimeRemaining -= days;
077                        if (endingTimeRemaining <= 0) {
078                                ended = true;
079                                notifyEnded();
080                        }
081                        return;
082                }
083                
084                advanceImpl(amount);
085        }
086        
087        public void notifyPlayerAboutToOpenIntelScreen() {
088                
089        }
090        
091        protected void advanceImpl(float amount) {}
092        
093        protected void notifyEnding() {
094                
095        }
096        
097        protected void notifyEnded() {
098                //Global.getSector().getIntelManager().removeIntel(this);
099        }
100        
101        public void endImmediately() {
102                endAfterDelay(0f);
103        }
104        public void endAfterDelay() {
105                endAfterDelay(getBaseDaysAfterEnd());
106        }
107        public void endAfterDelay(float days) {
108                endingTimeRemaining = days;
109                boolean wasEnding = isEnding();
110                ending = true;
111                if (!wasEnding) {
112                        notifyEnding();
113                }
114                if (endingTimeRemaining <= 0) {
115                        ended = true;
116                        notifyEnded();
117                }
118        }
119        
120        protected float getBaseDaysAfterEnd() {
121                return 3f;
122        }
123
124        public boolean isDone() {
125                return isEnded();
126        }
127
128        public boolean runWhilePaused() {
129                return false;
130        }
131        
132        public boolean isEnding() {
133                return ending != null && ending;
134        }
135        
136        public boolean isEnded() {
137                return ended != null && ended;
138        }
139        
140        
141        /**
142         * Call from createMessageListInfo() to figure out what type of update to create.
143         * Call from getCommMesageSound() to pick sound to play.
144         * @return
145         */
146        public Object getListInfoParam() {
147                return listInfoParam;
148        }
149        
150        public void setListInfoParam(Object listInfoParam) {
151                this.listInfoParam = listInfoParam;
152        }
153
154
155        public boolean isSendingUpdate() {
156                return listInfoParam != null;
157        }
158        
159        public void sendUpdate(Object listInfoParam, TextPanelAPI textPanel) {
160                this.listInfoParam = listInfoParam;
161                Global.getSector().getIntelManager().addIntelToTextPanel(this, textPanel);
162                this.listInfoParam = null;
163        }
164        
165        public void sendUpdateIfPlayerHasIntel(Object listInfoParam, TextPanelAPI textPanel) {
166                if (textPanel == null) {
167                        sendUpdateIfPlayerHasIntel(listInfoParam, false);
168                } else {
169                        sendUpdate(listInfoParam, textPanel);
170                }
171        }
172        
173        public void sendUpdateIfPlayerHasIntel(Object listInfoParam, boolean onlyIfImportant) {
174                sendUpdateIfPlayerHasIntel(listInfoParam, onlyIfImportant, false);
175        }
176        public void sendUpdateIfPlayerHasIntel(Object listInfoParam, boolean onlyIfImportant, boolean sendIfHidden) {
177                if (timestamp == null) return;
178                
179                if (onlyIfImportant && !isImportant()) return;
180                
181                if (!sendIfHidden && isHidden()) return;
182                
183                this.listInfoParam = listInfoParam;
184                Global.getSector().getCampaignUI().addMessage(this, MessageClickAction.INTEL_TAB, this);
185                this.listInfoParam = null;
186        }
187
188
189        public boolean canTurnImportantOff() {
190                return true;
191        }
192
193        public String getImportantIcon() {
194                return null;
195        }
196
197        public boolean hasImportantButton() {
198                return true;
199        }
200
201//      public void createIntelInfo(TooltipMakerAPI info, ListInfoMode mode) {
202//              info.addPara("Override .createIntelInfo()", Misc.getNegativeHighlightColor(), 0f);
203//      }
204        
205        protected void addBulletPoints(TooltipMakerAPI info, ListInfoMode mode) {
206                float pad = 3f;
207                float opad = 10f;
208                
209                float initPad = pad;
210                if (mode == ListInfoMode.IN_DESC) initPad = opad;
211                
212                Color tc = getBulletColorForMode(mode);
213        
214                boolean isUpdate = getListInfoParam() != null;
215                
216                bullet(info);
217                addBulletPoints(info, mode, isUpdate, tc, initPad);
218                unindent(info);
219        }
220        
221        protected void addBulletPoints(TooltipMakerAPI info, ListInfoMode mode, boolean isUpdate, 
222                                                                   Color tc, float initPad) {
223                
224        }
225
226        public void createIntelInfo(TooltipMakerAPI info, ListInfoMode mode) {
227                if (getName() != null) {
228                        Color c = getTitleColor(mode);
229                        info.addPara(getName(), c, 0f);
230                }
231                addBulletPoints(info, mode);
232        }
233        
234        protected String getName() {
235                return null;
236        }
237        
238        
239        public boolean hasSmallDescription() {
240                return true;
241        }
242        
243        public void createSmallDescription(TooltipMakerAPI info, float width, float height) {
244                info.addPara("Override .createSmallDescription()", Misc.getNegativeHighlightColor(), 0f);
245        }
246        
247        public boolean hasLargeDescription() {
248                return false;
249        }
250        
251        public void createLargeDescription(CustomPanelAPI panel, float width, float height) {
252                TooltipMakerAPI desc = panel.createUIElement(width, height, true);
253                desc.addPara("Override .createLargeDescription()", Misc.getNegativeHighlightColor(), 0f);
254                panel.addUIElement(desc).inTL(0, 0);
255        }
256
257        public String getIcon() {
258                return null;
259        }
260        
261//      public float getIconBrightness() {
262//              if (isEnding() || isEnded()) return 0.5f;
263//              return 1f;
264//      }
265        
266        public Color getBackgroundGlowColor() {
267                return null;
268        }
269
270        public boolean shouldRemoveIntel() {
271//              if (this instanceof CommSnifferIntel) {
272//                      System.out.println("wefwefe");
273//              }
274//              if (isImportant()) return false;
275                
276                if (timestamp == null && isEnding()) {
277                        return true; // already ending, and not yet player-visible; remove
278                }
279                return isEnded();
280        }
281
282        public Set<String> getIntelTags(SectorMapAPI map) {
283                Set<String> tags = new LinkedHashSet<String>();
284                if (isImportant()) {
285                        tags.add(Tags.INTEL_IMPORTANT);
286                }
287                if (isNew()) {
288                        tags.add(Tags.INTEL_NEW);
289                }
290                if (map != null) {
291                        SectorEntityToken loc = getMapLocation(map);
292                        if (loc != null) {
293                                float max = Global.getSettings().getFloat("maxRelayRangeInHyperspace");
294                                float dist = Misc.getDistanceLY(loc.getLocationInHyperspace(), Global.getSector().getPlayerFleet().getLocationInHyperspace());
295                                if (dist <= max) {
296                                        tags.add(Tags.INTEL_LOCAL);
297                                }
298                        }
299                }
300                
301//              FactionAPI faction = getFactionForUIColors();
302//              if (faction != null && !faction.isPlayerFaction()) {
303//                      if (faction.isHostileTo(Factions.PLAYER)) {
304//                              tags.add(Tags.INTEL_HOSTILE);
305//                      } else {
306//                              tags.add(Tags.INTEL_NOT_HOSTILE);
307//                      }
308//              }
309                
310                return tags;
311        }
312
313        
314        public boolean isImportant() {
315                return important != null && important;
316        }
317
318        public void setImportant(Boolean important) {
319                this.important = important;
320                if (this.important != null && !this.important) {
321                        this.important = null;
322                }
323        }
324        
325        public FactionAPI getFactionForUIColors() {
326                return Global.getSector().getPlayerFaction();
327        }
328        
329        public boolean doesButtonHaveConfirmDialog(Object buttonId) {
330                if (buttonId == BUTTON_DELETE) {
331                        return true;
332                }
333                return false;
334        }
335        public float getConfirmationPromptWidth(Object buttonId) {
336                return 550f;
337        }
338        
339        protected void createDeleteConfirmationPrompt(TooltipMakerAPI prompt) {
340                prompt.addPara("Are you sure you want to permanently delete this fleet log entry?", Misc.getTextColor(), 0f);
341        }
342        
343        public void createConfirmationPrompt(Object buttonId, TooltipMakerAPI prompt) {
344                if (buttonId == BUTTON_DELETE) {
345                        createDeleteConfirmationPrompt(prompt);
346                }
347        }
348        
349        public String getConfirmText(Object buttonId) {
350                return "Confirm";
351        }
352
353        public String getCancelText(Object buttonId) {
354                return "Cancel";
355        }
356        
357        protected void addDeleteButton(TooltipMakerAPI info, float width) {
358                addDeleteButton(info, width, "Delete log entry");
359        }
360        protected void addDeleteButton(TooltipMakerAPI info, float width, String delete) {
361                float opad = 10f;
362                ButtonAPI button = info.addButton(delete, BUTTON_DELETE, 
363                                        getFactionForUIColors().getBaseUIColor(), getFactionForUIColors().getDarkUIColor(),
364                                  (int)(width), 20f, opad * 2f);
365                button.setShortcut(Keyboard.KEY_G, true);
366        }
367        
368        public void buttonPressConfirmed(Object buttonId, IntelUIAPI ui) {
369                if (buttonId == BUTTON_DELETE) {
370                        endImmediately();
371                        ui.recreateIntelUI();
372                        return;
373                }
374                ui.updateUIForItem(this);
375        }
376        
377//      public void buttonPressConfirmed(Object buttonId, IntelUIAPI ui) {
378//              ui.updateUIForItem(this);
379//      }
380        
381        public void buttonPressCancelled(Object buttonId, IntelUIAPI ui) {
382        }
383        
384        public boolean isPlayerVisible() {
385                if (isHidden()) return false;
386                if (isEnded()) return false;
387                return timestamp != null;
388        }
389
390        public Long getPlayerVisibleTimestamp() {
391                return timestamp;
392        }
393
394        public void setPlayerVisibleTimestamp(Long timestamp) {
395                this.timestamp = timestamp;
396        }
397
398        public float getDaysSincePlayerVisible() {
399                long ts = Global.getSector().getClock().getTimestamp();
400                if (timestamp != null) ts = timestamp;
401                return Global.getSector().getClock().getElapsedDaysSince(ts);
402        }
403        
404        public void reportPlayerClickedOn() {
405                neverClicked = null; // makes it lose "new" status
406        }
407        
408        public boolean isNew() {
409                Long ts = getPlayerVisibleTimestamp();
410                if (ts == null) ts = 0L;
411                float days = Global.getSector().getClock().getElapsedDaysSince(ts);
412                return neverClicked != null && neverClicked && days < NEW_DAYS;
413        }
414        
415        public void setNew(boolean isNew) {
416                if (isNew) {
417                        neverClicked = true;
418                } else {
419                        neverClicked = null;
420                }
421        }
422        
423        public IntelSortTier getSortTier() {
424                if (isEnding()) {
425                        return IntelSortTier.TIER_COMPLETED;
426                }
427                return IntelSortTier.TIER_3;
428        }
429        
430        public String getSortString() {
431                if (getTagsForSort().contains(Tags.INTEL_FLEET_LOG) || getTagsForSort().contains(Tags.INTEL_EXPLORATION)) {
432                        return getSortStringNewestFirst();
433                }
434                return getName();
435                //return getName();
436                //return null;
437        }
438        
439        public boolean autoAddCampaignMessage() {
440                return !isHidden();
441        }
442        
443        public String getCommMessageSound() {
444                if (isSendingUpdate()) {
445                        return getSoundStandardUpdate();
446                }
447                return getSoundStandardPosting();
448        }
449        
450        
451        protected Boolean hidden = null;
452        public boolean isHidden() {
453                // never mind; handled by making comm relay in Galatia non-functional until the jump-point is stabilized
454                // but procurement missions etc generated inside Galatia still show up, so: need to do this
455                return TutorialMissionIntel.isTutorialInProgress() || hidden != null;  
456                //return hidden != null;
457        }
458        
459        
460        public void setHidden(boolean hidden) {
461                if (hidden) {
462                        this.hidden = hidden;
463                } else {
464                        this.hidden = null;
465                }
466        }
467
468
469        public void reportMadeVisibleToPlayer() {
470                
471        }
472        
473        protected float getCommRelayRange() {
474                return Global.getSettings().getFloat("maxRelayRangeInHyperspace");
475        }
476
477        public boolean canMakeVisibleToPlayer(boolean playerInRelayRange) {
478                return canMakeVisible(playerInRelayRange, 
479                                                                          Global.getSector().getPlayerFleet().getContainingLocation(),
480                                                                          Global.getSector().getPlayerFleet().getLocationInHyperspace(), false);
481        }
482        
483        public boolean canMakeVisibleToCommSniffer(boolean playerInRelayRange, SectorEntityToken relay) {
484                return canMakeVisible(playerInRelayRange, relay.getContainingLocation(), 
485                                                          relay.getLocationInHyperspace(), true);
486        }
487        
488        public boolean canMakeVisible(boolean playerInRelayRange, LocationAPI conLoc, Vector2f hyperLoc,
489                                                                                  boolean commSniffer) {
490                if (isEnding()) return false;
491                
492                if (postingLocation != null) {
493                        float rangeLY = 0f;
494                        if (postingRangeLY != null) {
495                                rangeLY = postingRangeLY;
496                        } else { // unless a range of 0 is specified, get local messages when nearing system
497                                rangeLY = getCommRelayRange();
498                        }
499                        
500                        float commRange = 0f;
501                        if (postingLocation.isInHyperspace()) {
502                                commRange = getCommRelayRange();
503                                rangeLY = Math.max(rangeLY, commRange);
504                        }
505
506                        boolean sameLoc = postingLocation.getContainingLocation() != null &&
507                                                          postingLocation.getContainingLocation() == 
508                                                                conLoc;
509                        if (rangeLY <= 0 && !sameLoc) {
510                                return false;
511                        }
512                        
513                        if (playerInRelayRange) {
514                                float dist = Misc.getDistanceLY(postingLocation.getLocationInHyperspace(), 
515                                                                                                hyperLoc);
516                                return dist <= rangeLY;
517                        } else {
518                                if (postingLocation.isInHyperspace()) {
519                                        float dist = Misc.getDistanceLY(postingLocation.getLocationInHyperspace(), 
520                                                                                                        hyperLoc);
521                                        return dist < commRange && (!commSniffer || playerInRelayRange);
522                                } else {
523                                        return sameLoc && (!commSniffer || playerInRelayRange);
524                                }
525                        }
526                }
527                
528                return playerInRelayRange;
529        }
530
531        public SectorEntityToken getPostingLocation() {
532                return postingLocation;
533        }
534
535        public void setPostingLocation(SectorEntityToken postingLocation) {
536                this.postingLocation = postingLocation;
537        }
538
539        public Float getPostingRangeLY() {
540                return postingRangeLY;
541        }
542
543        public void setPostingRangeLY(Float postingRangeLY) {
544                setPostingRangeLY(postingRangeLY, false);
545        }
546        public void setPostingRangeLY(Float postingRangeLY, boolean ensureVisibleOutsideSystem) {
547                if (ensureVisibleOutsideSystem) {
548                        if (postingRangeLY == null) postingRangeLY = 0f;
549                        postingRangeLY = Math.max(postingRangeLY, getCommRelayRange());
550                }
551                this.postingRangeLY = postingRangeLY;
552        }
553
554        
555        public void reportRemovedIntel() {
556                
557        }
558        
559        public SectorEntityToken getMapLocation(SectorMapAPI map) {
560                return null;
561        }
562
563        
564        protected void bullet(TooltipMakerAPI info) {
565                info.setBulletedListMode("    - ");
566                if (listInfoParam != null && false) {
567                        info.setTextWidthOverride(0);
568                } else {
569                        info.setTextWidthOverride(LIST_ITEM_TEXT_WIDTH);
570                }
571        }
572        protected void indent(TooltipMakerAPI info) {
573                info.setBulletedListMode("      ");
574                if (listInfoParam != null && false) {
575                        info.setTextWidthOverride(0);
576                } else {
577                        info.setTextWidthOverride(LIST_ITEM_TEXT_WIDTH);
578                }
579        }
580        protected void unindent(TooltipMakerAPI info) {
581                info.setBulletedListMode(null);
582                info.setTextWidthOverride(0);
583        }
584        
585        protected void addDays(TooltipMakerAPI info, String after, float days) {
586                addDays(info, after, days, null);
587        }
588        protected void addDays(TooltipMakerAPI info, String after, float days, Color c) {
589                addDays(info, after, days, c, 0f);
590        }
591        protected void addDays(TooltipMakerAPI info, String after, float days, Color c, float pad) {
592                addDays(info, "", after, days, c, pad);
593        }
594        protected void addDays(TooltipMakerAPI info, String before, String after, float days, Color c, float pad) {
595                String pre = "";
596                if (info.getBulletedListPrefix() != null) {
597                        pre = "";
598                }
599                
600                int d = (int) Math.round(days);
601                String daysStr = "days";
602                if (d <= 1) {
603                        d = 1;
604                        daysStr = "day";
605                }
606                if (c == null) c = Misc.getGrayColor();
607                info.addPara(before + pre + "%s " + daysStr + " " + after, pad, c,
608                                Misc.getHighlightColor(), "" + d);
609        }
610
611        protected String getDays(float days) {
612                return "" + (int) Math.round(days);
613        }
614        public static String getDaysString(float days) {
615                int d = (int) Math.round(days);
616                String daysStr = "days";
617                if (d == 1) {
618                        d = 1;
619                        daysStr = "day";
620                }
621                return daysStr;
622        }
623        
624        public String getSmallDescriptionTitle() {
625                return getName();
626        }
627        
628        public Color getTitleColor(ListInfoMode mode) {
629                boolean isUpdate = getListInfoParam() != null;
630                if (isEnding() && !isUpdate && mode != ListInfoMode.IN_DESC) {
631                        return Misc.getGrayColor();
632                }
633                return Global.getSector().getPlayerFaction().getBaseUIColor();
634        }
635        
636//      public static Color getListMessageBulletColor() {
637//              //return Misc.getGrayColor();
638//              return Misc.getTextColor();
639//      }
640//      
641//      public static Color getIntelListBulletColor() {
642//              return Misc.getGrayColor();
643//              //return Misc.getTextColor();
644//      }
645        
646        protected Color getBulletColorForMode(ListInfoMode mode) {
647                //boolean isUpdate = getListInfoParam() != null;
648                Color tc = Misc.getTextColor();
649                //if (true) return tc;
650                Color g = Misc.getGrayColor();
651                switch (mode) {
652                case INTEL: return g;
653                case MAP_TOOLTIP: return tc;
654                case IN_DESC: return tc;
655                case MESSAGES: return tc;
656                }
657
658                return g;
659        }
660        
661
662        public boolean callEvent(String ruleId, InteractionDialogAPI dialog, List<Token> params, Map<String, MemoryAPI> memoryMap) {
663                return false;
664        }
665        
666        
667        public static String getSoundStandardPosting() {
668                return "ui_intel_something_posted";
669        }
670        
671        public static String getSoundStandardUpdate() {
672                return "ui_intel_update";
673        }
674        
675        public static String getSoundMajorPosting() {
676                return "ui_intel_major_posted";
677        }
678        
679        public static String getSoundColonyThreat() {
680                return "colony_threat";
681        }
682        
683        public static String getSoundLogUpdate() {
684                return "ui_intel_log_update";
685        }
686        
687        public static String getSoundMinorMessage() {
688                return "ui_intel_minor_message";
689        }
690
691        public List<ArrowData> getArrowData(SectorMapAPI map) {
692                return null;
693        }
694
695
696        public float getTimeRemainingFraction() {
697                return 0;
698        }
699        
700        
701        public ButtonAPI addGenericButton(TooltipMakerAPI info, float width, String text, Object data) {
702                return addGenericButton(info, width, 
703                                getFactionForUIColors().getBaseUIColor(), getFactionForUIColors().getDarkUIColor(), text, data);
704        }
705        public ButtonAPI addGenericButton(TooltipMakerAPI info, float width, Color tc, Color bg, String text, Object data) {
706                float opad = 10f;
707                ButtonAPI button = info.addButton(text, data, tc, bg,
708                                  (int)(width), 20f, opad * 2f);
709                return button;
710        }
711
712
713        protected Boolean forceAdd = null;
714        public boolean forceAddNextFrame() {
715                return forceAdd != null;
716        }
717
718        public void setForceAddNextFrame(boolean add) {
719                if (add) {
720                        forceAdd = true;
721                } else {
722                        forceAdd = null;
723                }
724        }
725        
726        public static void addMarketToList(TooltipMakerAPI info, MarketAPI market, float pad) {
727                addMarketToList(info, market, pad, null);
728        }
729        
730        public static void addMarketToList(TooltipMakerAPI info, MarketAPI market, float pad, Color tc) {
731                if (tc == null) tc = Misc.getTextColor();
732                String indent = BaseIntelPlugin.INDENT;
733                if (info.getBulletedListPrefix() != null) indent = "";
734                LabelAPI label = info.addPara(indent + market.getName() + " (size %s, %s)",
735                                //faction.getPersonNamePrefixAOrAn() + " %s colony.", 
736                                pad, tc, market.getFaction().getBaseUIColor(),
737                                "" + (int) market.getSize(),
738                                market.getFaction().getDisplayName());
739                
740                label.setHighlight("" + (int) market.getSize(), market.getFaction().getDisplayName());
741                label.setHighlightColors(Misc.getHighlightColor(), market.getFaction().getBaseUIColor());
742        }
743        
744        public static void addMarketTable(TooltipMakerAPI info, Color base, Color dark, Color bright, List<MarketAPI> markets, float width, float pad) {
745                Color h = Misc.getHighlightColor();
746                FactionAPI f = Global.getSector().getPlayerFaction();
747                info.beginTable(base, dark, bright, 20f, "Colony", 130f, "Faction", 130f, "Size", width - 260f);
748                for (MarketAPI market : markets) {
749                        //info.addRow(Misc.getTextColor(), market.getName(),
750                        info.addRow(market.getFaction().getBaseUIColor(), market.getName(),
751                                         market.getFaction().getBaseUIColor(), market.getFaction().getDisplayName(),
752                                         h, "" + market.getSize());
753                }
754                
755                info.addTable("None", 0, pad);
756                info.addSpacer(5f);
757        }
758
759        public StoryPointActionDelegate getButtonStoryPointActionDelegate(Object buttonId) {
760                return null;
761        }
762        
763        public void storyActionConfirmed(Object buttonId, IntelUIAPI ui) {
764                
765        }
766
767        public Color getCircleBorderColorOverride() {
768                // TODO Auto-generated method stub
769                return null;
770        }
771
772        public void tableRowClicked(IntelUIAPI ui, TableRowClickData data) {
773                
774        }
775        
776        public void addLogTimestamp(TooltipMakerAPI info, Color tc, float opad) {
777                
778//              if (!getTagsForSort().contains(Tags.INTEL_FLEET_LOG) && !getTagsForSort().contains(Tags.INTEL_EXPLORATION)) {
779                if (!getTagsForSort().contains(Tags.INTEL_FLEET_LOG) && 
780                                !getTagsForSort().contains(Tags.INTEL_MARKER)) {
781                        return;
782                }
783                
784//              {
785//                      float days = getDaysSincePlayerVisible();
786//                      if (days >= 1) {
787//                              addDays(info, "Log entry added ", "ago.", days, tc, opad);
788//                      } else {
789//                              info.addPara("Log entry added less than a day ago.", opad);
790//                      }
791//              }
792                
793                Color h = Misc.getHighlightColor();
794                
795                long ts = Global.getSector().getClock().getTimestamp();
796                if (timestamp != null) ts = timestamp;
797                CampaignClockAPI clock = Global.getSector().getClock().createClock(ts);
798                
799//              String dateStr = "Logged on c." + clock.getCycle() + ", " + clock.getShortMonthString() + " " + clock.getDay();
800//              //tc = Misc.getGrayColor();
801//              info.addPara(dateStr, opad, tc, h, "c." + clock.getCycle(), "" + clock.getDay());
802                
803                long msPerMin = 60L * 1000L;
804                long msPerHour = msPerMin * 60L;
805                long msPerDay = msPerHour * 24L;
806                //long msPerWeek = msPerDay * 7L;
807                long msPerMonth = msPerDay * 30L;
808                long msPerCycle = msPerDay * 365L;
809
810                long diff = Global.getSector().getClock().getTimestamp() - ts;
811
812
813                String agoStr = "";
814                List<String> highlights = new ArrayList<>();
815//              highlights.add("c." + clock.getCycle());
816//              highlights.add("" + clock.getDay());
817                if (diff < msPerHour && false) {
818                        long minutes = diff / msPerMin;
819                        agoStr = "" + minutes + " " + (minutes == 1 ? "minute" : "minutes");
820                } else if (diff < msPerDay && false) {
821                        long hours = diff / msPerHour;
822                        agoStr = "" + hours + " " + (hours == 1 ? "hour" : "hours");
823                        long rem = diff - hours * msPerHour;
824                        long minutes = rem / msPerMin;
825                        agoStr += " " + minutes + " " + (minutes == 1 ? "minute" : "minutes");
826                } else if (diff < msPerMonth) {
827                        long days = diff / msPerDay;
828                        agoStr = "" + days + " " + (days == 1 ? "day" : "days");
829                        highlights.add("" + days);
830//                      long rem = diff - days * msPerDay;
831//                      long hours = rem / msPerHour;
832//                      agoStr += " " + hours + " " + (hours == 1 ? "hour" : "hours");
833                } else if (diff < msPerCycle) {
834                        long months = diff / msPerMonth;
835                        agoStr = "" + months + " " + (months == 1 ? "month" : "months");
836                        long rem = diff - months * msPerMonth;
837                        long days = rem / msPerDay;
838                        agoStr += " and " + days + " " + (days == 1 ? "day" : "days");
839                        highlights.add("" + months);
840                        highlights.add("" + days);
841                } else {
842                        long cycles = diff / msPerCycle;
843                        agoStr = "" + cycles + " " + (cycles == 1 ? "cycle" : "cycles");
844                        long rem = diff - cycles * msPerCycle;
845                        long months = rem / msPerMonth;
846                        agoStr += " and " + months + " " + (months == 1 ? "month" : "months");
847                        highlights.add("" + cycles);
848                        highlights.add("" + months);
849                }
850                
851
852                //String dateStr = "Logged on c." + clock.getCycle() + ", " + clock.getShortMonthString() + " " + clock.getDay();
853                //tc = Misc.getGrayColor();
854                //info.addPara(dateStr + ", " + agoStr + " ago.", opad, tc, h, highlights.toArray(new String[0]));
855                long days = diff / msPerDay;
856                if (days >= 1) {
857                        info.addPara("Log entry added " + agoStr + " ago.", opad, tc, h, highlights.toArray(new String[0]));
858                } else {
859                        info.addPara("Log entry added less than a day ago.", opad);
860                }
861                
862                //ago = Label.create(agoStr, Misc.getGrayColor());
863        }
864        
865        
866        public String getSortStringNewestFirst() {
867                return getSortStringNewestFirst("zzz");
868        }
869        public String getSortStringNewestFirst(String prefix) {
870                return prefix + String.format("%1$20s", "" + getPlayerVisibleTimestamp()).replace(' ', '0');
871                //return "Fleet Log " + getPlayerVisibleTimestamp();
872        }
873
874        @Override
875        public Set<String> getTagsForSort() {
876                if (tagsForSort == null) {
877                        tagsForSort = new LinkedHashSet<>();
878                }
879                return tagsForSort;
880        }
881
882        @Override
883        public void setTagsForSort(Set<String> tagsForSort) {
884                this.tagsForSort = tagsForSort;
885        }
886        
887        
888}
889
890
891
892
893
894