001package jmri.jmrit.operations.trains.csv;
002
003import java.io.IOException;
004import java.util.List;
005
006import org.apache.commons.csv.CSVPrinter;
007
008import jmri.InstanceManager;
009import jmri.jmrit.operations.locations.Location;
010import jmri.jmrit.operations.locations.Track;
011import jmri.jmrit.operations.rollingstock.cars.Car;
012import jmri.jmrit.operations.rollingstock.cars.CarManager;
013import jmri.jmrit.operations.rollingstock.engines.Engine;
014import jmri.jmrit.operations.routes.RouteLocation;
015import jmri.jmrit.operations.setup.Setup;
016import jmri.jmrit.operations.trains.Train;
017import jmri.jmrit.operations.trains.trainbuilder.TrainCommon;
018import jmri.util.FileUtil;
019
020/**
021 * Contains the csv operators for manifests and switch lists
022 *
023 * @author Daniel Boudreau Copyright (C) 2011, 2013, 2015, 2022
024 */
025public class TrainCsvCommon extends TrainCommon {
026
027    protected final void printDepartureTime(CSVPrinter printer, String time) throws IOException {
028        printer.printRecord("DT", Bundle.getMessage("csvDepartureTime"), time); // NOI18N
029    }
030
031    protected final void printHeader(CSVPrinter printer) throws IOException {
032        printer.printRecord(Bundle.getMessage("csvOperator"), Bundle.getMessage("csvDescription"),
033                Bundle.getMessage("csvParameters")); // NOI18N
034    }
035
036    protected final void printLocationSwitchListComment(CSVPrinter printer, String comment, String textColorName)
037            throws IOException {
038        printer.printRecord("SWLC", Bundle.getMessage("csvSwitchListComment"), comment, textColorName); // NOI18N
039    }
040
041    protected final void printLocationComment(CSVPrinter printer, String comment, String textColorName)
042            throws IOException {
043        printer.printRecord("LC", Bundle.getMessage("csvLocationComment"), comment, textColorName); // NOI18N
044    }
045
046    protected final void printLocationName(CSVPrinter printer, String name) throws IOException {
047        printer.printRecord("LN", Bundle.getMessage("csvLocationName"), name); // NOI18N
048    }
049
050    protected final void printPrinterName(CSVPrinter printer, String name) throws IOException {
051        printer.printRecord("PRNTR", Bundle.getMessage("csvPrinterName"), name); // NOI18N
052    }
053
054    protected final void printRailroadName(CSVPrinter printer, String name) throws IOException {
055        printer.printRecord("RN", Bundle.getMessage("csvRailroadName"), name); // NOI18N
056    }
057
058    protected final void printRemoveHelpers(CSVPrinter printer) throws IOException {
059        printer.printRecord("RH", Bundle.getMessage("csvRemoveHelpers")); // NOI18N
060    }
061
062    protected final void printRouteLocationComment(CSVPrinter printer, String comment, String textColorName)
063            throws IOException {
064        printer.printRecord("RLC", Bundle.getMessage("csvRouteLocationComment"), comment, textColorName); // NOI18N
065    }
066
067    protected final void printTrainDeparts(CSVPrinter printer, String name, String direction) throws IOException {
068        printer.printRecord("TD", Bundle.getMessage("csvTrainDeparts"), name, direction); // NOI18N
069    }
070
071    protected final void printTrainDescription(CSVPrinter printer, String description) throws IOException {
072        printer.printRecord("TM", Bundle.getMessage("csvTrainManifestDescription"), description); // NOI18N
073    }
074
075    protected final void printTrainLength(CSVPrinter printer, int length, int empty, int total) throws IOException {
076        printer.printRecord("TL", Bundle.getMessage("csvTrainLengthEmptiesCars"), length, empty, total); // NOI18N
077    }
078
079    protected final void printTrainName(CSVPrinter printer, String name) throws IOException {
080        printer.printRecord("TN", Bundle.getMessage("csvTrainName"), name); // NOI18N
081    }
082
083    protected final void printTrainTerminates(CSVPrinter printer, String name) throws IOException {
084        printer.printRecord("TT", Bundle.getMessage("csvTrainTerminates"), name);
085    }
086
087    protected final void printTrainWeight(CSVPrinter printer, int weight) throws IOException {
088        printer.printRecord("TW", Bundle.getMessage("csvTrainWeight"), weight); // NOI18N
089    }
090
091    protected final void printValidity(CSVPrinter printer, String date) throws IOException {
092        printer.printRecord("VT", Bundle.getMessage("csvValid"), date); // NOI18N
093    }
094
095    protected final void printLocationSwitchListComment(CSVPrinter fileOut, Location location) throws IOException {
096        String textColorName = TrainCommon.getTextColorName(location.getSwitchListCommentWithColor());
097        // comment can have multiple lines
098        String[] comments = location.getSwitchListComment().split(NEW_LINE); // NOI18N
099        for (String comment : comments) {
100            printLocationSwitchListComment(fileOut, comment, textColorName);
101        }
102    }
103
104    protected final void printLocationComment(CSVPrinter fileOut, Location location) throws IOException {
105        if (!location.getComment().equals(Location.NONE)) {
106            String textColorName = TrainCommon.getTextColorName(location.getCommentWithColor());
107            // comment can have multiple lines
108            String[] comments = location.getComment().split(NEW_LINE); // NOI18N
109            for (String comment : comments) {
110                printLocationComment(fileOut, comment, textColorName);
111            }
112        }
113    }
114
115    protected final void printRouteLocationComment(CSVPrinter fileOut, RouteLocation rl) throws IOException {
116        if (!rl.getComment().equals(RouteLocation.NONE)) {
117            String textColorName = rl.getCommentTextColor();
118            // comment can have multiple lines
119            String[] comments = rl.getComment().split(NEW_LINE); // NOI18N
120            for (String comment : comments) {
121                printRouteLocationComment(fileOut, comment, textColorName);
122            }
123        }
124    }
125
126    protected final void printTrainComment(CSVPrinter fileOut, Train train) throws IOException {
127        if (!train.getComment().equals(Train.NONE)) {
128            String textColorName = TrainCommon.getTextColorName(train.getCommentWithColor());
129            String[] comments = train.getComment().split(NEW_LINE);
130            for (String comment : comments) {
131                fileOut.printRecord("TC", Bundle.getMessage("csvTrainComment"), comment, textColorName); // NOI18N
132            }
133        }
134    }
135
136    protected final void printRouteComment(CSVPrinter fileOut, Train train) throws IOException {
137        fileOut.printRecord("RC", Bundle.getMessage("csvRouteComment"), train.getRoute().getComment()); // NOI18N
138    }
139
140    protected void printLogoURL(CSVPrinter fileOut, Train train) throws IOException {
141        String logoURL = FileUtil.getExternalFilename(Setup.getManifestLogoURL());
142        if (!train.getManifestLogoPathName().equals(Train.NONE)) {
143            logoURL = FileUtil.getExternalFilename(train.getManifestLogoPathName());
144        }
145        if (!logoURL.isEmpty()) {
146            fileOut.printRecord("LOGO", Bundle.getMessage("csvLogoFilePath"), logoURL);
147        }
148    }
149
150    protected void printCar(CSVPrinter fileOut, Car car, String code, String message, int count) throws IOException {
151        fileOut.printRecord(code,
152                message,
153                car.getRoadName(),
154                car.getNumber(),
155                car.getTypeName(),
156                car.getLength(),
157                car.getLoadName(),
158                car.getColor(),
159                car.getLocationName(),
160                car.getTrackName(),
161                car.getDestinationName(),
162                car.getDestinationTrackName(),
163                car.getOwnerName(),
164                car.getKernelName(),
165                car.getComment(),
166                car.getPickupComment(),
167                car.getDropComment(),
168                car.isCaboose() ? "C" : "",
169                car.hasFred() ? "F" : "",
170                car.isHazardous() ? "H" : "",
171                car.getRfid(),
172                car.getReturnWhenEmptyDestinationName(),
173                car.getReturnWhenEmptyDestTrackName(),
174                car.isUtility() ? "U" : "",
175                count,
176                car.getFinalDestinationName(),
177                car.getFinalDestinationTrackName(),
178                car.getLoadType(),
179                car.getReturnWhenLoadedDestinationName(),
180                car.getReturnWhenLoadedDestTrackName(),
181                car.getRoutePath(),
182                car.getDivisionName());
183    }
184
185    protected void printEngine(CSVPrinter fileOut, Engine engine, String code, String message) throws IOException {
186        fileOut.printRecord(code,
187                message,
188                engine.getRoadName(),
189                engine.getNumber(),
190                engine.getModel(),
191                engine.getLength(),
192                engine.getTypeName(),
193                engine.getHp(),
194                engine.getLocationName(),
195                engine.getTrackName(),
196                engine.getDestinationName(),
197                engine.getDestinationTrackName(),
198                engine.getOwnerName(),
199                engine.getConsistName(),
200                engine.isLead() ? "Lead loco" : "", // NOI18N
201                engine.getComment(),
202                engine.getRfid(),
203                engine.getDccAddress());
204    }
205
206    protected final void checkForEngineOrCabooseChange(CSVPrinter fileOut, Train train, RouteLocation rl)
207            throws IOException {
208        if (train.getSecondLegOptions() != Train.NO_CABOOSE_OR_FRED) {
209            if (rl == train.getSecondLegStartRouteLocation()) {
210                engineCsvChange(fileOut, rl, train.getSecondLegOptions());
211            }
212            if (rl == train.getSecondLegEndRouteLocation()) {
213                printRemoveHelpers(fileOut);
214            }
215        }
216        if (train.getThirdLegOptions() != Train.NO_CABOOSE_OR_FRED) {
217            if (rl == train.getThirdLegStartRouteLocation()) {
218                engineCsvChange(fileOut, rl, train.getThirdLegOptions());
219            }
220            if (rl == train.getThirdLegEndRouteLocation()) {
221                printRemoveHelpers(fileOut);
222            }
223        }
224    }
225
226    protected void engineCsvChange(CSVPrinter fileOut, RouteLocation rl, int legOptions) throws IOException {
227        if ((legOptions & Train.HELPER_ENGINES) == Train.HELPER_ENGINES) {
228            fileOut.printRecord("AH", Bundle.getMessage("csvAddHelpers"));
229        }
230        if ((legOptions & Train.REMOVE_CABOOSE) == Train.REMOVE_CABOOSE ||
231                (legOptions & Train.ADD_CABOOSE) == Train.ADD_CABOOSE) {
232            fileOut.printRecord("CC", Bundle.getMessage("csvChangeCaboose"));
233        }
234        if ((legOptions & Train.CHANGE_ENGINES) == Train.CHANGE_ENGINES) {
235            fileOut.printRecord("CL", Bundle.getMessage("csvChangeLocos"));
236        }
237    }
238
239    protected void printTrackComments(CSVPrinter fileOut, RouteLocation rl, List<Car> carList) throws IOException {
240        Location location = rl.getLocation();
241        if (location != null) {
242            List<Track> tracks = location.getTracksByNameList(null);
243            for (Track track : tracks) {
244                // any pick ups or set outs to this track?
245                boolean pickup = false;
246                boolean setout = false;
247                for (Car car : carList) {
248                    if (car.getRouteLocation() == rl && car.getTrack() != null && car.getTrack() == track) {
249                        pickup = true;
250                    }
251                    if (car.getRouteDestination() == rl &&
252                            car.getDestinationTrack() != null &&
253                            car.getDestinationTrack() == track) {
254                        setout = true;
255                    }
256                }
257                // print the appropriate comment if there's one
258                // each comment can have multiple lines
259                if (pickup && setout && !track.getCommentBoth().equals(Track.NONE)) {
260                    String textColorName = TrainCommon.getTextColorName(track.getCommentBothWithColor());
261                    String[] comments = track.getCommentBoth().split(NEW_LINE);
262                    for (String comment : comments) {
263                        fileOut.printRecord("TKCB", Bundle.getMessage("csvTrackCommentBoth"), comment, textColorName); // NOI18N
264                    }
265                } else if (pickup && !setout && !track.getCommentPickup().equals(Track.NONE)) {
266                    String textColorName = TrainCommon.getTextColorName(track.getCommentPickupWithColor());
267                    String[] comments = track.getCommentPickup().split(NEW_LINE);
268                    for (String comment : comments) {
269                        fileOut.printRecord("TKCP", Bundle.getMessage("csvTrackCommentPickUp"), comment, textColorName); // NOI18N
270                    }
271                } else if (!pickup && setout && !track.getCommentSetout().equals(Track.NONE)) {
272                    String textColorName = TrainCommon.getTextColorName(track.getCommentSetoutWithColor());
273                    String[] comments = track.getCommentSetout().split(NEW_LINE);
274                    for (String comment : comments) {
275                        fileOut.printRecord("TKCS", Bundle.getMessage("csvTrackCommentSetOut"), comment, textColorName); // NOI18N
276                    }
277                }
278            }
279        }
280    }
281
282    protected void listCarsLocationUnknown(CSVPrinter fileOut) throws IOException {
283        List<Car> cars = InstanceManager.getDefault(CarManager.class).getCarsLocationUnknown();
284        if (cars.isEmpty()) {
285            return; // no cars to search for!
286        }
287        fileOut.printRecord("SMCM", Bundle.getMessage("csvSearchMiaMessage"), Setup.getMiaComment());
288        for (Car car : cars) {
289            printCar(fileOut, car, "SMC", Bundle.getMessage("csvSearchMissingCar"), 0);
290        }
291    }
292}