001package jmri.jmrit.operations.setup;
002
003import java.awt.Color;
004import java.awt.JobAttributes.SidesType;
005import java.io.IOException;
006import java.util.*;
007
008import javax.print.attribute.standard.Sides;
009import javax.swing.JComboBox;
010
011import org.jdom2.Element;
012import org.slf4j.Logger;
013import org.slf4j.LoggerFactory;
014
015import jmri.*;
016import jmri.beans.PropertyChangeSupport;
017import jmri.jmris.AbstractOperationsServer;
018import jmri.jmrit.operations.OperationsPanel;
019import jmri.jmrit.operations.rollingstock.RollingStockLogger;
020import jmri.jmrit.operations.setup.backup.AutoBackup;
021import jmri.jmrit.operations.setup.backup.AutoSave;
022import jmri.jmrit.operations.trains.TrainLogger;
023import jmri.jmrit.operations.trains.TrainManagerXml;
024import jmri.util.ColorUtil;
025import jmri.util.swing.JmriColorChooser;
026import jmri.web.server.WebServerPreferences;
027
028/**
029 * Operations settings.
030 *
031 * @author Daniel Boudreau Copyright (C) 2008, 2010, 2012, 2014, 2025
032 */
033public class Setup extends PropertyChangeSupport implements InstanceManagerAutoDefault, Disposable {
034
035    public static final String NONE = "";
036
037    // scale ratios from NMRA
038    public static final int Z_RATIO = 220;
039    public static final int N_RATIO = 160;
040    public static final int TT_RATIO = 120;
041    public static final int OO_RATIO = 76; // actual ratio 76.2
042    public static final int HO_RATIO = 87;
043    public static final int S_RATIO = 64;
044    public static final int O_RATIO = 48;
045    public static final int Gauge1_RATIO = 32; // NMRA #1
046    public static final int G_24_RATIO = 24;
047
048    // initial weight in milli ounces from NMRA
049    private static final int Z_INITIAL_WEIGHT = 364; // not specified by NMRA
050    private static final int N_INITIAL_WEIGHT = 500;
051    private static final int TT_INITIAL_WEIGHT = 750;
052    private static final int HOn3_INITIAL_WEIGHT = 750;
053    private static final int OO_INITIAL_WEIGHT = 750; // not specified by NMRA
054    private static final int HO_INITIAL_WEIGHT = 1000;
055    private static final int Sn3_INITIAL_WEIGHT = 1000;
056    private static final int S_INITIAL_WEIGHT = 2000;
057    private static final int On3_INITIAL_WEIGHT = 1500;
058    private static final int O_INITIAL_WEIGHT = 5000;
059    private static final int G_INITIAL_WEIGHT = 10000; // not specified by NMRA
060
061    // additional weight in milli ounces from NMRA
062    private static final int Z_ADD_WEIGHT = 100; // not specified by NMRA
063    private static final int N_ADD_WEIGHT = 150;
064    private static final int TT_ADD_WEIGHT = 375;
065    private static final int HOn3_ADD_WEIGHT = 375;
066    private static final int OO_ADD_WEIGHT = 500; // not specified by NMRA
067    private static final int HO_ADD_WEIGHT = 500;
068    private static final int Sn3_ADD_WEIGHT = 500;
069    private static final int S_ADD_WEIGHT = 500;
070    private static final int On3_ADD_WEIGHT = 750;
071    private static final int O_ADD_WEIGHT = 1000;
072    private static final int G_ADD_WEIGHT = 2000; // not specified by NMRA
073
074    // actual weight to tons conversion ratios (based on 40' boxcar at ~80 tons)
075    private static final int Z_RATIO_TONS = 130;
076    private static final int N_RATIO_TONS = 80;
077    private static final int TT_RATIO_TONS = 36;
078    private static final int HOn3_RATIO_TONS = 20;
079    private static final int OO_RATIO_TONS = 20;
080    private static final int HO_RATIO_TONS = 20; // 20 tons per ounce
081    private static final int Sn3_RATIO_TONS = 16;
082    private static final int S_RATIO_TONS = 14;
083    private static final int On3_RATIO_TONS = 8;
084    private static final int O_RATIO_TONS = 5;
085    private static final int G_RATIO_TONS = 2;
086
087    public static final int Z_SCALE = 1;
088    public static final int N_SCALE = 2;
089    public static final int TT_SCALE = 3;
090    public static final int HOn3_SCALE = 4;
091    public static final int OO_SCALE = 5;
092    public static final int HO_SCALE = 6;
093    public static final int Sn3_SCALE = 7;
094    public static final int S_SCALE = 8;
095    public static final int On3_SCALE = 9;
096    public static final int O_SCALE = 10;
097    public static final int Gauge1_SCALE = 11; // NMRA #1
098    public static final int G_24_SCALE = 12;
099
100    public static final int EAST = 1; // train direction serviced by this location
101    public static final int WEST = 2;
102    public static final int NORTH = 4;
103    public static final int SOUTH = 8;
104
105    public static final String EAST_DIR = Bundle.getMessage("East");
106    public static final String WEST_DIR = Bundle.getMessage("West");
107    public static final String NORTH_DIR = Bundle.getMessage("North");
108    public static final String SOUTH_DIR = Bundle.getMessage("South");
109
110    public static final String DESCRIPTIVE = Bundle.getMessage("Descriptive"); // Car types
111    public static final String AAR = Bundle.getMessage("ArrCodes"); // Car types
112
113    public static final String MONOSPACED = Bundle.getMessage("Monospaced"); // default printer font
114
115    public static final String STANDARD_FORMAT = Bundle.getMessage("StandardFormat");
116    public static final String TWO_COLUMN_FORMAT = Bundle.getMessage("TwoColumnFormat");
117    public static final String TWO_COLUMN_TRACK_FORMAT = Bundle.getMessage("TwoColumnTrackFormat");
118
119    public static final String PORTRAIT = Bundle.getMessage("Portrait");
120    public static final String LANDSCAPE = Bundle.getMessage("Landscape");
121    public static final String HALFPAGE = Bundle.getMessage("HalfPage");
122    public static final String HANDHELD = Bundle.getMessage("HandHeld");
123    public static final String RECEIPT = Bundle.getMessage("Receipt");
124
125    public static final String PAGE_NORMAL = Bundle.getMessage("PageNormal");
126    public static final String PAGE_PER_TRAIN = Bundle.getMessage("PagePerTrain");
127    public static final String PAGE_PER_VISIT = Bundle.getMessage("PagePerVisit");
128
129    public static final String BUILD_REPORT_MINIMAL = "1";
130    public static final String BUILD_REPORT_NORMAL = "3";
131    public static final String BUILD_REPORT_DETAILED = "5";
132    public static final String BUILD_REPORT_VERY_DETAILED = "7";
133
134    // the following are converted to English spelling when storing to file, see KEYS below
135    public static final String ROAD = Bundle.getMessage("Road"); // the supported message format options
136    public static final String NUMBER = Bundle.getMessage("Number");
137    public static final String TYPE = Bundle.getMessage("Type");
138    public static final String MODEL = Bundle.getMessage("Model");
139    public static final String LENGTH = Bundle.getMessage("Length");
140    public static final String WEIGHT = Bundle.getMessage("Weight");
141    public static final String HP = Bundle.getMessage("HP");
142    public static final String LOAD = Bundle.getMessage("Load");
143    public static final String LOAD_TYPE = Bundle.getMessage("Load_Type");
144    public static final String COLOR = Bundle.getMessage("Color");
145    public static final String TRACK = Bundle.getMessage("Track");
146    public static final String DESTINATION = Bundle.getMessage("Destination");
147    public static final String DEST_TRACK = Bundle.getMessage("Dest&Track");
148    public static final String FINAL_DEST = Bundle.getMessage("Final_Dest");
149    public static final String FINAL_DEST_TRACK = Bundle.getMessage("FD&Track");
150    public static final String LOCATION = Bundle.getMessage("Location");
151    public static final String CONSIST = Bundle.getMessage("Consist");
152    public static final String DCC_ADDRESS = Bundle.getMessage("DCC_Address");
153    public static final String KERNEL = Bundle.getMessage("Kernel");
154    public static final String KERNEL_SIZE = Bundle.getMessage("Kernel_Size");
155    public static final String OWNER = Bundle.getMessage("Owner");
156    public static final String DIVISION = Bundle.getMessage("Division");
157    public static final String BLOCKING_ORDER = Bundle.getMessage("Blocking_Order");
158    public static final String RWE = Bundle.getMessage("RWE");
159    public static final String COMMENT = Bundle.getMessage("Comment");
160    public static final String DROP_COMMENT = Bundle.getMessage("SetOut_Msg");
161    public static final String PICKUP_COMMENT = Bundle.getMessage("PickUp_Msg");
162    public static final String HAZARDOUS = Bundle.getMessage("Hazardous");
163    public static final String LAST_TRAIN = Bundle.getMessage("LastTrain");
164    public static final String BLANK = " "; // blank has be a character or a space
165    public static final String TAB = Bundle.getMessage("Tab"); // used to tab out in tabular mode
166    public static final String TAB2 = Bundle.getMessage("Tab2");
167    public static final String TAB3 = Bundle.getMessage("Tab3");
168    
169    public static final String BOX = " [ ] "; // NOI18N
170
171    // these are for the utility printing when using tabs
172    public static final String NO_ROAD = "NO_ROAD"; // NOI18N
173    public static final String NO_NUMBER = "NO_NUMBER"; // NOI18N
174    public static final String NO_COLOR = "NO_COLOR"; // NOI18N
175
176    // truncated manifests
177    public static final String NO_DESTINATION = "NO_DESTINATION"; // NOI18N
178    public static final String NO_DEST_TRACK = "NO_DEST_TRACK"; // NOI18N
179    public static final String NO_LOCATION = "NO_LOCATION"; // NOI18N
180    public static final String NO_TRACK = "NO_TRACK"; // NOI18N
181
182    // Unit of Length
183    public static final String FEET = Bundle.getMessage("Feet");
184    public static final String METER = Bundle.getMessage("Meter");
185    public static final String FEET_ABV = Bundle.getMessage("FeetAbbreviation");
186    public static final String METER_ABV = Bundle.getMessage("MeterAbbreviation");
187
188    private static final String[] CAR_ATTRIBUTES = { ROAD, NUMBER, TYPE, LENGTH, WEIGHT, LOAD, LOAD_TYPE, HAZARDOUS,
189            COLOR, KERNEL, KERNEL_SIZE, OWNER, DIVISION, TRACK, LOCATION, DESTINATION, DEST_TRACK, FINAL_DEST, FINAL_DEST_TRACK,
190            BLOCKING_ORDER, COMMENT, DROP_COMMENT, PICKUP_COMMENT, RWE, LAST_TRAIN};
191    
192    private static final String[] ENGINE_ATTRIBUTES = {ROAD, NUMBER, TYPE, MODEL, LENGTH, WEIGHT, HP, CONSIST, OWNER,
193            TRACK, LOCATION, DESTINATION, COMMENT, DCC_ADDRESS, LAST_TRAIN};
194    /*
195     * The print Manifest and switch list user selectable options are stored in the
196     * xml file using the English translations.
197     */
198    private static final String[] KEYS = {"Road", "Number", "Type", "Model", "Length", "Weight", "Load", "Load_Type",
199            "HP", "Color", "Track", "Destination", "Dest&Track", "Final_Dest", "FD&Track", "Location", "Consist",
200            "DCC_Address", "Kernel", "Kernel_Size", "Owner", "Division", "Blocking_Order", "RWE", "Comment",
201            "SetOut_Msg", "PickUp_Msg", "Hazardous", "LastTrain", "Tab", "Tab2", "Tab3"};
202
203    private int scale = HO_SCALE; // Default scale
204    private int ratio = HO_RATIO;
205    private int ratioTons = HO_RATIO_TONS;
206    private int initWeight = HO_INITIAL_WEIGHT;
207    private int addWeight = HO_ADD_WEIGHT;
208    private String railroadName = NONE;
209    private int traindir = EAST + WEST + NORTH + SOUTH;
210    private int maxTrainLength = 1000; // maximum train length
211    private int maxEngineSize = 6; // maximum number of engines that can be assigned to a train
212    private double horsePowerPerTon = 1; // Horsepower per ton
213    private int carMoves = 5; // default number of moves when creating a route
214    private String carTypes = DESCRIPTIVE;
215    private String ownerName = NONE;
216    private String fontName = MONOSPACED;
217    private int manifestFontSize = 10;
218    private int buildReportFontSize = 10;
219    private String manifestOrientation = PORTRAIT;
220    private String switchListOrientation = PORTRAIT;
221    private Sides sides = Sides.ONE_SIDED;
222    private boolean printHeader = true;
223    private Color pickupEngineColor = Color.black;
224    private Color dropEngineColor = Color.black;
225    private Color pickupColor = Color.black;
226    private Color dropColor = Color.black;
227    private Color localColor = Color.black;
228    private String[] pickupEngineMessageFormat = { ROAD, NUMBER, BLANK, MODEL, BLANK, BLANK, LOCATION, COMMENT };
229    private String[] dropEngineMessageFormat = { ROAD, NUMBER, BLANK, MODEL, BLANK, BLANK, DESTINATION, COMMENT };
230    private String[] pickupManifestMessageFormat = { ROAD, NUMBER, TYPE, LENGTH, COLOR, LOAD, HAZARDOUS, LOCATION,
231            COMMENT, PICKUP_COMMENT };
232    private String[] dropManifestMessageFormat = { ROAD, NUMBER, TYPE, LENGTH, COLOR, LOAD, HAZARDOUS, DESTINATION,
233            COMMENT, DROP_COMMENT };
234    private String[] localManifestMessageFormat = { ROAD, NUMBER, TYPE, LENGTH, COLOR, LOAD, HAZARDOUS, LOCATION,
235            DESTINATION, COMMENT };
236    private String[] pickupSwitchListMessageFormat = { ROAD, NUMBER, TYPE, LENGTH, COLOR, LOAD, HAZARDOUS, LOCATION,
237            COMMENT, PICKUP_COMMENT };
238    private String[] dropSwitchListMessageFormat = { ROAD, NUMBER, TYPE, LENGTH, COLOR, LOAD, HAZARDOUS, DESTINATION,
239            COMMENT, DROP_COMMENT };
240    private String[] localSwitchListMessageFormat = { ROAD, NUMBER, TYPE, LENGTH, COLOR, LOAD, HAZARDOUS, LOCATION,
241            DESTINATION, COMMENT };
242    private String[] missingCarMessageFormat = { ROAD, NUMBER, TYPE, LENGTH, COLOR, COMMENT };
243    private String pickupEnginePrefix = BOX + Bundle.getMessage("PickUpPrefix");
244    private String dropEnginePrefix = BOX + Bundle.getMessage("SetOutPrefix");
245    private String pickupCarPrefix = BOX + Bundle.getMessage("PickUpPrefix");
246    private String dropCarPrefix = BOX + Bundle.getMessage("SetOutPrefix");
247    private String localPrefix = BOX + Bundle.getMessage("LocalCarPrefix");
248    private String switchListPickupCarPrefix = BOX + Bundle.getMessage("PickUpPrefix");
249    private String switchListDropCarPrefix = BOX + Bundle.getMessage("SetOutPrefix");
250    private String switchListLocalPrefix = BOX + Bundle.getMessage("LocalCarPrefix");
251    private String miaComment = Bundle.getMessage("misplacedCars");
252    private String hazardousMsg = "(" + Bundle.getMessage("Hazardous") + ")";
253    private String logoURL = NONE;
254    private String panelName = "Panel"; // NOI18N
255    private String buildReportLevel = BUILD_REPORT_VERY_DETAILED;
256    private String routerBuildReportLevel = BUILD_REPORT_NORMAL;
257    private int carSwitchTime = 3; // how long it takes to move a car in minutes
258    private int travelTime = 4; // how long it takes a train to move from one location to another in minutes
259    private String yearModeled = NONE; // year being modeled
260    private String lengthUnit = FEET;
261    private String lengthUnitAbv = FEET_ABV;
262    private String iconNorthColor = NONE;
263    private String iconSouthColor = NONE;
264    private String iconEastColor = NONE;
265    private String iconWestColor = NONE;
266    private String iconLocalColor = NONE;
267    private String iconTerminateColor = NONE;
268
269    private boolean tab = false; // when true, tab out manifest and switch lists
270    private int tab1CharLength = Control.max_len_string_attibute;
271    private int tab2CharLength = 6; // arbitrary lengths
272    private int tab3CharLength = 8;
273
274    private String manifestFormat = STANDARD_FORMAT;
275    private boolean manifestEditorEnabled = false; // when true use text editor to view build report
276    private boolean switchListSameManifest = true; // when true switch list format is the same as the manifest
277    private boolean manifestTruncated = false; // when true, manifest is truncated if switch list is available
278    private boolean manifestDepartureTime = false; // when true, manifest shows train's departure time
279    private boolean switchListDepartureTime = false; // when true, switch list shows train's departure time
280    private boolean switchListRouteComment = true; // when true, switch list have route location comments
281    private boolean trackSummary = true; // when true, print switch list track summary
282    private boolean groupCarMoves = false; // when true, car moves are grouped together
283    private boolean locoLast = false; // when true, loco set outs printed last
284
285    private boolean switchListRealTime = true; // when true switch list only show work for built trains
286    private boolean switchListAllTrains = true; // when true show all trains that visit the location
287    private String switchListPageFormat = PAGE_NORMAL; // how switch lists pages are printed
288
289    private boolean buildReportEditorEnabled = false; // when true use text editor to view build report
290    private boolean buildReportIndentEnabled = true; // when true use text editor to view build report
291    private boolean buildReportAlwaysPreviewEnabled = false; // when true use text editor to view build report
292
293    private boolean enableTrainIconXY = true;
294    private boolean appendTrainIcon = false; // when true, append engine number to train name
295    private String setupComment = NONE;
296
297    private boolean mainMenuEnabled = false; // when true add operations menu to main menu bar
298    private boolean closeWindowOnSave = false; // when true, close window when save button is activated
299    private boolean autoSave = true; // when true, automatically save files if modified
300    private boolean autoBackup = true; // when true, automatically backup files
301    private boolean enableValue = false; // when true show value fields for rolling stock
302    private String labelValue = Bundle.getMessage("Value");
303    private boolean enableRfid = false; // when true show RFID fields for rolling stock
304    private String labelRfid = Bundle.getMessage("RFID");
305
306    private boolean carRoutingEnabled = true; // when true enable car routing
307    private boolean carRoutingYards = false; // when true enable car routing via yard tracks
308    private boolean carRoutingStaging = false; // when true staging tracks can be used for car routing
309    private boolean forwardToYardEnabled = true; // when true forward car to yard if track is full
310    private boolean onlyActiveTrains = false; // when true only active trains are used for routing
311    private boolean checkCarDestination = false; // when true check car's track for valid destination
312
313    private boolean carLogger = false; // when true car logger is enabled
314    private boolean engineLogger = false; // when true engine logger is enabled
315    private boolean trainLogger = false; // when true train logger is enabled
316    private boolean saveTrainManifests = false; // when true save previous train manifest
317
318    private boolean aggressiveBuild = false; // when true subtract car length from track reserve length
319    private int numberPasses = 2; // the number of passes in train builder
320    private boolean onTimeBuild = false;    // when true on time mode
321    private int dwellTime = 60; // time in minutes before allowing track reuse
322    private boolean allowLocalInterchangeMoves = false; // when true local C/I to C/I moves are allowed
323    private boolean allowLocalYardMoves = false; // when true local yard to yard moves are allowed
324    private boolean allowLocalSpurMoves = false; // when true local spur to spur moves are allowed
325
326    private boolean trainIntoStagingCheck = true; // staging track must accept train's rolling stock types and roads
327    private boolean trackImmediatelyAvail = false; // when true staging track is available for other trains
328    private boolean allowCarsReturnStaging = false; // allow cars on a turn to return to staging if necessary (prevent
329                                                    // build failure)
330    private boolean promptFromStaging = false; // prompt user to specify which departure staging track to use
331    private boolean promptToStaging = false; // prompt user to specify which arrival staging track to use
332    private boolean tryNormalModeStaging = true; // try normal build if route length failure using aggressive
333
334    private boolean generateCsvManifest = false; // when true generate csv manifest
335    private boolean generateCsvSwitchList = false; // when true generate csv switch list
336    private boolean enableVsdPhysicalLocations = false;
337
338    private boolean printLocationComments = false; // when true print location comments on the manifest
339    private boolean printRouteComments = false; // when true print route comments on the manifest
340    private boolean printLoadsAndEmpties = false; // when true print Loads and Empties on the manifest
341    private boolean printTrainScheduleName = false; // when true print train schedule name on manifests and switch lists
342    private boolean use12hrFormat = false; // when true use 12hr rather than 24hr format
343    private boolean printValid = true; // when true print out the valid time and date
344    private boolean sortByTrack = false; // when true manifest work is sorted by track names
345    private boolean printHeaders = false; // when true add headers to manifest and switch lists
346    private boolean printNoPageBreaks = true; // when true no page breaks for a location's work
347    private boolean printHeaderLine1 = true; // when true add header line 1 to manifest and switch lists
348    private boolean printHeaderLine2 = true; // when true add header line 2 to manifest and switch lists
349    private boolean printHeaderLine3 = true; // when true add header line 3 to manifest and switch lists
350
351    private boolean printCabooseLoad = false; // when true print caboose load
352    private boolean printPassengerLoad = false; // when true print passenger car load
353    private boolean showTrackMoves = false; // when true show track moves in table
354    
355    private Hashtable<String, String> hashTableDayToName = new Hashtable<>();
356
357    // property changes
358    public static final String SWITCH_LIST_CSV_PROPERTY_CHANGE = "setupSwitchListCSVChange"; // NOI18N
359    public static final String MANIFEST_CSV_PROPERTY_CHANGE = "setupManifestCSVChange"; // NOI18N
360    public static final String REAL_TIME_PROPERTY_CHANGE = "setupSwitchListRealTime"; // NOI18N
361    public static final String SHOW_TRACK_MOVES_PROPERTY_CHANGE = "setupShowTrackMoves"; // NOI18N
362    public static final String SAVE_TRAIN_MANIFEST_PROPERTY_CHANGE = "saveTrainManifestChange"; // NOI18N
363    public static final String ALLOW_CARS_TO_RETURN_PROPERTY_CHANGE = "allowCarsToReturnChange"; // NOI18N
364    public static final String TRAIN_DIRECTION_PROPERTY_CHANGE = "setupTrainDirectionChange"; // NOI18N
365    public static final String ROUTING_STAGING_PROPERTY_CHANGE = "setupRoutingStagingChange"; // NOI18N
366    public static final String TRAVEL_TIME_PROPERTY_CHANGE = "setupTravelTimeChange"; // NOI18N
367
368    public static boolean isMainMenuEnabled() {
369        InstanceManager.getDefault(OperationsSetupXml.class); // load file
370        return getDefault().mainMenuEnabled;
371    }
372
373    public static void setMainMenuEnabled(boolean enabled) {
374        getDefault().mainMenuEnabled = enabled;
375    }
376
377    public static boolean isCloseWindowOnSaveEnabled() {
378        return getDefault().closeWindowOnSave;
379    }
380
381    public static void setCloseWindowOnSaveEnabled(boolean enabled) {
382        getDefault().closeWindowOnSave = enabled;
383    }
384
385    public static boolean isAutoSaveEnabled() {
386        return getDefault().autoSave;
387    }
388
389    public static void setAutoSaveEnabled(boolean enabled) {
390        getDefault().autoSave = enabled;
391        if (enabled) {
392            AutoSave.start();
393        } else {
394            AutoSave.stop();
395        }
396    }
397
398    public static boolean isAutoBackupEnabled() {
399        return getDefault().autoBackup;
400    }
401
402    public static void setAutoBackupEnabled(boolean enabled) {
403        // Do an autoBackup only if we are changing the setting from false to
404        // true.
405        if (enabled && !getDefault().autoBackup) {
406            try {
407                InstanceManager.getDefault(AutoBackup.class).autoBackup();
408            } catch (IOException ex) {
409                log.debug("Autobackup after setting AutoBackup flag true", ex);
410            }
411        }
412
413        getDefault().autoBackup = enabled;
414    }
415
416    public static boolean isValueEnabled() {
417        return getDefault().enableValue;
418    }
419
420    public static void setValueEnabled(boolean enabled) {
421        getDefault().enableValue = enabled;
422    }
423
424    public static String getValueLabel() {
425        return getDefault().labelValue;
426    }
427
428    public static void setValueLabel(String label) {
429        getDefault().labelValue = label;
430    }
431
432    public static boolean isRfidEnabled() {
433        return getDefault().enableRfid;
434    }
435
436    public static void setRfidEnabled(boolean enabled) {
437        getDefault().enableRfid = enabled;
438    }
439
440    public static String getRfidLabel() {
441        return getDefault().labelRfid;
442    }
443
444    public static void setRfidLabel(String label) {
445        getDefault().labelRfid = label;
446    }
447
448    public static boolean isCarRoutingEnabled() {
449        return getDefault().carRoutingEnabled;
450    }
451
452    public static void setCarRoutingEnabled(boolean enabled) {
453        getDefault().carRoutingEnabled = enabled;
454    }
455
456    public static boolean isCarRoutingViaYardsEnabled() {
457        return getDefault().carRoutingYards;
458    }
459
460    public static void setCarRoutingViaYardsEnabled(boolean enabled) {
461        getDefault().carRoutingYards = enabled;
462    }
463
464    public static boolean isCarRoutingViaStagingEnabled() {
465        return getDefault().carRoutingStaging;
466    }
467
468    public static void setCarRoutingViaStagingEnabled(boolean enabled) {
469        boolean old = isCarRoutingViaStagingEnabled();
470        getDefault().carRoutingStaging = enabled;
471        setDirtyAndFirePropertyChange(ROUTING_STAGING_PROPERTY_CHANGE, old, enabled);
472    }
473
474    public static boolean isForwardToYardEnabled() {
475        return getDefault().forwardToYardEnabled;
476    }
477
478    public static void setForwardToYardEnabled(boolean enabled) {
479        getDefault().forwardToYardEnabled = enabled;
480    }
481
482    public static boolean isOnlyActiveTrainsEnabled() {
483        return getDefault().onlyActiveTrains;
484    }
485
486    public static void setOnlyActiveTrainsEnabled(boolean enabled) {
487        getDefault().onlyActiveTrains = enabled;
488    }
489
490    /**
491     * When true, router checks that the car's destination is serviced by departure
492     * track. Very restrictive, not recommended.
493     * 
494     * @return true if enabled.
495     */
496    public static boolean isCheckCarDestinationEnabled() {
497        return getDefault().checkCarDestination;
498    }
499
500    public static void setCheckCarDestinationEnabled(boolean enabled) {
501        getDefault().checkCarDestination = enabled;
502    }
503
504    public static boolean isBuildAggressive() {
505        return getDefault().aggressiveBuild;
506    }
507
508    public static void setBuildAggressive(boolean enabled) {
509        getDefault().aggressiveBuild = enabled;
510    }
511
512    public static int getNumberPasses() {
513        return getDefault().numberPasses;
514    }
515
516    public static void setNumberPasses(int number) {
517        getDefault().numberPasses = number;
518    }
519    
520    public static boolean isBuildOnTime() {
521        return getDefault().onTimeBuild;
522    }
523
524    public static void setBuildOnTime(boolean enabled) {
525        getDefault().onTimeBuild = enabled;
526    }
527    
528    public static int getDwellTime() {
529        return getDefault().dwellTime;
530    }
531
532    public static void setDwellTime(int minutes) {
533        getDefault().dwellTime = minutes;
534    }
535
536    public static boolean isLocalInterchangeMovesEnabled() {
537        return getDefault().allowLocalInterchangeMoves;
538    }
539
540    public static void setLocalInterchangeMovesEnabled(boolean enabled) {
541        getDefault().allowLocalInterchangeMoves = enabled;
542    }
543
544    public static boolean isLocalYardMovesEnabled() {
545        return getDefault().allowLocalYardMoves;
546    }
547
548    public static void setLocalYardMovesEnabled(boolean enabled) {
549        getDefault().allowLocalYardMoves = enabled;
550    }
551
552    public static boolean isLocalSpurMovesEnabled() {
553        return getDefault().allowLocalSpurMoves;
554    }
555
556    public static void setLocalSpurMovesEnabled(boolean enabled) {
557        getDefault().allowLocalSpurMoves = enabled;
558    }
559
560    public static boolean isStagingTrainCheckEnabled() {
561        return getDefault().trainIntoStagingCheck;
562    }
563
564    /**
565     * Controls staging track selection, when true, the terminus staging track has
566     * to have the same characteristics as the train.
567     *
568     * @param enabled when true, the terminal staging track must service the same
569     *                car types, loads, etc. as the train
570     */
571    public static void setStagingTrainCheckEnabled(boolean enabled) {
572        getDefault().trainIntoStagingCheck = enabled;
573    }
574
575    public static boolean isStagingTrackImmediatelyAvail() {
576        return getDefault().trackImmediatelyAvail;
577    }
578
579    public static void setStagingTrackImmediatelyAvail(boolean enabled) {
580        getDefault().trackImmediatelyAvail = enabled;
581    }
582
583    /**
584     * allow cars to return to the same staging location if no other options
585     * (tracks) are available. Also available on a per train basis.
586     * 
587     * @return true if cars are allowed to depart and return to same staging
588     *         location
589     */
590    public static boolean isStagingAllowReturnEnabled() {
591        return getDefault().allowCarsReturnStaging;
592    }
593
594    public static void setStagingAllowReturnEnabled(boolean enabled) {
595        boolean old = getDefault().allowCarsReturnStaging;
596        getDefault().allowCarsReturnStaging = enabled;
597        setDirtyAndFirePropertyChange(ALLOW_CARS_TO_RETURN_PROPERTY_CHANGE, old, enabled);
598    }
599
600    public static boolean isStagingPromptFromEnabled() {
601        return getDefault().promptFromStaging;
602    }
603
604    public static void setStagingPromptFromEnabled(boolean enabled) {
605        getDefault().promptFromStaging = enabled;
606    }
607
608    public static boolean isStagingPromptToEnabled() {
609        return getDefault().promptToStaging;
610    }
611
612    public static void setStagingPromptToEnabled(boolean enabled) {
613        getDefault().promptToStaging = enabled;
614    }
615
616    public static boolean isStagingTryNormalBuildEnabled() {
617        return getDefault().tryNormalModeStaging;
618    }
619
620    public static void setStagingTryNormalBuildEnabled(boolean enabled) {
621        getDefault().tryNormalModeStaging = enabled;
622    }
623
624    public static boolean isGenerateCsvManifestEnabled() {
625        return getDefault().generateCsvManifest;
626    }
627
628    public static void setGenerateCsvManifestEnabled(boolean enabled) {
629        boolean old = getDefault().generateCsvManifest;
630        getDefault().generateCsvManifest = enabled;
631        if (enabled && !old) {
632            InstanceManager.getDefault(TrainManagerXml.class).createDefaultCsvManifestDirectory();
633        }
634        setDirtyAndFirePropertyChange(MANIFEST_CSV_PROPERTY_CHANGE, old, enabled);
635    }
636
637    public static boolean isGenerateCsvSwitchListEnabled() {
638        return getDefault().generateCsvSwitchList;
639    }
640
641    public static void setGenerateCsvSwitchListEnabled(boolean enabled) {
642        boolean old = getDefault().generateCsvSwitchList;
643        getDefault().generateCsvSwitchList = enabled;
644        if (enabled && !old) {
645            InstanceManager.getDefault(TrainManagerXml.class).createDefaultCsvSwitchListDirectory();
646        }
647        setDirtyAndFirePropertyChange(SWITCH_LIST_CSV_PROPERTY_CHANGE, old, enabled);
648    }
649
650    public static boolean isVsdPhysicalLocationEnabled() {
651        return getDefault().enableVsdPhysicalLocations;
652    }
653
654    public static void setVsdPhysicalLocationEnabled(boolean enabled) {
655        getDefault().enableVsdPhysicalLocations = enabled;
656    }
657
658    public static String getRailroadName() {
659        if (getDefault().railroadName.isEmpty()) {
660            return InstanceManager.getDefault(WebServerPreferences.class).getRailroadName();
661        }
662        return getDefault().railroadName;
663    }
664
665    public static void setRailroadName(String name) {
666        String old = getDefault().railroadName;
667        getDefault().railroadName = name;
668        if (old == null || !old.equals(name)) {
669            setDirtyAndFirePropertyChange("Railroad Name Change", old, name); // NOI18N
670        }
671    }
672
673    public static String getHazardousMsg() {
674        return getDefault().hazardousMsg;
675    }
676
677    public static void setHazardousMsg(String message) {
678        getDefault().hazardousMsg = message;
679    }
680
681    public static String getMiaComment() {
682        return getDefault().miaComment;
683    }
684
685    public static void setMiaComment(String comment) {
686        getDefault().miaComment = comment;
687    }
688
689    public static void setTrainDirection(int direction) {
690        int old = getDefault().traindir;
691        getDefault().traindir = direction;
692        if (old != direction) {
693            setDirtyAndFirePropertyChange(TRAIN_DIRECTION_PROPERTY_CHANGE, old, direction);
694        }
695    }
696
697    public static int getTrainDirection() {
698        return getDefault().traindir;
699    }
700
701    public static void setMaxTrainLength(int length) {
702        getDefault().maxTrainLength = length;
703    }
704
705    public static int getMaxTrainLength() {
706        return getDefault().maxTrainLength;
707    }
708
709    public static void setMaxNumberEngines(int value) {
710        getDefault().maxEngineSize = value;
711    }
712
713    public static int getMaxNumberEngines() {
714        return getDefault().maxEngineSize;
715    }
716
717    public static void setHorsePowerPerTon(double value) {
718        getDefault().horsePowerPerTon = value;
719    }
720
721    public static double getHorsePowerPerTon() {
722        return getDefault().horsePowerPerTon;
723    }
724
725    public static void setCarMoves(int moves) {
726        getDefault().carMoves = moves;
727    }
728
729    public static int getCarMoves() {
730        return getDefault().carMoves;
731    }
732
733    public static String getPanelName() {
734        return getDefault().panelName;
735    }
736
737    public static void setPanelName(String name) {
738        getDefault().panelName = name;
739    }
740
741    public static String getLengthUnit() {
742        return getDefault().lengthUnit;
743    }
744
745    /**
746     * Abbreviation unit of length
747     * 
748     * @return symbol for feet or meter
749     */
750    public static String getLengthUnitAbv() {
751        return getDefault().lengthUnitAbv;
752    }
753
754    public static void setLengthUnit(String unit) {
755        getDefault().lengthUnit = unit;
756        if (unit.equals(FEET)) {
757            getDefault().lengthUnitAbv = FEET_ABV;
758        } else {
759            getDefault().lengthUnitAbv = METER_ABV;
760        }
761    }
762
763    public static String getYearModeled() {
764        return getDefault().yearModeled;
765    }
766
767    public static void setYearModeled(String year) {
768        getDefault().yearModeled = year;
769    }
770
771    public static String getCarTypes() {
772        return getDefault().carTypes;
773    }
774
775    public static void setCarTypes(String types) {
776        getDefault().carTypes = types;
777    }
778
779    public static void setTrainIconCordEnabled(boolean enable) {
780        getDefault().enableTrainIconXY = enable;
781    }
782
783    public static boolean isTrainIconCordEnabled() {
784        return getDefault().enableTrainIconXY;
785    }
786
787    public static void setTrainIconAppendEnabled(boolean enable) {
788        getDefault().appendTrainIcon = enable;
789    }
790
791    public static boolean isTrainIconAppendEnabled() {
792        return getDefault().appendTrainIcon;
793    }
794
795    public static void setComment(String comment) {
796        getDefault().setupComment = comment;
797    }
798
799    public static String getComment() {
800        return getDefault().setupComment;
801    }
802
803    public static void setBuildReportLevel(String level) {
804        getDefault().buildReportLevel = level;
805    }
806
807    public static String getBuildReportLevel() {
808        return getDefault().buildReportLevel;
809    }
810
811    /**
812     * Sets the report level for the car router.
813     * 
814     * @param level BUILD_REPORT_NORMAL, BUILD_REPORT_DETAILED,
815     *              BUILD_REPORT_VERY_DETAILED
816     */
817    public static void setRouterBuildReportLevel(String level) {
818        getDefault().routerBuildReportLevel = level;
819    }
820
821    public static String getRouterBuildReportLevel() {
822        return getDefault().routerBuildReportLevel;
823    }
824
825    public static void setManifestEditorEnabled(boolean enable) {
826        getDefault().manifestEditorEnabled = enable;
827    }
828
829    public static boolean isManifestEditorEnabled() {
830        return getDefault().manifestEditorEnabled;
831    }
832
833    public static void setBuildReportEditorEnabled(boolean enable) {
834        getDefault().buildReportEditorEnabled = enable;
835    }
836
837    public static boolean isBuildReportEditorEnabled() {
838        return getDefault().buildReportEditorEnabled;
839    }
840
841    public static void setBuildReportIndentEnabled(boolean enable) {
842        getDefault().buildReportIndentEnabled = enable;
843    }
844
845    public static boolean isBuildReportIndentEnabled() {
846        return getDefault().buildReportIndentEnabled;
847    }
848
849    public static void setBuildReportAlwaysPreviewEnabled(boolean enable) {
850        getDefault().buildReportAlwaysPreviewEnabled = enable;
851    }
852
853    public static boolean isBuildReportAlwaysPreviewEnabled() {
854        return getDefault().buildReportAlwaysPreviewEnabled;
855    }
856
857    public static void setSwitchListFormatSameAsManifest(boolean b) {
858        getDefault().switchListSameManifest = b;
859    }
860
861    public static boolean isSwitchListFormatSameAsManifest() {
862        return getDefault().switchListSameManifest;
863    }
864
865    public static void setPrintTrackSummaryEnabled(boolean b) {
866        getDefault().trackSummary = b;
867    }
868
869    public static boolean isPrintTrackSummaryEnabled() {
870        return getDefault().trackSummary;
871    }
872
873    public static void setSwitchListRouteLocationCommentEnabled(boolean b) {
874        getDefault().switchListRouteComment = b;
875    }
876
877    public static boolean isSwitchListRouteLocationCommentEnabled() {
878        return getDefault().switchListRouteComment;
879    }
880
881    public static void setGroupCarMoves(boolean b) {
882        getDefault().groupCarMoves = b;
883    }
884
885    public static boolean isGroupCarMovesEnabled() {
886        return getDefault().groupCarMoves;
887    }
888
889    public static void setPrintLocoLast(boolean b) {
890        getDefault().locoLast = b;
891    }
892
893    public static boolean isPrintLocoLastEnabled() {
894        return getDefault().locoLast;
895    }
896
897    public static void setSwitchListRealTime(boolean b) {
898        boolean old = getDefault().switchListRealTime;
899        getDefault().switchListRealTime = b;
900        setDirtyAndFirePropertyChange(REAL_TIME_PROPERTY_CHANGE, old, b);
901    }
902
903    public static boolean isSwitchListRealTime() {
904        return getDefault().switchListRealTime;
905    }
906
907    public static void setSwitchListAllTrainsEnabled(boolean b) {
908        boolean old = getDefault().switchListAllTrains;
909        getDefault().switchListAllTrains = b;
910        setDirtyAndFirePropertyChange("Switch List All Trains", old, b); // NOI18N
911    }
912
913    /**
914     * When true switch list shows all trains visiting a location, even if the train
915     * doesn't have any work at that location. When false, switch lists only report
916     * a train if it has work at the location.
917     *
918     * @return When true show all trains visiting a location.
919     */
920    public static boolean isSwitchListAllTrainsEnabled() {
921        return getDefault().switchListAllTrains;
922    }
923
924    /**
925     * Used to determine if there's spaces or form feed between trains and locations
926     * when printing switch lists. see getSwitchListPageFormatComboBox()
927     *
928     * @param format PAGE_NORMAL, PAGE_PER_TRAIN, or PAGE_PER_VISIT
929     */
930    public static void setSwitchListPageFormat(String format) {
931        getDefault().switchListPageFormat = format;
932    }
933
934    public static String getSwitchListPageFormat() {
935        return getDefault().switchListPageFormat;
936    }
937
938    public static void setPrintTruncateManifestEnabled(boolean b) {
939        getDefault().manifestTruncated = b;
940    }
941
942    public static boolean isPrintTruncateManifestEnabled() {
943        return getDefault().manifestTruncated;
944    }
945
946    public static void setUseDepartureTimeEnabled(boolean b) {
947        getDefault().manifestDepartureTime = b;
948    }
949
950    public static boolean isUseDepartureTimeEnabled() {
951        return getDefault().manifestDepartureTime;
952    }
953
954    public static void setUseSwitchListDepartureTimeEnabled(boolean b) {
955        getDefault().switchListDepartureTime = b;
956    }
957
958    public static boolean isUseSwitchListDepartureTimeEnabled() {
959        return getDefault().switchListDepartureTime;
960    }
961
962    public static void setPrintLocationCommentsEnabled(boolean enable) {
963        getDefault().printLocationComments = enable;
964    }
965
966    public static boolean isPrintLocationCommentsEnabled() {
967        return getDefault().printLocationComments;
968    }
969
970    public static void setPrintRouteCommentsEnabled(boolean enable) {
971        getDefault().printRouteComments = enable;
972    }
973
974    public static boolean isPrintRouteCommentsEnabled() {
975        return getDefault().printRouteComments;
976    }
977
978    public static void setPrintLoadsAndEmptiesEnabled(boolean enable) {
979        getDefault().printLoadsAndEmpties = enable;
980    }
981
982    public static boolean isPrintLoadsAndEmptiesEnabled() {
983        return getDefault().printLoadsAndEmpties;
984    }
985
986    public static void setPrintTrainScheduleNameEnabled(boolean enable) {
987        getDefault().printTrainScheduleName = enable;
988    }
989
990    public static boolean isPrintTrainScheduleNameEnabled() {
991        return getDefault().printTrainScheduleName;
992    }
993
994    public static void set12hrFormatEnabled(boolean enable) {
995        getDefault().use12hrFormat = enable;
996    }
997
998    public static boolean is12hrFormatEnabled() {
999        return getDefault().use12hrFormat;
1000    }
1001
1002    public static void setPrintValidEnabled(boolean enable) {
1003        getDefault().printValid = enable;
1004    }
1005
1006    public static boolean isPrintValidEnabled() {
1007        return getDefault().printValid;
1008    }
1009
1010    public static void setSortByTrackNameEnabled(boolean enable) {
1011        getDefault().sortByTrack = enable;
1012    }
1013
1014    /**
1015     * when true manifest work is sorted by track names.
1016     * 
1017     * @return true if work at a location is to be sorted by track names.
1018     */
1019    public static boolean isSortByTrackNameEnabled() {
1020        return getDefault().sortByTrack;
1021    }
1022
1023    public static void setPrintHeadersEnabled(boolean enable) {
1024        getDefault().printHeaders = enable;
1025    }
1026
1027    public static boolean isPrintHeadersEnabled() {
1028        return getDefault().printHeaders;
1029    }
1030
1031    public static void setPrintNoPageBreaksEnabled(boolean enable) {
1032        getDefault().printNoPageBreaks = enable;
1033    }
1034
1035    public static boolean isPrintNoPageBreaksEnabled() {
1036        return getDefault().printNoPageBreaks;
1037    }
1038
1039    public static void setPrintHeaderLine1Enabled(boolean enable) {
1040        getDefault().printHeaderLine1 = enable;
1041    }
1042
1043    public static boolean isPrintHeaderLine1Enabled() {
1044        return getDefault().printHeaderLine1;
1045    }
1046
1047    public static void setPrintHeaderLine2Enabled(boolean enable) {
1048        getDefault().printHeaderLine2 = enable;
1049    }
1050
1051    public static boolean isPrintHeaderLine2Enabled() {
1052        return getDefault().printHeaderLine2;
1053    }
1054
1055    public static void setPrintHeaderLine3Enabled(boolean enable) {
1056        getDefault().printHeaderLine3 = enable;
1057    }
1058
1059    public static boolean isPrintHeaderLine3Enabled() {
1060        return getDefault().printHeaderLine3;
1061    }
1062
1063    public static void setPrintCabooseLoadEnabled(boolean enable) {
1064        getDefault().printCabooseLoad = enable;
1065    }
1066
1067    public static boolean isPrintCabooseLoadEnabled() {
1068        return getDefault().printCabooseLoad;
1069    }
1070
1071    public static void setPrintPassengerLoadEnabled(boolean enable) {
1072        getDefault().printPassengerLoad = enable;
1073    }
1074
1075    public static boolean isPrintPassengerLoadEnabled() {
1076        return getDefault().printPassengerLoad;
1077    }
1078
1079    public static void setShowTrackMovesEnabled(boolean enable) {
1080        boolean old = getDefault().showTrackMoves;
1081        getDefault().showTrackMoves = enable;
1082        setDirtyAndFirePropertyChange(SHOW_TRACK_MOVES_PROPERTY_CHANGE, old, enable);
1083    }
1084
1085    public static boolean isShowTrackMovesEnabled() {
1086        return getDefault().showTrackMoves;
1087    }
1088
1089    public static void setSwitchTime(int minutes) {
1090        getDefault().carSwitchTime = minutes;
1091    }
1092
1093    public static int getSwitchTime() {
1094        return getDefault().carSwitchTime;
1095    }
1096
1097    public static void setTravelTime(int minutes) {
1098        int old = getTravelTime();
1099        getDefault().travelTime = minutes;
1100        setDirtyAndFirePropertyChange(TRAVEL_TIME_PROPERTY_CHANGE, old, minutes);
1101    }
1102
1103    public static int getTravelTime() {
1104        return getDefault().travelTime;
1105    }
1106
1107    public static void setTrainIconColorNorth(String color) {
1108        getDefault().iconNorthColor = color;
1109    }
1110
1111    public static String getTrainIconColorNorth() {
1112        return getDefault().iconNorthColor;
1113    }
1114
1115    public static void setTrainIconColorSouth(String color) {
1116        getDefault().iconSouthColor = color;
1117    }
1118
1119    public static String getTrainIconColorSouth() {
1120        return getDefault().iconSouthColor;
1121    }
1122
1123    public static void setTrainIconColorEast(String color) {
1124        getDefault().iconEastColor = color;
1125    }
1126
1127    public static String getTrainIconColorEast() {
1128        return getDefault().iconEastColor;
1129    }
1130
1131    public static void setTrainIconColorWest(String color) {
1132        getDefault().iconWestColor = color;
1133    }
1134
1135    public static String getTrainIconColorWest() {
1136        return getDefault().iconWestColor;
1137    }
1138
1139    public static void setTrainIconColorLocal(String color) {
1140        getDefault().iconLocalColor = color;
1141    }
1142
1143    public static String getTrainIconColorLocal() {
1144        return getDefault().iconLocalColor;
1145    }
1146
1147    public static void setTrainIconColorTerminate(String color) {
1148        getDefault().iconTerminateColor = color;
1149    }
1150
1151    public static String getTrainIconColorTerminate() {
1152        return getDefault().iconTerminateColor;
1153    }
1154
1155    public static String getFontName() {
1156        return getDefault().fontName;
1157    }
1158
1159    public static void setFontName(String name) {
1160        getDefault().fontName = name;
1161    }
1162
1163    public static int getManifestFontSize() {
1164        return getDefault().manifestFontSize;
1165    }
1166
1167    public static void setManifestFontSize(int size) {
1168        getDefault().manifestFontSize = size;
1169    }
1170
1171    public static Sides getPrintDuplexSides() {
1172        return getDefault().sides;
1173    }
1174    
1175    public static void setPrintDuplexSides(Sides sides) {
1176        getDefault().sides = sides;
1177    }
1178
1179    public static boolean isPrintPageHeaderEnabled() {
1180        return getDefault().printHeader;
1181    }
1182
1183    public static void setPrintPageHeaderEnabled(boolean enable) {
1184        getDefault().printHeader = enable;
1185    }
1186
1187    public static int getBuildReportFontSize() {
1188        return getDefault().buildReportFontSize;
1189    }
1190
1191    public static void setBuildReportFontSize(int size) {
1192        getDefault().buildReportFontSize = size;
1193    }
1194
1195    public static String getManifestOrientation() {
1196        return getDefault().manifestOrientation;
1197    }
1198
1199    public static void setManifestOrientation(String orientation) {
1200        getDefault().manifestOrientation = orientation;
1201    }
1202
1203    public static String getSwitchListOrientation() {
1204        if (isSwitchListFormatSameAsManifest()) {
1205            return getDefault().manifestOrientation;
1206        } else {
1207            return getDefault().switchListOrientation;
1208        }
1209    }
1210
1211    public static void setSwitchListOrientation(String orientation) {
1212        getDefault().switchListOrientation = orientation;
1213    }
1214
1215    public static boolean isTabEnabled() {
1216        return getDefault().tab;
1217    }
1218
1219    public static void setTabEnabled(boolean enable) {
1220        getDefault().tab = enable;
1221    }
1222
1223    public static int getTab1Length() {
1224        return getDefault().tab1CharLength;
1225    }
1226
1227    public static void setTab1length(int length) {
1228        getDefault().tab1CharLength = length;
1229    }
1230
1231    public static int getTab2Length() {
1232        return getDefault().tab2CharLength;
1233    }
1234
1235    public static void setTab2length(int length) {
1236        getDefault().tab2CharLength = length;
1237    }
1238
1239    public static int getTab3Length() {
1240        return getDefault().tab3CharLength;
1241    }
1242
1243    public static void setTab3length(int length) {
1244        getDefault().tab3CharLength = length;
1245    }
1246
1247    public static String getManifestFormat() {
1248        return getDefault().manifestFormat;
1249    }
1250
1251    /**
1252     * Sets the format for manifests
1253     * 
1254     * @param format STANDARD_FORMAT, TWO_COLUMN_FORMAT, or TWO_COLUMN_TRACK_FORMAT
1255     */
1256    public static void setManifestFormat(String format) {
1257        getDefault().manifestFormat = format;
1258    }
1259
1260    public static boolean isCarLoggerEnabled() {
1261        return getDefault().carLogger;
1262    }
1263
1264    public static void setCarLoggerEnabled(boolean enable) {
1265        getDefault().carLogger = enable;
1266        InstanceManager.getDefault(RollingStockLogger.class).enableCarLogging(enable);
1267    }
1268
1269    public static boolean isEngineLoggerEnabled() {
1270        return getDefault().engineLogger;
1271    }
1272
1273    public static void setEngineLoggerEnabled(boolean enable) {
1274        getDefault().engineLogger = enable;
1275        InstanceManager.getDefault(RollingStockLogger.class).enableEngineLogging(enable);
1276    }
1277
1278    public static boolean isTrainLoggerEnabled() {
1279        return getDefault().trainLogger;
1280    }
1281
1282    public static void setTrainLoggerEnabled(boolean enable) {
1283        getDefault().trainLogger = enable;
1284        InstanceManager.getDefault(TrainLogger.class).enableTrainLogging(enable);
1285    }
1286
1287    public static boolean isSaveTrainManifestsEnabled() {
1288        return getDefault().saveTrainManifests;
1289    }
1290
1291    public static void setSaveTrainManifestsEnabled(boolean enable) {
1292        boolean old = getDefault().saveTrainManifests;
1293        getDefault().saveTrainManifests = enable;
1294        setDirtyAndFirePropertyChange(SAVE_TRAIN_MANIFEST_PROPERTY_CHANGE, old, enable);
1295    }
1296
1297    public static String getPickupEnginePrefix() {
1298        return getDefault().pickupEnginePrefix;
1299    }
1300
1301    public static void setPickupEnginePrefix(String prefix) {
1302        getDefault().pickupEnginePrefix = prefix;
1303    }
1304
1305    public static String getDropEnginePrefix() {
1306        return getDefault().dropEnginePrefix;
1307    }
1308
1309    public static void setDropEnginePrefix(String prefix) {
1310        getDefault().dropEnginePrefix = prefix;
1311    }
1312
1313    public static String getPickupCarPrefix() {
1314        return getDefault().pickupCarPrefix;
1315    }
1316
1317    public static void setPickupCarPrefix(String prefix) {
1318        getDefault().pickupCarPrefix = prefix;
1319    }
1320
1321    public static String getDropCarPrefix() {
1322        return getDefault().dropCarPrefix;
1323    }
1324
1325    public static void setDropCarPrefix(String prefix) {
1326        getDefault().dropCarPrefix = prefix;
1327    }
1328
1329    public static String getLocalPrefix() {
1330        return getDefault().localPrefix;
1331    }
1332
1333    public static void setLocalPrefix(String prefix) {
1334        getDefault().localPrefix = prefix;
1335    }
1336
1337    public static int getManifestPrefixLength() {
1338        int maxLength = getPickupEnginePrefix().length();
1339        if (getDropEnginePrefix().length() > maxLength) {
1340            maxLength = getDropEnginePrefix().length();
1341        }
1342        if (getPickupCarPrefix().length() > maxLength) {
1343            maxLength = getPickupCarPrefix().length();
1344        }
1345        if (getDropCarPrefix().length() > maxLength) {
1346            maxLength = getDropCarPrefix().length();
1347        }
1348        if (getLocalPrefix().length() > maxLength) {
1349            maxLength = getLocalPrefix().length();
1350        }
1351        return maxLength;
1352    }
1353
1354    public static String getSwitchListPickupCarPrefix() {
1355        if (isSwitchListFormatSameAsManifest()) {
1356            return getDefault().pickupCarPrefix;
1357        } else {
1358            return getDefault().switchListPickupCarPrefix;
1359        }
1360    }
1361
1362    public static void setSwitchListPickupCarPrefix(String prefix) {
1363        getDefault().switchListPickupCarPrefix = prefix;
1364    }
1365
1366    public static String getSwitchListDropCarPrefix() {
1367        if (isSwitchListFormatSameAsManifest()) {
1368            return getDefault().dropCarPrefix;
1369        } else {
1370            return getDefault().switchListDropCarPrefix;
1371        }
1372    }
1373
1374    public static void setSwitchListDropCarPrefix(String prefix) {
1375        getDefault().switchListDropCarPrefix = prefix;
1376    }
1377
1378    public static String getSwitchListLocalPrefix() {
1379        if (isSwitchListFormatSameAsManifest()) {
1380            return getDefault().localPrefix;
1381        } else {
1382            return getDefault().switchListLocalPrefix;
1383        }
1384    }
1385
1386    public static void setSwitchListLocalPrefix(String prefix) {
1387        getDefault().switchListLocalPrefix = prefix;
1388    }
1389
1390    public static int getSwitchListPrefixLength() {
1391        int maxLength = getPickupEnginePrefix().length();
1392        if (getDropEnginePrefix().length() > maxLength) {
1393            maxLength = getDropEnginePrefix().length();
1394        }
1395        if (getSwitchListPickupCarPrefix().length() > maxLength) {
1396            maxLength = getSwitchListPickupCarPrefix().length();
1397        }
1398        if (getSwitchListDropCarPrefix().length() > maxLength) {
1399            maxLength = getSwitchListDropCarPrefix().length();
1400        }
1401        if (getSwitchListLocalPrefix().length() > maxLength) {
1402            maxLength = getSwitchListLocalPrefix().length();
1403        }
1404        return maxLength;
1405    }
1406
1407    public static String[] getEngineAttributes() {
1408        return ENGINE_ATTRIBUTES.clone();
1409    }
1410
1411    public static String[] getPickupEngineMessageFormat() {
1412        return getDefault().pickupEngineMessageFormat.clone();
1413    }
1414
1415    public static void setPickupEngineMessageFormat(String[] format) {
1416        getDefault().pickupEngineMessageFormat = format;
1417    }
1418
1419    public static String[] getDropEngineMessageFormat() {
1420        return getDefault().dropEngineMessageFormat.clone();
1421    }
1422
1423    public static void setDropEngineMessageFormat(String[] format) {
1424        getDefault().dropEngineMessageFormat = format;
1425    }
1426
1427    public static String[] getCarAttributes() {
1428        return CAR_ATTRIBUTES.clone();
1429    }
1430
1431    public static String[] getPickupManifestMessageFormat() {
1432        return getDefault().pickupManifestMessageFormat.clone();
1433    }
1434
1435    public static void setPickupManifestMessageFormat(String[] format) {
1436        getDefault().pickupManifestMessageFormat = format;
1437    }
1438
1439    public static String[] getDropManifestMessageFormat() {
1440        return getDefault().dropManifestMessageFormat.clone();
1441    }
1442
1443    public static void setDropManifestMessageFormat(String[] format) {
1444        getDefault().dropManifestMessageFormat = format;
1445    }
1446
1447    public static String[] getLocalManifestMessageFormat() {
1448        return getDefault().localManifestMessageFormat.clone();
1449    }
1450
1451    public static void setLocalManifestMessageFormat(String[] format) {
1452        getDefault().localManifestMessageFormat = format;
1453    }
1454
1455    public static String[] getMissingCarMessageFormat() {
1456        return getDefault().missingCarMessageFormat.clone();
1457    }
1458
1459    public static void setMissingCarMessageFormat(String[] format) {
1460        getDefault().missingCarMessageFormat = format;
1461    }
1462
1463    public static String[] getPickupSwitchListMessageFormat() {
1464        if (isSwitchListFormatSameAsManifest()) {
1465            return getDefault().pickupManifestMessageFormat.clone();
1466        } else {
1467            return getDefault().pickupSwitchListMessageFormat.clone();
1468        }
1469    }
1470
1471    public static void setPickupSwitchListMessageFormat(String[] format) {
1472        getDefault().pickupSwitchListMessageFormat = format;
1473    }
1474
1475    public static String[] getDropSwitchListMessageFormat() {
1476        if (isSwitchListFormatSameAsManifest()) {
1477            return getDefault().dropManifestMessageFormat.clone();
1478        } else {
1479            return getDefault().dropSwitchListMessageFormat.clone();
1480        }
1481    }
1482
1483    public static void setDropSwitchListMessageFormat(String[] format) {
1484        getDefault().dropSwitchListMessageFormat = format;
1485    }
1486
1487    public static String[] getLocalSwitchListMessageFormat() {
1488        if (isSwitchListFormatSameAsManifest()) {
1489            return getDefault().localManifestMessageFormat.clone();
1490        } else {
1491            return getDefault().localSwitchListMessageFormat.clone();
1492        }
1493    }
1494
1495    public static void setLocalSwitchListMessageFormat(String[] format) {
1496        getDefault().localSwitchListMessageFormat = format;
1497    }
1498
1499    /**
1500     * Gets the manifest format for utility cars. The car's road, number, and color
1501     * are not printed.
1502     *
1503     * @return Utility car format
1504     */
1505    public static String[] getPickupUtilityManifestMessageFormat() {
1506        return createUitlityCarMessageFormat(getPickupManifestMessageFormat());
1507    }
1508
1509    public static String[] getDropUtilityManifestMessageFormat() {
1510        return createUitlityCarMessageFormat(getDropManifestMessageFormat());
1511    }
1512
1513    public static String[] getLocalUtilityManifestMessageFormat() {
1514        return createUitlityCarMessageFormat(getLocalManifestMessageFormat());
1515    }
1516
1517    public static String[] getPickupUtilitySwitchListMessageFormat() {
1518        return createUitlityCarMessageFormat(getPickupSwitchListMessageFormat());
1519    }
1520
1521    public static String[] getDropUtilitySwitchListMessageFormat() {
1522        return createUitlityCarMessageFormat(getDropSwitchListMessageFormat());
1523    }
1524
1525    public static String[] getLocalUtilitySwitchListMessageFormat() {
1526        return createUitlityCarMessageFormat(getLocalSwitchListMessageFormat());
1527    }
1528
1529    private static String[] createUitlityCarMessageFormat(String[] format) {
1530        // remove car's road, number, color
1531        for (int i = 0; i < format.length; i++) {
1532            if (format[i].equals(ROAD)) {
1533                format[i] = NO_ROAD;
1534            } else if (format[i].equals(NUMBER)) {
1535                format[i] = NO_NUMBER;
1536            } else if (format[i].equals(COLOR)) {
1537                format[i] = NO_COLOR;
1538            }
1539        }
1540        return format;
1541    }
1542
1543    public static String[] getPickupTruncatedManifestMessageFormat() {
1544        return createTruncatedManifestMessageFormat(getPickupManifestMessageFormat());
1545    }
1546
1547    public static String[] getDropTruncatedManifestMessageFormat() {
1548        return createTruncatedManifestMessageFormat(getDropManifestMessageFormat());
1549    }
1550
1551    public static String[] createTruncatedManifestMessageFormat(String[] format) {
1552        // remove car's destination and location
1553        for (int i = 0; i < format.length; i++) {
1554            if (format[i].equals(DESTINATION)) {
1555                format[i] = NO_DESTINATION;
1556            } else if (format[i].equals(DEST_TRACK)) {
1557                format[i] = NO_DEST_TRACK;
1558            } else if (format[i].equals(LOCATION)) {
1559                format[i] = NO_LOCATION;
1560            } else if (format[i].equals(TRACK)) {
1561                format[i] = NO_TRACK;
1562            }
1563        }
1564        return format;
1565    }
1566
1567    public static String[] getPickupTwoColumnByTrackManifestMessageFormat() {
1568        return createTwoColumnByTrackPickupMessageFormat(getPickupManifestMessageFormat());
1569    }
1570
1571    public static String[] getPickupTwoColumnByTrackSwitchListMessageFormat() {
1572        return createTwoColumnByTrackPickupMessageFormat(getPickupSwitchListMessageFormat());
1573    }
1574
1575    public static String[] getPickupTwoColumnByTrackUtilityManifestMessageFormat() {
1576        return createTwoColumnByTrackPickupMessageFormat(getPickupUtilityManifestMessageFormat());
1577    }
1578
1579    public static String[] getPickupTwoColumnByTrackUtilitySwitchListMessageFormat() {
1580        return createTwoColumnByTrackPickupMessageFormat(getPickupUtilitySwitchListMessageFormat());
1581    }
1582
1583    private static String[] createTwoColumnByTrackPickupMessageFormat(String[] format) {
1584        for (int i = 0; i < format.length; i++) {
1585            if (format[i].equals(LOCATION)) {
1586                format[i] = BLANK;
1587            } else if (format[i].equals(TRACK)) {
1588                format[i] = BLANK;
1589            }
1590        }
1591        return format;
1592    }
1593
1594    public static String[] getDropTwoColumnByTrackManifestMessageFormat() {
1595        return createTwoColumnByTrackDropMessageFormat(getDropManifestMessageFormat());
1596    }
1597
1598    public static String[] getDropTwoColumnByTrackSwitchListMessageFormat() {
1599        return createTwoColumnByTrackDropMessageFormat(getDropSwitchListMessageFormat());
1600    }
1601
1602    public static String[] getDropTwoColumnByTrackUtilityManifestMessageFormat() {
1603        return createTwoColumnByTrackDropMessageFormat(getDropUtilityManifestMessageFormat());
1604    }
1605
1606    public static String[] getDropTwoColumnByTrackUtilitySwitchListMessageFormat() {
1607        return createTwoColumnByTrackDropMessageFormat(getDropUtilitySwitchListMessageFormat());
1608    }
1609
1610    private static String[] createTwoColumnByTrackDropMessageFormat(String[] format) {
1611        for (int i = 0; i < format.length; i++) {
1612            if (format[i].equals(DESTINATION)) {
1613                format[i] = BLANK;
1614            } else if (format[i].equals(TRACK)) {
1615                format[i] = BLANK;
1616            }
1617        }
1618        return format;
1619    }
1620
1621    public static String getDropEngineTextColor() {
1622        return ColorUtil.colorToColorName(getDefault().dropEngineColor);
1623    }
1624
1625    public static void setDropEngineTextColor(String color) {
1626        setDropEngineColor(ColorUtil.stringToColor(color));
1627    }
1628
1629    public static void setDropEngineColor(Color c) {
1630        getDefault().dropEngineColor = c;
1631        JmriColorChooser.addRecentColor(c);
1632    }
1633
1634    public static String getPickupEngineTextColor() {
1635        return ColorUtil.colorToColorName(getDefault().pickupEngineColor);
1636    }
1637
1638    public static void setPickupEngineTextColor(String color) {
1639        setPickupEngineColor(ColorUtil.stringToColor(color));
1640    }
1641
1642    public static void setPickupEngineColor(Color c) {
1643        getDefault().pickupEngineColor = c;
1644        JmriColorChooser.addRecentColor(c);
1645    }
1646
1647    public static String getDropTextColor() {
1648        return ColorUtil.colorToColorName(getDefault().dropColor);
1649    }
1650
1651    public static void setDropTextColor(String color) {
1652        setDropColor(ColorUtil.stringToColor(color));
1653    }
1654
1655    public static void setDropColor(Color c) {
1656        getDefault().dropColor = c;
1657        JmriColorChooser.addRecentColor(c);
1658    }
1659
1660    public static String getPickupTextColor() {
1661        return ColorUtil.colorToColorName(getDefault().pickupColor);
1662    }
1663
1664    public static void setPickupTextColor(String color) {
1665        setPickupColor(ColorUtil.stringToColor(color));
1666    }
1667
1668    public static void setPickupColor(Color c) {
1669        getDefault().pickupColor = c;
1670        JmriColorChooser.addRecentColor(c);
1671    }
1672
1673    public static String getLocalTextColor() {
1674        return ColorUtil.colorToColorName(getDefault().localColor);
1675    }
1676
1677    public static void setLocalTextColor(String color) {
1678        setLocalColor(ColorUtil.stringToColor(color));
1679    }
1680
1681    public static void setLocalColor(Color c) {
1682        getDefault().localColor = c;
1683        JmriColorChooser.addRecentColor(c);
1684    }
1685
1686    public static Color getPickupEngineColor() {
1687        return getDefault().pickupEngineColor;
1688    }
1689
1690    public static Color getDropEngineColor() {
1691        return getDefault().dropEngineColor;
1692    }
1693
1694    public static Color getPickupColor() {
1695        return getDefault().pickupColor;
1696    }
1697
1698    public static Color getDropColor() {
1699        return getDefault().dropColor;
1700    }
1701
1702    public static Color getLocalColor() {
1703        return getDefault().localColor;
1704    }
1705
1706    public static Color getColor(String colorName) {
1707        return ColorUtil.stringToColor(colorName);
1708    }
1709
1710    public static String getManifestLogoURL() {
1711        return getDefault().logoURL;
1712    }
1713
1714    public static void setManifestLogoURL(String pathName) {
1715        getDefault().logoURL = pathName;
1716    }
1717
1718    public static String getOwnerName() {
1719        return getDefault().ownerName;
1720    }
1721
1722    public static void setOwnerName(String name) {
1723        getDefault().ownerName = name;
1724    }
1725
1726    public static int getScaleRatio() {
1727        if (getDefault().scale == 0) {
1728            log.error("Scale not set");
1729        }
1730        return getDefault().ratio;
1731    }
1732
1733    public static int getScaleTonRatio() {
1734        if (getDefault().scale == 0) {
1735            log.error("Scale not set");
1736        }
1737        return getDefault().ratioTons;
1738    }
1739
1740    public static int getInitalWeight() {
1741        if (getDefault().scale == 0) {
1742            log.error("Scale not set");
1743        }
1744        return getDefault().initWeight;
1745    }
1746
1747    public static int getAddWeight() {
1748        if (getDefault().scale == 0) {
1749            log.error("Scale not set");
1750        }
1751        return getDefault().addWeight;
1752    }
1753
1754    public static int getScale() {
1755        return getDefault().scale;
1756    }
1757
1758    public static void setScale(int s) {
1759        getDefault().scale = s;
1760        switch (getDefault().scale) {
1761            case Z_SCALE:
1762                getDefault().ratio = Z_RATIO;
1763                getDefault().initWeight = Z_INITIAL_WEIGHT;
1764                getDefault().addWeight = Z_ADD_WEIGHT;
1765                getDefault().ratioTons = Z_RATIO_TONS;
1766                break;
1767            case N_SCALE:
1768                getDefault().ratio = N_RATIO;
1769                getDefault().initWeight = N_INITIAL_WEIGHT;
1770                getDefault().addWeight = N_ADD_WEIGHT;
1771                getDefault().ratioTons = N_RATIO_TONS;
1772                break;
1773            case TT_SCALE:
1774                getDefault().ratio = TT_RATIO;
1775                getDefault().initWeight = TT_INITIAL_WEIGHT;
1776                getDefault().addWeight = TT_ADD_WEIGHT;
1777                getDefault().ratioTons = TT_RATIO_TONS;
1778                break;
1779            case HOn3_SCALE:
1780                getDefault().ratio = HO_RATIO;
1781                getDefault().initWeight = HOn3_INITIAL_WEIGHT;
1782                getDefault().addWeight = HOn3_ADD_WEIGHT;
1783                getDefault().ratioTons = HOn3_RATIO_TONS;
1784                break;
1785            case OO_SCALE:
1786                getDefault().ratio = OO_RATIO;
1787                getDefault().initWeight = OO_INITIAL_WEIGHT;
1788                getDefault().addWeight = OO_ADD_WEIGHT;
1789                getDefault().ratioTons = OO_RATIO_TONS;
1790                break;
1791            case HO_SCALE:
1792                getDefault().ratio = HO_RATIO;
1793                getDefault().initWeight = HO_INITIAL_WEIGHT;
1794                getDefault().addWeight = HO_ADD_WEIGHT;
1795                getDefault().ratioTons = HO_RATIO_TONS;
1796                break;
1797            case Sn3_SCALE:
1798                getDefault().ratio = S_RATIO;
1799                getDefault().initWeight = Sn3_INITIAL_WEIGHT;
1800                getDefault().addWeight = Sn3_ADD_WEIGHT;
1801                getDefault().ratioTons = Sn3_RATIO_TONS;
1802                break;
1803            case S_SCALE:
1804                getDefault().ratio = S_RATIO;
1805                getDefault().initWeight = S_INITIAL_WEIGHT;
1806                getDefault().addWeight = S_ADD_WEIGHT;
1807                getDefault().ratioTons = S_RATIO_TONS;
1808                break;
1809            case On3_SCALE:
1810                getDefault().ratio = O_RATIO;
1811                getDefault().initWeight = On3_INITIAL_WEIGHT;
1812                getDefault().addWeight = On3_ADD_WEIGHT;
1813                getDefault().ratioTons = On3_RATIO_TONS;
1814                break;
1815            case O_SCALE:
1816                getDefault().ratio = O_RATIO;
1817                getDefault().initWeight = O_INITIAL_WEIGHT;
1818                getDefault().addWeight = O_ADD_WEIGHT;
1819                getDefault().ratioTons = O_RATIO_TONS;
1820                break;
1821
1822            case Gauge1_SCALE:
1823                getDefault().ratio = Gauge1_RATIO;
1824                getDefault().initWeight = G_INITIAL_WEIGHT;
1825                getDefault().addWeight = G_ADD_WEIGHT;
1826                getDefault().ratioTons = G_RATIO_TONS;
1827                break;
1828            case G_24_SCALE:
1829                getDefault().ratio = G_24_RATIO;
1830                getDefault().initWeight = G_INITIAL_WEIGHT;
1831                getDefault().addWeight = G_ADD_WEIGHT;
1832                getDefault().ratioTons = G_RATIO_TONS;
1833                break;
1834            default:
1835                log.error("Unknown scale");
1836        }
1837    }
1838
1839    public static JComboBox<String> getManifestFormatComboBox() {
1840        JComboBox<String> box = new JComboBox<>();
1841        box.addItem(STANDARD_FORMAT);
1842        box.addItem(TWO_COLUMN_FORMAT);
1843        box.addItem(TWO_COLUMN_TRACK_FORMAT);
1844        OperationsPanel.padComboBox(box, TWO_COLUMN_TRACK_FORMAT.length());
1845        return box;
1846    }
1847
1848    public static JComboBox<String> getOrientationComboBox() {
1849        JComboBox<String> box = new JComboBox<>();
1850        box.addItem(PORTRAIT);
1851        box.addItem(LANDSCAPE);
1852        box.addItem(HALFPAGE);
1853        box.addItem(HANDHELD);
1854        box.addItem(RECEIPT);
1855        OperationsPanel.padComboBox(box, LANDSCAPE.length());
1856        return box;
1857    }
1858
1859    public static JComboBox<String> getSwitchListPageFormatComboBox() {
1860        JComboBox<String> box = new JComboBox<>();
1861        box.addItem(PAGE_NORMAL);
1862        box.addItem(PAGE_PER_TRAIN);
1863        box.addItem(PAGE_PER_VISIT);
1864        OperationsPanel.padComboBox(box, PAGE_PER_TRAIN.length());
1865        return box;
1866    }
1867
1868    public static JComboBox<String> getEngineMessageComboBox() {
1869        JComboBox<String> box = new JComboBox<>();
1870        box.addItem(BLANK);
1871        for (String attribute : getEngineAttributes()) {
1872            box.addItem(attribute);
1873        }
1874        if (isTabEnabled()) {
1875            box.addItem(TAB);
1876            box.addItem(TAB2);
1877            box.addItem(TAB3);
1878        }
1879        return box;
1880    }
1881
1882    public static JComboBox<String> getCarMessageComboBox() {
1883        JComboBox<String> box = new JComboBox<>();
1884        box.addItem(BLANK);
1885        for (String attribute : getCarAttributes()) {
1886            box.addItem(attribute);
1887        }
1888        if (isTabEnabled()) {
1889            box.addItem(TAB);
1890            box.addItem(TAB2);
1891            box.addItem(TAB3);
1892        }
1893        return box;
1894    }
1895
1896    /**
1897     *
1898     * @return JComboBox loaded with the strings (North, South, East, West) showing
1899     *         the available train directions for this railroad
1900     */
1901    public static JComboBox<String> getTrainDirectionComboBox() {
1902        JComboBox<String> box = new JComboBox<>();
1903        for (String direction : getTrainDirectionList()) {
1904            box.addItem(direction);
1905        }
1906        return box;
1907    }
1908
1909    /**
1910     * Get train directions String format
1911     *
1912     * @return List of valid train directions
1913     */
1914    public static List<String> getTrainDirectionList() {
1915        List<String> directions = new ArrayList<>();
1916        if ((getDefault().traindir & EAST) == EAST) {
1917            directions.add(EAST_DIR);
1918        }
1919        if ((getDefault().traindir & WEST) == WEST) {
1920            directions.add(WEST_DIR);
1921        }
1922        if ((getDefault().traindir & NORTH) == NORTH) {
1923            directions.add(NORTH_DIR);
1924        }
1925        if ((getDefault().traindir & SOUTH) == SOUTH) {
1926            directions.add(SOUTH_DIR);
1927        }
1928        return directions;
1929    }
1930
1931    /**
1932     * Converts binary direction to String direction
1933     *
1934     * @param direction EAST, WEST, NORTH, SOUTH
1935     * @return String representation of a direction
1936     */
1937    public static String getDirectionString(int direction) {
1938        switch (direction) {
1939            case EAST:
1940                return EAST_DIR;
1941            case WEST:
1942                return WEST_DIR;
1943            case NORTH:
1944                return NORTH_DIR;
1945            case SOUTH:
1946                return SOUTH_DIR;
1947            default:
1948                return "unknown"; // NOI18N
1949        }
1950    }
1951
1952    /**
1953     * Converts binary direction to a set of String directions
1954     *
1955     * @param directions EAST, WEST, NORTH, SOUTH
1956     * @return String[] representation of a set of directions
1957     */
1958    public static String[] getDirectionStrings(int directions) {
1959        String[] dir = new String[4];
1960        int i = 0;
1961        if ((directions & EAST) == EAST) {
1962            dir[i++] = EAST_DIR;
1963        }
1964        if ((directions & WEST) == WEST) {
1965            dir[i++] = WEST_DIR;
1966        }
1967        if ((directions & NORTH) == NORTH) {
1968            dir[i++] = NORTH_DIR;
1969        }
1970        if ((directions & SOUTH) == SOUTH) {
1971            dir[i++] = SOUTH_DIR;
1972        }
1973        return dir;
1974    }
1975
1976    /**
1977     * Converts String direction to binary direction
1978     *
1979     * @param direction EAST_DIR WEST_DIR NORTH_DIR SOUTH_DIR
1980     * @return integer representation of a direction
1981     */
1982    public static int getDirectionInt(String direction) {
1983        if (direction.equals(EAST_DIR)) {
1984            return EAST;
1985        } else if (direction.equals(WEST_DIR)) {
1986            return WEST;
1987        } else if (direction.equals(NORTH_DIR)) {
1988            return NORTH;
1989        } else if (direction.equals(SOUTH_DIR)) {
1990            return SOUTH;
1991        } else {
1992            return 0; // return unknown
1993        }
1994    }
1995    
1996    public static void setDayToName(String day, String name) {
1997        if (name != null) {
1998            getDefault().hashTableDayToName.put(day, name);
1999        }
2000    }
2001    
2002    public static String getDayToName(String day) {
2003        return getDefault().hashTableDayToName.get(day);
2004    }
2005
2006    // must synchronize changes with operation-config.dtd
2007    public static Element store() {
2008        Element values;
2009        Element e = new Element(Xml.OPERATIONS);
2010
2011        // only store railroad name if it doesn't match the preferences railroad name
2012        if (!InstanceManager.getDefault(WebServerPreferences.class).getRailroadName().equals(getRailroadName())) {
2013            e.addContent(values = new Element(Xml.RAIL_ROAD));
2014            values.setAttribute(Xml.NAME, getRailroadName());
2015        }
2016
2017        e.addContent(values = new Element(Xml.SETUP));
2018        values.setAttribute(Xml.COMMENT, getComment());
2019
2020        e.addContent(values = new Element(Xml.SETTINGS));
2021        values.setAttribute(Xml.MAIN_MENU, isMainMenuEnabled() ? Xml.TRUE : Xml.FALSE);
2022        values.setAttribute(Xml.CLOSE_ON_SAVE, isCloseWindowOnSaveEnabled() ? Xml.TRUE : Xml.FALSE);
2023        values.setAttribute(Xml.AUTO_SAVE, isAutoSaveEnabled() ? Xml.TRUE : Xml.FALSE);
2024        values.setAttribute(Xml.AUTO_BACKUP, isAutoBackupEnabled() ? Xml.TRUE : Xml.FALSE);
2025        values.setAttribute(Xml.TRAIN_DIRECTION, Integer.toString(getTrainDirection()));
2026        values.setAttribute(Xml.TRAIN_LENGTH, Integer.toString(getMaxTrainLength()));
2027        values.setAttribute(Xml.MAX_ENGINES, Integer.toString(getMaxNumberEngines()));
2028        values.setAttribute(Xml.HPT, Double.toString(getHorsePowerPerTon()));
2029        values.setAttribute(Xml.SCALE, Integer.toString(getScale()));
2030        values.setAttribute(Xml.CAR_TYPES, getCarTypes());
2031        values.setAttribute(Xml.SWITCH_TIME, Integer.toString(getSwitchTime()));
2032        values.setAttribute(Xml.TRAVEL_TIME, Integer.toString(getTravelTime()));
2033        values.setAttribute(Xml.SHOW_VALUE, isValueEnabled() ? Xml.TRUE : Xml.FALSE);
2034        values.setAttribute(Xml.VALUE_LABEL, getValueLabel());
2035        values.setAttribute(Xml.SHOW_RFID, isRfidEnabled() ? Xml.TRUE : Xml.FALSE);
2036        values.setAttribute(Xml.RFID_LABEL, getRfidLabel());
2037        values.setAttribute(Xml.LENGTH_UNIT, getLengthUnit());
2038        values.setAttribute(Xml.YEAR_MODELED, getYearModeled());
2039
2040        e.addContent(values = new Element(Xml.PICKUP_ENG_FORMAT));
2041        storeXmlMessageFormat(values, getPickupEnginePrefix(), getPickupEngineMessageFormat());
2042
2043        e.addContent(values = new Element(Xml.DROP_ENG_FORMAT));
2044        storeXmlMessageFormat(values, getDropEnginePrefix(), getDropEngineMessageFormat());
2045
2046        e.addContent(values = new Element(Xml.PICKUP_CAR_FORMAT));
2047        storeXmlMessageFormat(values, getPickupCarPrefix(), getPickupManifestMessageFormat());
2048
2049        e.addContent(values = new Element(Xml.DROP_CAR_FORMAT));
2050        storeXmlMessageFormat(values, getDropCarPrefix(), getDropManifestMessageFormat());
2051
2052        e.addContent(values = new Element(Xml.LOCAL_FORMAT));
2053        storeXmlMessageFormat(values, getLocalPrefix(), getLocalManifestMessageFormat());
2054
2055        e.addContent(values = new Element(Xml.MISSING_CAR_FORMAT));
2056        storeXmlMessageFormat(values, NONE, getMissingCarMessageFormat());
2057
2058        e.addContent(values = new Element(Xml.SWITCH_LIST));
2059        values.setAttribute(Xml.SAME_AS_MANIFEST, isSwitchListFormatSameAsManifest() ? Xml.TRUE : Xml.FALSE);
2060        values.setAttribute(Xml.REAL_TIME, isSwitchListRealTime() ? Xml.TRUE : Xml.FALSE);
2061        values.setAttribute(Xml.ALL_TRAINS, isSwitchListAllTrainsEnabled() ? Xml.TRUE : Xml.FALSE);
2062
2063        // save switch list format
2064        String format = Xml.PAGE_NORMAL;
2065        if (getSwitchListPageFormat().equals(PAGE_PER_TRAIN)) {
2066            format = Xml.PAGE_PER_TRAIN;
2067            values.setAttribute(Xml.PAGE_MODE, Xml.TRUE); // backwards compatible for versions before 3.11
2068        } else if (getSwitchListPageFormat().equals(PAGE_PER_VISIT)) {
2069            format = Xml.PAGE_PER_VISIT;
2070        }
2071        values.setAttribute(Xml.PAGE_FORMAT, format);
2072
2073        values.setAttribute(Xml.PRINT_ROUTE_LOCATION, isSwitchListRouteLocationCommentEnabled() ? Xml.TRUE : Xml.FALSE);
2074        values.setAttribute(Xml.TRACK_SUMMARY, isPrintTrackSummaryEnabled() ? Xml.TRUE : Xml.FALSE);
2075        values.setAttribute(Xml.USE_DEPARTURE_TIME, isUseSwitchListDepartureTimeEnabled() ? Xml.TRUE : Xml.FALSE);
2076
2077        e.addContent(values = new Element(Xml.SWITCH_LIST_PICKUP_CAR_FORMAT));
2078        storeXmlMessageFormat(values, getSwitchListPickupCarPrefix(), getPickupSwitchListMessageFormat());
2079
2080        e.addContent(values = new Element(Xml.SWITCH_LIST_DROP_CAR_FORMAT));
2081        storeXmlMessageFormat(values, getSwitchListDropCarPrefix(), getDropSwitchListMessageFormat());
2082
2083        e.addContent(values = new Element(Xml.SWITCH_LIST_LOCAL_FORMAT));
2084        storeXmlMessageFormat(values, getSwitchListLocalPrefix(), getLocalSwitchListMessageFormat());
2085
2086        e.addContent(values = new Element(Xml.PANEL));
2087        values.setAttribute(Xml.NAME, getPanelName());
2088        values.setAttribute(Xml.TRAIN_ICONXY, isTrainIconCordEnabled() ? Xml.TRUE : Xml.FALSE);
2089        values.setAttribute(Xml.TRAIN_ICON_APPEND, isTrainIconAppendEnabled() ? Xml.TRUE : Xml.FALSE);
2090
2091        e.addContent(values = new Element(Xml.FONT_NAME));
2092        values.setAttribute(Xml.NAME, getFontName());
2093
2094        e.addContent(values = new Element(Xml.FONT_SIZE));
2095        values.setAttribute(Xml.SIZE, Integer.toString(getManifestFontSize()));
2096
2097        e.addContent(values = new Element(Xml.PAGE_ORIENTATION));
2098        values.setAttribute(Xml.MANIFEST, getManifestOrientation());
2099        values.setAttribute(Xml.SWITCH_LIST, getSwitchListOrientation());
2100
2101        e.addContent(values = new Element(Xml.PRINT_DUPLEX));
2102        values.setAttribute(Xml.NAME, getPrintDuplexSides().toString());
2103
2104        e.addContent(values = new Element(Xml.MANIFEST_COLORS));
2105        values.setAttribute(Xml.DROP_ENGINE_COLOR, getDropEngineTextColor());
2106        values.setAttribute(Xml.PICKUP_ENGINE_COLOR, getPickupEngineTextColor());
2107        values.setAttribute(Xml.DROP_COLOR, getDropTextColor());
2108        values.setAttribute(Xml.PICKUP_COLOR, getPickupTextColor());
2109        values.setAttribute(Xml.LOCAL_COLOR, getLocalTextColor());
2110
2111        e.addContent(values = new Element(Xml.TAB));
2112        values.setAttribute(Xml.ENABLED, isTabEnabled() ? Xml.TRUE : Xml.FALSE);
2113        values.setAttribute(Xml.LENGTH, Integer.toString(getTab1Length()));
2114        values.setAttribute(Xml.TAB2_LENGTH, Integer.toString(getTab2Length()));
2115        values.setAttribute(Xml.TAB3_LENGTH, Integer.toString(getTab3Length()));
2116
2117        e.addContent(values = new Element(Xml.MANIFEST));
2118        values.setAttribute(Xml.PRINT_LOC_COMMENTS, isPrintLocationCommentsEnabled() ? Xml.TRUE : Xml.FALSE);
2119        values.setAttribute(Xml.PRINT_ROUTE_COMMENTS, isPrintRouteCommentsEnabled() ? Xml.TRUE : Xml.FALSE);
2120        values.setAttribute(Xml.PRINT_LOADS_EMPTIES, isPrintLoadsAndEmptiesEnabled() ? Xml.TRUE : Xml.FALSE);
2121        values.setAttribute(Xml.PRINT_TRAIN_SCHEDULE, isPrintTrainScheduleNameEnabled() ? Xml.TRUE : Xml.FALSE);
2122        values.setAttribute(Xml.USE12HR_FORMAT, is12hrFormatEnabled() ? Xml.TRUE : Xml.FALSE);
2123        values.setAttribute(Xml.PRINT_VALID, isPrintValidEnabled() ? Xml.TRUE : Xml.FALSE);
2124        values.setAttribute(Xml.SORT_BY_TRACK, isSortByTrackNameEnabled() ? Xml.TRUE : Xml.FALSE);
2125        values.setAttribute(Xml.PRINT_PAGE_HEADER, isPrintPageHeaderEnabled() ? Xml.TRUE : Xml.FALSE);
2126        values.setAttribute(Xml.PRINT_HEADERS, isPrintHeadersEnabled() ? Xml.TRUE : Xml.FALSE);
2127        values.setAttribute(Xml.PRINT_NO_PAGE_BREAKS, isPrintNoPageBreaksEnabled() ? Xml.TRUE : Xml.FALSE);
2128        values.setAttribute(Xml.TRUNCATE, isPrintTruncateManifestEnabled() ? Xml.TRUE : Xml.FALSE);
2129        values.setAttribute(Xml.USE_DEPARTURE_TIME, isUseDepartureTimeEnabled() ? Xml.TRUE : Xml.FALSE);
2130        values.setAttribute(Xml.USE_EDITOR, isManifestEditorEnabled() ? Xml.TRUE : Xml.FALSE);
2131        values.setAttribute(Xml.PRINT_CABOOSE_LOAD, isPrintCabooseLoadEnabled() ? Xml.TRUE : Xml.FALSE);
2132        values.setAttribute(Xml.PRINT_PASSENGER_LOAD, isPrintPassengerLoadEnabled() ? Xml.TRUE : Xml.FALSE);
2133        values.setAttribute(Xml.GROUP_MOVES, isGroupCarMovesEnabled() ? Xml.TRUE : Xml.FALSE);
2134        values.setAttribute(Xml.PRINT_LOCO_LAST, isPrintLocoLastEnabled() ? Xml.TRUE : Xml.FALSE);
2135        values.setAttribute(Xml.HAZARDOUS_MSG, getHazardousMsg());
2136
2137        // new format June 2014
2138        e.addContent(values = new Element(Xml.MANIFEST_FORMAT));
2139
2140        // save manifest format
2141        String value = Xml.STANDARD;
2142        if (getManifestFormat().equals(TWO_COLUMN_FORMAT)) {
2143            value = Xml.TWO_COLUMN;
2144        } else if (getManifestFormat().equals(TWO_COLUMN_TRACK_FORMAT)) {
2145            value = Xml.TWO_COLUMN_TRACK;
2146        }
2147        values.setAttribute(Xml.VALUE, value);
2148
2149        // new format June 2025
2150        e.addContent(values = new Element(Xml.HEADER_LINES));
2151        values.setAttribute(Xml.PRINT_HEADER_LINE1, isPrintHeaderLine1Enabled() ? Xml.TRUE : Xml.FALSE);
2152        values.setAttribute(Xml.PRINT_HEADER_LINE2, isPrintHeaderLine2Enabled() ? Xml.TRUE : Xml.FALSE);
2153        values.setAttribute(Xml.PRINT_HEADER_LINE3, isPrintHeaderLine3Enabled() ? Xml.TRUE : Xml.FALSE);
2154
2155        if (!getManifestLogoURL().equals(NONE)) {
2156            values = new Element(Xml.MANIFEST_LOGO);
2157            values.setAttribute(Xml.NAME, getManifestLogoURL());
2158            e.addContent(values);
2159        }
2160
2161        // manifest save file options
2162        e.addContent(values = new Element(Xml.MANIFEST_FILE_OPTIONS));
2163        values.setAttribute(Xml.MANIFEST_SAVE, isSaveTrainManifestsEnabled() ? Xml.TRUE : Xml.FALSE);
2164
2165        e.addContent(values = new Element(Xml.BUILD_OPTIONS));
2166        values.setAttribute(Xml.AGGRESSIVE, isBuildAggressive() ? Xml.TRUE : Xml.FALSE);
2167        values.setAttribute(Xml.NUMBER_PASSES, Integer.toString(getNumberPasses()));
2168        values.setAttribute(Xml.ON_TIME, isBuildOnTime() ? Xml.TRUE : Xml.FALSE);
2169        values.setAttribute(Xml.DWELL_TIME, Integer.toString(getDwellTime()));
2170
2171        values.setAttribute(Xml.ALLOW_LOCAL_INTERCHANGE, isLocalInterchangeMovesEnabled() ? Xml.TRUE : Xml.FALSE);
2172        values.setAttribute(Xml.ALLOW_LOCAL_SPUR, isLocalSpurMovesEnabled() ? Xml.TRUE : Xml.FALSE);
2173        values.setAttribute(Xml.ALLOW_LOCAL_YARD, isLocalYardMovesEnabled() ? Xml.TRUE : Xml.FALSE);
2174
2175        values.setAttribute(Xml.STAGING_RESTRICTION_ENABLED, isStagingTrainCheckEnabled() ? Xml.TRUE : Xml.FALSE);
2176        values.setAttribute(Xml.STAGING_TRACK_AVAIL, isStagingTrackImmediatelyAvail() ? Xml.TRUE : Xml.FALSE);
2177        values.setAttribute(Xml.ALLOW_RETURN_STAGING, isStagingAllowReturnEnabled() ? Xml.TRUE : Xml.FALSE);
2178        values.setAttribute(Xml.PROMPT_STAGING_ENABLED, isStagingPromptFromEnabled() ? Xml.TRUE : Xml.FALSE);
2179        values.setAttribute(Xml.PROMPT_TO_STAGING_ENABLED, isStagingPromptToEnabled() ? Xml.TRUE : Xml.FALSE);
2180        values.setAttribute(Xml.STAGING_TRY_NORMAL, isStagingTryNormalBuildEnabled() ? Xml.TRUE : Xml.FALSE);
2181
2182        values.setAttribute(Xml.GENERATE_CSV_MANIFEST, isGenerateCsvManifestEnabled() ? Xml.TRUE : Xml.FALSE);
2183        values.setAttribute(Xml.GENERATE_CSV_SWITCH_LIST, isGenerateCsvSwitchListEnabled() ? Xml.TRUE : Xml.FALSE);
2184
2185        e.addContent(values = new Element(Xml.BUILD_REPORT));
2186        values.setAttribute(Xml.LEVEL, getBuildReportLevel());
2187        values.setAttribute(Xml.ROUTER_LEVEL, getRouterBuildReportLevel());
2188        values.setAttribute(Xml.USE_EDITOR, isBuildReportEditorEnabled() ? Xml.TRUE : Xml.FALSE);
2189        values.setAttribute(Xml.INDENT, isBuildReportIndentEnabled() ? Xml.TRUE : Xml.FALSE);
2190        values.setAttribute(Xml.ALWAYS_PREVIEW, isBuildReportAlwaysPreviewEnabled() ? Xml.TRUE : Xml.FALSE);
2191        values.setAttribute(Xml.FONT_SIZE, Integer.toString(getBuildReportFontSize()));
2192
2193        // new format for router options
2194        e.addContent(values = new Element(Xml.ROUTER));
2195        values.setAttribute(Xml.CAR_ROUTING_ENABLED, isCarRoutingEnabled() ? Xml.TRUE : Xml.FALSE);
2196        values.setAttribute(Xml.CAR_ROUTING_VIA_YARDS, isCarRoutingViaYardsEnabled() ? Xml.TRUE : Xml.FALSE);
2197        values.setAttribute(Xml.CAR_ROUTING_VIA_STAGING, isCarRoutingViaStagingEnabled() ? Xml.TRUE : Xml.FALSE);
2198        values.setAttribute(Xml.FORWARD_TO_YARD, isForwardToYardEnabled() ? Xml.TRUE : Xml.FALSE);
2199        values.setAttribute(Xml.ONLY_ACTIVE_TRAINS, isOnlyActiveTrainsEnabled() ? Xml.TRUE : Xml.FALSE);
2200        values.setAttribute(Xml.CHECK_CAR_DESTINATION, isCheckCarDestinationEnabled() ? Xml.TRUE : Xml.FALSE);
2201
2202        // new format for logger options
2203        e.addContent(values = new Element(Xml.LOGGER));
2204        values.setAttribute(Xml.CAR_LOGGER, isCarLoggerEnabled() ? Xml.TRUE : Xml.FALSE);
2205        values.setAttribute(Xml.ENGINE_LOGGER, isEngineLoggerEnabled() ? Xml.TRUE : Xml.FALSE);
2206        values.setAttribute(Xml.TRAIN_LOGGER, isTrainLoggerEnabled() ? Xml.TRUE : Xml.FALSE);
2207
2208        e.addContent(values = new Element(Xml.OWNER));
2209        values.setAttribute(Xml.NAME, getOwnerName());
2210
2211        e.addContent(values = new Element(Xml.ICON_COLOR));
2212        values.setAttribute(Xml.NORTH, getTrainIconColorNorth());
2213        values.setAttribute(Xml.SOUTH, getTrainIconColorSouth());
2214        values.setAttribute(Xml.EAST, getTrainIconColorEast());
2215        values.setAttribute(Xml.WEST, getTrainIconColorWest());
2216        values.setAttribute(Xml.LOCAL, getTrainIconColorLocal());
2217        values.setAttribute(Xml.TERMINATE, getTrainIconColorTerminate());
2218
2219        e.addContent(values = new Element(Xml.COMMENTS));
2220        values.setAttribute(Xml.MISPLACED_CARS, getMiaComment());
2221
2222        e.addContent(values = new Element(Xml.DISPLAY));
2223        values.setAttribute(Xml.SHOW_TRACK_MOVES, isShowTrackMovesEnabled() ? Xml.TRUE : Xml.FALSE);
2224
2225        if (isVsdPhysicalLocationEnabled()) {
2226            e.addContent(values = new Element(Xml.VSD));
2227            values.setAttribute(Xml.ENABLE_PHYSICAL_LOCATIONS, isVsdPhysicalLocationEnabled() ? Xml.TRUE : Xml.FALSE);
2228        }
2229        // Save CATS setting
2230        e.addContent(values = new Element(Xml.CATS));
2231        values.setAttribute(Xml.EXACT_LOCATION_NAME,
2232                AbstractOperationsServer.isExactLoationNameEnabled() ? Xml.TRUE : Xml.FALSE);
2233        // day to name mapping
2234        e.addContent(values = new Element(Xml.DAY_NAME_MAP));
2235        for (int i = 0; i < Control.numberOfDays; i++) {
2236            Element map;
2237            String day = Integer.toString(i);
2238            String name = getDefault().hashTableDayToName.get(day);
2239            if (name != null && !name.isBlank()) {
2240                values.addContent(map = new Element(Xml.MAP));
2241                map.setAttribute(Xml.DAY, day);
2242                map.setAttribute(Xml.NAME, name);
2243            }
2244        }
2245        return e;
2246    }
2247
2248    private static void storeXmlMessageFormat(Element values, String prefix, String[] messageFormat) {
2249        values.setAttribute(Xml.PREFIX, prefix);
2250        StringBuilder buf = new StringBuilder();
2251        stringToTagConversion(messageFormat);
2252        for (String attibute : messageFormat) {
2253            buf.append(attibute).append(",");
2254        }
2255        values.setAttribute(Xml.SETTING, buf.toString());
2256    }
2257
2258    public static void load(Element e) {
2259        if (e.getChild(Xml.OPERATIONS) == null) {
2260            log.warn("OperationsPro settings values not found");
2261            return;
2262        }
2263        Element operations = e.getChild(Xml.OPERATIONS);
2264        org.jdom2.Attribute a;
2265
2266        if ((operations.getChild(Xml.RAIL_ROAD) != null) &&
2267                (a = operations.getChild(Xml.RAIL_ROAD).getAttribute(Xml.NAME)) != null) {
2268            String name = a.getValue();
2269            log.debug("railroadName: {}", name);
2270            // code before 4.11 "useJmriRailroadName" when using the preferences railroad
2271            // name.
2272            // here for backwards compatibility
2273            if (!name.equals(Xml.USE_JMRI_RAILROAD_NAME)) {
2274                getDefault().railroadName = name; // don't set the dirty bit
2275            }
2276        }
2277
2278        if ((operations.getChild(Xml.SETUP) != null) &&
2279                (a = operations.getChild(Xml.SETUP).getAttribute(Xml.COMMENT)) != null) {
2280            String comment = a.getValue();
2281            log.debug("setup comment: {}", comment);
2282            getDefault().setupComment = comment;
2283        }
2284
2285        if (operations.getChild(Xml.SETTINGS) != null) {
2286            if ((a = operations.getChild(Xml.SETTINGS).getAttribute(Xml.MAIN_MENU)) != null) {
2287                String enabled = a.getValue();
2288                log.debug("mainMenu: {}", enabled);
2289                setMainMenuEnabled(enabled.equals(Xml.TRUE));
2290            }
2291            if ((a = operations.getChild(Xml.SETTINGS).getAttribute(Xml.CLOSE_ON_SAVE)) != null) {
2292                String enabled = a.getValue();
2293                log.debug("closeOnSave: {}", enabled);
2294                setCloseWindowOnSaveEnabled(enabled.equals(Xml.TRUE));
2295            }
2296            if ((a = operations.getChild(Xml.SETTINGS).getAttribute(Xml.TRAIN_DIRECTION)) != null) {
2297                String dir = a.getValue();
2298                log.debug("direction: {}", dir);
2299                try {
2300                    getDefault().traindir = Integer.parseInt(dir);
2301                } catch (NumberFormatException ee) {
2302                    log.error("Train direction ({}) isn't a valid number", a.getValue());
2303                }
2304            }
2305            if ((a = operations.getChild(Xml.SETTINGS).getAttribute(Xml.TRAIN_LENGTH)) != null) {
2306                String length = a.getValue();
2307                log.debug("Max train length: {}", length);
2308                try {
2309                    setMaxTrainLength(Integer.parseInt(length));
2310                } catch (NumberFormatException ee) {
2311                    log.error("Train maximum length ({}) isn't a valid number", a.getValue());
2312                }
2313            }
2314            if ((a = operations.getChild(Xml.SETTINGS).getAttribute(Xml.MAX_ENGINES)) != null) {
2315                String size = a.getValue();
2316                log.debug("Max number of engines: {}", size);
2317                try {
2318                    setMaxNumberEngines(Integer.parseInt(size));
2319                } catch (NumberFormatException ee) {
2320                    log.error("Maximum number of engines ({}) isn't a valid number", a.getValue());
2321                }
2322            }
2323            if ((a = operations.getChild(Xml.SETTINGS).getAttribute(Xml.HPT)) != null) {
2324                String value = a.getValue();
2325                log.debug("HPT: {}", value);
2326                try {
2327                    setHorsePowerPerTon(Double.parseDouble(value));
2328                } catch (NumberFormatException ee) {
2329                    log.error("Train HPT ({}) isn't a valid number", a.getValue());
2330                }
2331            }
2332            if ((a = operations.getChild(Xml.SETTINGS).getAttribute(Xml.SCALE)) != null) {
2333                String scale = a.getValue();
2334                log.debug("scale: {}", scale);
2335                try {
2336                    setScale(Integer.parseInt(scale));
2337                } catch (NumberFormatException ee) {
2338                    log.error("Scale ({}) isn't a valid number", a.getValue());
2339                }
2340            }
2341            if ((a = operations.getChild(Xml.SETTINGS).getAttribute(Xml.CAR_TYPES)) != null) {
2342                String types = a.getValue();
2343                log.debug("CarTypes: {}", types);
2344                setCarTypes(types);
2345            }
2346            if ((a = operations.getChild(Xml.SETTINGS).getAttribute(Xml.SWITCH_TIME)) != null) {
2347                String minutes = a.getValue();
2348                log.debug("switchTime: {}", minutes);
2349                try {
2350                    setSwitchTime(Integer.parseInt(minutes));
2351                } catch (NumberFormatException ee) {
2352                    log.error("Switch time ({}) isn't a valid number", a.getValue());
2353                }
2354            }
2355            if ((a = operations.getChild(Xml.SETTINGS).getAttribute(Xml.TRAVEL_TIME)) != null) {
2356                String minutes = a.getValue();
2357                log.debug("travelTime: {}", minutes);
2358                try {
2359                    setTravelTime(Integer.parseInt(minutes));
2360                } catch (NumberFormatException ee) {
2361                    log.error("Travel time ({}) isn't a valid number", a.getValue());
2362                }
2363            }
2364            if ((a = operations.getChild(Xml.SETTINGS).getAttribute(Xml.SHOW_VALUE)) != null) {
2365                String enable = a.getValue();
2366                log.debug("showValue: {}", enable);
2367                setValueEnabled(enable.equals(Xml.TRUE));
2368            }
2369            if ((a = operations.getChild(Xml.SETTINGS).getAttribute(Xml.VALUE_LABEL)) != null) {
2370                String label = a.getValue();
2371                log.debug("valueLabel: {}", label);
2372                setValueLabel(label);
2373            }
2374            if ((a = operations.getChild(Xml.SETTINGS).getAttribute(Xml.SHOW_RFID)) != null) {
2375                String enable = a.getValue();
2376                log.debug("showRfid: {}", enable);
2377                setRfidEnabled(enable.equals(Xml.TRUE));
2378            }
2379            if ((a = operations.getChild(Xml.SETTINGS).getAttribute(Xml.RFID_LABEL)) != null) {
2380                String label = a.getValue();
2381                log.debug("rfidLabel: {}", label);
2382                setRfidLabel(label);
2383            }
2384            if ((a = operations.getChild(Xml.SETTINGS).getAttribute(Xml.LENGTH_UNIT)) != null) {
2385                String unit = a.getValue();
2386                log.debug("lengthUnit: {}", unit);
2387                setLengthUnit(unit);
2388            }
2389            if ((a = operations.getChild(Xml.SETTINGS).getAttribute(Xml.YEAR_MODELED)) != null) {
2390                String year = a.getValue();
2391                log.debug("yearModeled: {}", year);
2392                setYearModeled(year);
2393            }
2394            // next eight attributes are here for backward compatibility
2395            if ((a = operations.getChild(Xml.SETTINGS).getAttribute(Xml.PRINT_LOC_COMMENTS)) != null) {
2396                String enable = a.getValue();
2397                log.debug("printLocComments: {}", enable);
2398                setPrintLocationCommentsEnabled(enable.equals(Xml.TRUE));
2399            }
2400            if ((a = operations.getChild(Xml.SETTINGS).getAttribute(Xml.PRINT_ROUTE_COMMENTS)) != null) {
2401                String enable = a.getValue();
2402                log.debug("printRouteComments: {}", enable);
2403                setPrintRouteCommentsEnabled(enable.equals(Xml.TRUE));
2404            }
2405            if ((a = operations.getChild(Xml.SETTINGS).getAttribute(Xml.PRINT_LOADS_EMPTIES)) != null) {
2406                String enable = a.getValue();
2407                log.debug("printLoadsEmpties: {}", enable);
2408                setPrintLoadsAndEmptiesEnabled(enable.equals(Xml.TRUE));
2409            }
2410            if ((a = operations.getChild(Xml.SETTINGS).getAttribute(Xml.PRINT_TRAIN_SCHEDULE)) != null) {
2411                String enable = a.getValue();
2412                log.debug("printTrainSchedule: {}", enable);
2413                setPrintTrainScheduleNameEnabled(enable.equals(Xml.TRUE));
2414            }
2415            if ((a = operations.getChild(Xml.SETTINGS).getAttribute(Xml.USE12HR_FORMAT)) != null) {
2416                String enable = a.getValue();
2417                log.debug("use12hrFormat: {}", enable);
2418                set12hrFormatEnabled(enable.equals(Xml.TRUE));
2419            }
2420            if ((a = operations.getChild(Xml.SETTINGS).getAttribute(Xml.PRINT_VALID)) != null) {
2421                String enable = a.getValue();
2422                log.debug("printValid: {}", enable);
2423                setPrintValidEnabled(enable.equals(Xml.TRUE));
2424            }
2425            if ((a = operations.getChild(Xml.SETTINGS).getAttribute(Xml.SORT_BY_TRACK)) != null) {
2426                String enable = a.getValue();
2427                log.debug("sortByTrack: {}", enable);
2428                setSortByTrackNameEnabled(enable.equals(Xml.TRUE));
2429            }
2430            if ((a = operations.getChild(Xml.SETTINGS).getAttribute(Xml.PRINT_HEADERS)) != null) {
2431                String enable = a.getValue();
2432                log.debug("printHeaders: {}", enable);
2433                setPrintHeadersEnabled(enable.equals(Xml.TRUE));
2434            }
2435        }
2436        if (operations.getChild(Xml.PICKUP_ENG_FORMAT) != null) {
2437            if ((a = operations.getChild(Xml.PICKUP_ENG_FORMAT).getAttribute(Xml.PREFIX)) != null) {
2438                setPickupEnginePrefix(a.getValue());
2439            }
2440            if ((a = operations.getChild(Xml.PICKUP_ENG_FORMAT).getAttribute(Xml.SETTING)) != null) {
2441                String setting = a.getValue();
2442                log.debug("pickupEngFormat: {}", setting);
2443                String[] keys = setting.split(",");
2444                xmlAttributeToKeyConversion(keys);
2445                keyToStringConversion(keys);
2446                setPickupEngineMessageFormat(keys);
2447            }
2448        }
2449        if (operations.getChild(Xml.DROP_ENG_FORMAT) != null) {
2450            if ((a = operations.getChild(Xml.DROP_ENG_FORMAT).getAttribute(Xml.PREFIX)) != null) {
2451                setDropEnginePrefix(a.getValue());
2452            }
2453            if ((a = operations.getChild(Xml.DROP_ENG_FORMAT).getAttribute(Xml.SETTING)) != null) {
2454                String setting = a.getValue();
2455                log.debug("dropEngFormat: {}", setting);
2456                String[] keys = setting.split(",");
2457                xmlAttributeToKeyConversion(keys);
2458                keyToStringConversion(keys);
2459                setDropEngineMessageFormat(keys);
2460            }
2461        }
2462        if (operations.getChild(Xml.PICKUP_CAR_FORMAT) != null) {
2463            if ((a = operations.getChild(Xml.PICKUP_CAR_FORMAT).getAttribute(Xml.PREFIX)) != null) {
2464                setPickupCarPrefix(a.getValue());
2465            }
2466            if ((a = operations.getChild(Xml.PICKUP_CAR_FORMAT).getAttribute(Xml.SETTING)) != null) {
2467                String setting = a.getValue();
2468                log.debug("pickupCarFormat: {}", setting);
2469                String[] keys = setting.split(",");
2470                replaceOldFormat(keys);
2471                xmlAttributeToKeyConversion(keys);
2472                keyToStringConversion(keys);
2473                setPickupManifestMessageFormat(keys);
2474            }
2475        }
2476        if (operations.getChild(Xml.DROP_CAR_FORMAT) != null) {
2477            if ((a = operations.getChild(Xml.DROP_CAR_FORMAT).getAttribute(Xml.PREFIX)) != null) {
2478                setDropCarPrefix(a.getValue());
2479            }
2480            if ((a = operations.getChild(Xml.DROP_CAR_FORMAT).getAttribute(Xml.SETTING)) != null) {
2481                String setting = a.getValue();
2482                log.debug("dropCarFormat: {}", setting);
2483                String[] keys = setting.split(",");
2484                replaceOldFormat(keys);
2485                xmlAttributeToKeyConversion(keys);
2486                keyToStringConversion(keys);
2487                setDropManifestMessageFormat(keys);
2488            }
2489        }
2490        if (operations.getChild(Xml.LOCAL_FORMAT) != null) {
2491            if ((a = operations.getChild(Xml.LOCAL_FORMAT).getAttribute(Xml.PREFIX)) != null) {
2492                setLocalPrefix(a.getValue());
2493            }
2494            if ((a = operations.getChild(Xml.LOCAL_FORMAT).getAttribute(Xml.SETTING)) != null) {
2495                String setting = a.getValue();
2496                log.debug("localFormat: {}", setting);
2497                String[] keys = setting.split(",");
2498                replaceOldFormat(keys);
2499                xmlAttributeToKeyConversion(keys);
2500                keyToStringConversion(keys);
2501                setLocalManifestMessageFormat(keys);
2502            }
2503        }
2504        if (operations.getChild(Xml.MISSING_CAR_FORMAT) != null) {
2505            if ((a = operations.getChild(Xml.MISSING_CAR_FORMAT).getAttribute(Xml.SETTING)) != null) {
2506                String setting = a.getValue();
2507                log.debug("missingCarFormat: {}", setting);
2508                String[] keys = setting.split(",");
2509                keyToStringConversion(keys);
2510                setMissingCarMessageFormat(keys);
2511            }
2512        }
2513        if (operations.getChild(Xml.SWITCH_LIST) != null) {
2514            if ((a = operations.getChild(Xml.SWITCH_LIST).getAttribute(Xml.SAME_AS_MANIFEST)) != null) {
2515                String b = a.getValue();
2516                log.debug("sameAsManifest: {}", b);
2517                setSwitchListFormatSameAsManifest(b.equals(Xml.TRUE));
2518            }
2519            if ((a = operations.getChild(Xml.SWITCH_LIST).getAttribute(Xml.REAL_TIME)) != null) {
2520                String b = a.getValue();
2521                log.debug("realTime: {}", b);
2522                getDefault().switchListRealTime = b.equals(Xml.TRUE);
2523            }
2524            if ((a = operations.getChild(Xml.SWITCH_LIST).getAttribute(Xml.ALL_TRAINS)) != null) {
2525                String b = a.getValue();
2526                log.debug("allTrains: {}", b);
2527                getDefault().switchListAllTrains = b.equals(Xml.TRUE);
2528            }
2529            if ((a = operations.getChild(Xml.SWITCH_LIST).getAttribute(Xml.PAGE_FORMAT)) != null) {
2530                switch (a.getValue()) {
2531                    case Xml.PAGE_NORMAL:
2532                        getDefault().switchListPageFormat = PAGE_NORMAL;
2533                        break;
2534                    case Xml.PAGE_PER_TRAIN:
2535                        getDefault().switchListPageFormat = PAGE_PER_TRAIN;
2536                        break;
2537                    case Xml.PAGE_PER_VISIT:
2538                        getDefault().switchListPageFormat = PAGE_PER_VISIT;
2539                        break;
2540                    default:
2541                        log.error("Unknown switch list page format {}", a.getValue());
2542                }
2543            } // old way to save switch list page format pre 3.11
2544            else if ((a = operations.getChild(Xml.SWITCH_LIST).getAttribute(Xml.PAGE_MODE)) != null) {
2545                String b = a.getValue();
2546                log.debug("old style pageMode: {}", b);
2547                if (b.equals(Xml.TRUE)) {
2548                    getDefault().switchListPageFormat = PAGE_PER_TRAIN;
2549                }
2550            }
2551            if ((a = operations.getChild(Xml.SWITCH_LIST).getAttribute(Xml.PRINT_ROUTE_LOCATION)) != null) {
2552                String b = a.getValue();
2553                log.debug("print route location comment: {}", b);
2554                setSwitchListRouteLocationCommentEnabled(b.equals(Xml.TRUE));
2555            }
2556            if ((a = operations.getChild(Xml.SWITCH_LIST).getAttribute(Xml.TRACK_SUMMARY)) != null) {
2557                String b = a.getValue();
2558                log.debug("track summary: {}", b);
2559                setPrintTrackSummaryEnabled(b.equals(Xml.TRUE));
2560            }
2561            if ((a = operations.getChild(Xml.SWITCH_LIST).getAttribute(Xml.USE_DEPARTURE_TIME)) != null) {
2562                String b = a.getValue();
2563                log.debug("switch list departure time: {}", b);
2564                setUseSwitchListDepartureTimeEnabled(b.equals(Xml.TRUE));
2565            }
2566        }
2567        if (operations.getChild(Xml.SWITCH_LIST_PICKUP_CAR_FORMAT) != null) {
2568            if ((a = operations.getChild(Xml.SWITCH_LIST_PICKUP_CAR_FORMAT).getAttribute(Xml.PREFIX)) != null) {
2569                setSwitchListPickupCarPrefix(a.getValue());
2570            }
2571            if ((a = operations.getChild(Xml.SWITCH_LIST_PICKUP_CAR_FORMAT).getAttribute(Xml.SETTING)) != null) {
2572                String setting = a.getValue();
2573                log.debug("switchListpickupCarFormat: {}", setting);
2574                String[] keys = setting.split(",");
2575                replaceOldFormat(keys);
2576                xmlAttributeToKeyConversion(keys);
2577                keyToStringConversion(keys);
2578                setPickupSwitchListMessageFormat(keys);
2579            }
2580        }
2581        if (operations.getChild(Xml.SWITCH_LIST_DROP_CAR_FORMAT) != null) {
2582            if ((a = operations.getChild(Xml.SWITCH_LIST_DROP_CAR_FORMAT).getAttribute(Xml.PREFIX)) != null) {
2583                setSwitchListDropCarPrefix(a.getValue());
2584            }
2585            if ((a = operations.getChild(Xml.SWITCH_LIST_DROP_CAR_FORMAT).getAttribute(Xml.SETTING)) != null) {
2586                String setting = a.getValue();
2587                log.debug("switchListDropCarFormat: {}", setting);
2588                String[] keys = setting.split(",");
2589                replaceOldFormat(keys);
2590                xmlAttributeToKeyConversion(keys);
2591                keyToStringConversion(keys);
2592                setDropSwitchListMessageFormat(keys);
2593            }
2594        }
2595        if (operations.getChild(Xml.SWITCH_LIST_LOCAL_FORMAT) != null) {
2596            if ((a = operations.getChild(Xml.SWITCH_LIST_LOCAL_FORMAT).getAttribute(Xml.PREFIX)) != null) {
2597                setSwitchListLocalPrefix(a.getValue());
2598            }
2599            if ((a = operations.getChild(Xml.SWITCH_LIST_LOCAL_FORMAT).getAttribute(Xml.SETTING)) != null) {
2600                String setting = a.getValue();
2601                log.debug("switchListLocalFormat: {}", setting);
2602                String[] keys = setting.split(",");
2603                replaceOldFormat(keys);
2604                xmlAttributeToKeyConversion(keys);
2605                keyToStringConversion(keys);
2606                setLocalSwitchListMessageFormat(keys);
2607            }
2608        }
2609        if (operations.getChild(Xml.PANEL) != null) {
2610            if ((a = operations.getChild(Xml.PANEL).getAttribute(Xml.NAME)) != null) {
2611                String panel = a.getValue();
2612                log.debug("panel: {}", panel);
2613                setPanelName(panel);
2614            }
2615            if ((a = operations.getChild(Xml.PANEL).getAttribute(Xml.TRAIN_ICONXY)) != null) {
2616                String enable = a.getValue();
2617                log.debug("TrainIconXY: {}", enable);
2618                setTrainIconCordEnabled(enable.equals(Xml.TRUE));
2619            }
2620            if ((a = operations.getChild(Xml.PANEL).getAttribute(Xml.TRAIN_ICON_APPEND)) != null) {
2621                String enable = a.getValue();
2622                log.debug("TrainIconAppend: {}", enable);
2623                setTrainIconAppendEnabled(enable.equals(Xml.TRUE));
2624            }
2625        }
2626        if ((operations.getChild(Xml.FONT_NAME) != null) &&
2627                (a = operations.getChild(Xml.FONT_NAME).getAttribute(Xml.NAME)) != null) {
2628            String font = a.getValue();
2629            log.debug("fontName: {}", font);
2630            setFontName(font);
2631        }
2632        if ((operations.getChild(Xml.FONT_SIZE) != null) &&
2633                (a = operations.getChild(Xml.FONT_SIZE).getAttribute(Xml.SIZE)) != null) {
2634            String size = a.getValue();
2635            log.debug("fontsize: {}", size);
2636            try {
2637                setManifestFontSize(Integer.parseInt(size));
2638            } catch (NumberFormatException ee) {
2639                log.error("Manifest font size ({}) isn't a valid number", a.getValue());
2640            }
2641        }
2642        if ((operations.getChild(Xml.PAGE_ORIENTATION) != null)) {
2643            if ((a = operations.getChild(Xml.PAGE_ORIENTATION).getAttribute(Xml.MANIFEST)) != null) {
2644                String orientation = a.getValue();
2645                log.debug("manifestOrientation: {}", orientation);
2646                setManifestOrientation(orientation);
2647            }
2648            if ((a = operations.getChild(Xml.PAGE_ORIENTATION).getAttribute(Xml.SWITCH_LIST)) != null) {
2649                String orientation = a.getValue();
2650                log.debug("switchListOrientation: {}", orientation);
2651                setSwitchListOrientation(orientation);
2652            }
2653        }
2654        if ((operations.getChild(Xml.PRINT_DUPLEX) != null)) {
2655            if ((a = operations.getChild(Xml.PRINT_DUPLEX).getAttribute(Xml.NAME)) != null) {
2656                String sides = a.getValue();
2657                log.debug("Print duplex: {}", sides);
2658                if (sides.equals(SidesType.TWO_SIDED_LONG_EDGE.toString())) {
2659                    setPrintDuplexSides(Sides.TWO_SIDED_LONG_EDGE);
2660                }
2661                if (sides.equals(SidesType.TWO_SIDED_SHORT_EDGE.toString())) {
2662                    setPrintDuplexSides(Sides.TWO_SIDED_SHORT_EDGE);
2663                }
2664            }
2665        }
2666        if ((operations.getChild(Xml.MANIFEST_COLORS) != null)) {
2667            if ((a = operations.getChild(Xml.MANIFEST_COLORS).getAttribute(Xml.DROP_COLOR)) != null) {
2668                String dropColor = a.getValue();
2669                log.debug("dropColor: {}", dropColor);
2670                setDropTextColor(dropColor);
2671            }
2672            if ((a = operations.getChild(Xml.MANIFEST_COLORS).getAttribute(Xml.PICKUP_COLOR)) != null) {
2673                String pickupColor = a.getValue();
2674                log.debug("pickupColor: {}", pickupColor);
2675                setPickupTextColor(pickupColor);
2676            }
2677            if ((a = operations.getChild(Xml.MANIFEST_COLORS).getAttribute(Xml.LOCAL_COLOR)) != null) {
2678                String localColor = a.getValue();
2679                log.debug("localColor: {}", localColor);
2680                setLocalTextColor(localColor);
2681            }
2682            if ((a = operations.getChild(Xml.MANIFEST_COLORS).getAttribute(Xml.DROP_ENGINE_COLOR)) != null) {
2683                String dropColor = a.getValue();
2684                log.debug("dropEngineColor: {}", dropColor);
2685                setDropEngineTextColor(dropColor);
2686            } else {
2687                // Engine drop color didn't exist before 5.11.3
2688                setDropEngineTextColor(getDropTextColor());
2689            }
2690            if ((a = operations.getChild(Xml.MANIFEST_COLORS).getAttribute(Xml.PICKUP_ENGINE_COLOR)) != null) {
2691                String pickupColor = a.getValue();
2692                log.debug("pickupEngineColor: {}", pickupColor);
2693                setPickupEngineTextColor(pickupColor);
2694            } else {
2695                // Engine pick up color didn't exist before 5.11.3
2696                setPickupEngineTextColor(getPickupTextColor());
2697            }
2698        }
2699        if ((operations.getChild(Xml.TAB) != null)) {
2700            if ((a = operations.getChild(Xml.TAB).getAttribute(Xml.ENABLED)) != null) {
2701                String enable = a.getValue();
2702                log.debug("tab: {}", enable);
2703                setTabEnabled(enable.equals(Xml.TRUE));
2704            }
2705            if ((a = operations.getChild(Xml.TAB).getAttribute(Xml.LENGTH)) != null) {
2706                String length = a.getValue();
2707                log.debug("tab 1 length: {}", length);
2708                try {
2709                    setTab1length(Integer.parseInt(length));
2710                } catch (NumberFormatException ee) {
2711                    log.error("Tab 1 length ({}) isn't a valid number", a.getValue());
2712                }
2713            }
2714            if ((a = operations.getChild(Xml.TAB).getAttribute(Xml.TAB2_LENGTH)) != null) {
2715                String length = a.getValue();
2716                log.debug("tab 2 length: {}", length);
2717                try {
2718                    setTab2length(Integer.parseInt(length));
2719                } catch (NumberFormatException ee) {
2720                    log.error("Tab 2 length ({}) isn't a valid number", a.getValue());
2721                }
2722            }
2723            if ((a = operations.getChild(Xml.TAB).getAttribute(Xml.TAB3_LENGTH)) != null) {
2724                String length = a.getValue();
2725                log.debug("tab 3 length: {}", length);
2726                try {
2727                    setTab3length(Integer.parseInt(length));
2728                } catch (NumberFormatException ee) {
2729                    log.error("Tab 3 length ({}) isn't a valid number", a.getValue());
2730                }
2731            }
2732        }
2733        if ((operations.getChild(Xml.MANIFEST) != null)) {
2734            if ((a = operations.getChild(Xml.MANIFEST).getAttribute(Xml.PRINT_LOC_COMMENTS)) != null) {
2735                String enable = a.getValue();
2736                log.debug("manifest printLocComments: {}", enable);
2737                setPrintLocationCommentsEnabled(enable.equals(Xml.TRUE));
2738            }
2739            if ((a = operations.getChild(Xml.MANIFEST).getAttribute(Xml.PRINT_ROUTE_COMMENTS)) != null) {
2740                String enable = a.getValue();
2741                log.debug("manifest printRouteComments: {}", enable);
2742                setPrintRouteCommentsEnabled(enable.equals(Xml.TRUE));
2743            }
2744            if ((a = operations.getChild(Xml.MANIFEST).getAttribute(Xml.PRINT_LOADS_EMPTIES)) != null) {
2745                String enable = a.getValue();
2746                log.debug("manifest printLoadsEmpties: {}", enable);
2747                setPrintLoadsAndEmptiesEnabled(enable.equals(Xml.TRUE));
2748            }
2749            if ((a = operations.getChild(Xml.MANIFEST).getAttribute(Xml.PRINT_TRAIN_SCHEDULE)) != null) {
2750                String enable = a.getValue();
2751                log.debug("manifest printTrainSchedule: {}", enable);
2752                setPrintTrainScheduleNameEnabled(enable.equals(Xml.TRUE));
2753            }
2754            if ((a = operations.getChild(Xml.MANIFEST).getAttribute(Xml.USE12HR_FORMAT)) != null) {
2755                String enable = a.getValue();
2756                log.debug("manifest use12hrFormat: {}", enable);
2757                set12hrFormatEnabled(enable.equals(Xml.TRUE));
2758            }
2759            if ((a = operations.getChild(Xml.MANIFEST).getAttribute(Xml.PRINT_VALID)) != null) {
2760                String enable = a.getValue();
2761                log.debug("manifest printValid: {}", enable);
2762                setPrintValidEnabled(enable.equals(Xml.TRUE));
2763            }
2764            if ((a = operations.getChild(Xml.MANIFEST).getAttribute(Xml.SORT_BY_TRACK)) != null) {
2765                String enable = a.getValue();
2766                log.debug("manifest sortByTrack: {}", enable);
2767                setSortByTrackNameEnabled(enable.equals(Xml.TRUE));
2768            }
2769            if ((a = operations.getChild(Xml.MANIFEST).getAttribute(Xml.PRINT_PAGE_HEADER)) != null) {
2770                String enable = a.getValue();
2771                log.debug("manifest printPageHeader: {}", enable);
2772                setPrintPageHeaderEnabled(enable.equals(Xml.TRUE));
2773            }
2774            if ((a = operations.getChild(Xml.MANIFEST).getAttribute(Xml.PRINT_HEADERS)) != null) {
2775                String enable = a.getValue();
2776                log.debug("manifest print headers: {}", enable);
2777                setPrintHeadersEnabled(enable.equals(Xml.TRUE));
2778            }
2779            if ((a = operations.getChild(Xml.MANIFEST).getAttribute(Xml.PRINT_NO_PAGE_BREAKS)) != null) {
2780                String enable = a.getValue();
2781                log.debug("printNoPageBreaks: {}", enable);
2782                setPrintNoPageBreaksEnabled(enable.equals(Xml.TRUE));
2783            }
2784            if ((a = operations.getChild(Xml.MANIFEST).getAttribute(Xml.TRUNCATE)) != null) {
2785                String enable = a.getValue();
2786                log.debug("manifest truncate: {}", enable);
2787                setPrintTruncateManifestEnabled(enable.equals(Xml.TRUE));
2788            }
2789            if ((a = operations.getChild(Xml.MANIFEST).getAttribute(Xml.USE_DEPARTURE_TIME)) != null) {
2790                String enable = a.getValue();
2791                log.debug("manifest use departure time: {}", enable);
2792                setUseDepartureTimeEnabled(enable.equals(Xml.TRUE));
2793            }
2794            if ((a = operations.getChild(Xml.MANIFEST).getAttribute(Xml.USE_EDITOR)) != null) {
2795                String enable = a.getValue();
2796                log.debug("manifest useEditor: {}", enable);
2797                setManifestEditorEnabled(enable.equals(Xml.TRUE));
2798            }
2799            if ((a = operations.getChild(Xml.MANIFEST).getAttribute(Xml.PRINT_CABOOSE_LOAD)) != null) {
2800                String enable = a.getValue();
2801                log.debug("manifest print caboose load: {}", enable);
2802                setPrintCabooseLoadEnabled(enable.equals(Xml.TRUE));
2803            }
2804            if ((a = operations.getChild(Xml.MANIFEST).getAttribute(Xml.PRINT_PASSENGER_LOAD)) != null) {
2805                String enable = a.getValue();
2806                log.debug("manifest print passenger load: {}", enable);
2807                setPrintPassengerLoadEnabled(enable.equals(Xml.TRUE));
2808            }
2809            if ((a = operations.getChild(Xml.MANIFEST).getAttribute(Xml.GROUP_MOVES)) != null) {
2810                String enable = a.getValue();
2811                log.debug("manifest group car moves: {}", enable);
2812                setGroupCarMoves(enable.equals(Xml.TRUE));
2813            }
2814            if ((a = operations.getChild(Xml.MANIFEST).getAttribute(Xml.PRINT_LOCO_LAST)) != null) {
2815                String enable = a.getValue();
2816                log.debug("manifest print loco last: {}", enable);
2817                setPrintLocoLast(enable.equals(Xml.TRUE));
2818            }
2819            if ((a = operations.getChild(Xml.MANIFEST).getAttribute(Xml.HAZARDOUS_MSG)) != null) {
2820                String message = a.getValue();
2821                log.debug("manifest hazardousMsg: {}", message);
2822                setHazardousMsg(message);
2823            }
2824        }
2825        if ((operations.getChild(Xml.MANIFEST_FORMAT) != null)) {
2826            if ((a = operations.getChild(Xml.MANIFEST_FORMAT).getAttribute(Xml.VALUE)) != null) {
2827                switch (a.getValue()) {
2828                    case Xml.STANDARD:
2829                        getDefault().manifestFormat = STANDARD_FORMAT;
2830                        break;
2831                    case Xml.TWO_COLUMN:
2832                        getDefault().manifestFormat = TWO_COLUMN_FORMAT;
2833                        break;
2834                    case Xml.TWO_COLUMN_TRACK:
2835                        getDefault().manifestFormat = TWO_COLUMN_TRACK_FORMAT;
2836                        break;
2837                    default:
2838                        log.debug("Unknown manifest format");
2839                }
2840            }
2841        } else if ((operations.getChild(Xml.COLUMN_FORMAT) != null)) {
2842            if ((a = operations.getChild(Xml.COLUMN_FORMAT).getAttribute(Xml.TWO_COLUMNS)) != null) {
2843                String enable = a.getValue();
2844                log.debug("two columns: {}", enable);
2845                if (enable.equals(Xml.TRUE)) {
2846                    setManifestFormat(TWO_COLUMN_FORMAT);
2847                }
2848            }
2849        }
2850        if ((operations.getChild(Xml.HEADER_LINES) != null)) {
2851            if ((a = operations.getChild(Xml.HEADER_LINES).getAttribute(Xml.PRINT_HEADER_LINE1)) != null) {
2852                String enable = a.getValue();
2853                setPrintHeaderLine1Enabled(enable.equals(Xml.TRUE));
2854            }
2855            if ((a = operations.getChild(Xml.HEADER_LINES).getAttribute(Xml.PRINT_HEADER_LINE2)) != null) {
2856                String enable = a.getValue();
2857                setPrintHeaderLine2Enabled(enable.equals(Xml.TRUE));
2858            }
2859            if ((a = operations.getChild(Xml.HEADER_LINES).getAttribute(Xml.PRINT_HEADER_LINE3)) != null) {
2860                String enable = a.getValue();
2861                setPrintHeaderLine3Enabled(enable.equals(Xml.TRUE));
2862            }
2863        }
2864        // get manifest logo
2865        if ((operations.getChild(Xml.MANIFEST_LOGO) != null)) {
2866            if ((a = operations.getChild(Xml.MANIFEST_LOGO).getAttribute(Xml.NAME)) != null) {
2867                setManifestLogoURL(a.getValue());
2868            }
2869        }
2870        // manifest file options
2871        if ((operations.getChild(Xml.MANIFEST_FILE_OPTIONS) != null)) {
2872            if ((a = operations.getChild(Xml.MANIFEST_FILE_OPTIONS).getAttribute(Xml.MANIFEST_SAVE)) != null) {
2873                String enable = a.getValue();
2874                log.debug("manifest file save option: {}", enable);
2875                getDefault().saveTrainManifests = enable.equals(Xml.TRUE);
2876            }
2877        }
2878        if ((operations.getChild(Xml.BUILD_OPTIONS) != null)) {
2879            if ((a = operations.getChild(Xml.BUILD_OPTIONS).getAttribute(Xml.AGGRESSIVE)) != null) {
2880                String enable = a.getValue();
2881                log.debug("aggressive: {}", enable);
2882                setBuildAggressive(enable.equals(Xml.TRUE));
2883            }
2884            if ((a = operations.getChild(Xml.BUILD_OPTIONS).getAttribute(Xml.NUMBER_PASSES)) != null) {
2885                String number = a.getValue();
2886                log.debug("number of passes: {}", number);
2887                try {
2888                    setNumberPasses(Integer.parseInt(number));
2889                } catch (NumberFormatException ne) {
2890                    log.debug("Number of passes isn't a number");
2891                }
2892            }
2893            if ((a = operations.getChild(Xml.BUILD_OPTIONS).getAttribute(Xml.ON_TIME)) != null) {
2894                String enable = a.getValue();
2895                log.debug("on time: {}", enable);
2896                setBuildOnTime(enable.equals(Xml.TRUE));
2897            }
2898            if ((a = operations.getChild(Xml.BUILD_OPTIONS).getAttribute(Xml.DWELL_TIME)) != null) {
2899                String minutes = a.getValue();
2900                log.debug("dwell time: {}", minutes);
2901                try {
2902                    setDwellTime(Integer.parseInt(minutes));
2903                } catch (NumberFormatException ne) {
2904                    log.debug("dwell time isn't a number");
2905                }
2906            }
2907            if ((a = operations.getChild(Xml.BUILD_OPTIONS).getAttribute(Xml.ALLOW_LOCAL_INTERCHANGE)) != null) {
2908                String enable = a.getValue();
2909                log.debug("allowLocalInterchangeMoves: {}", enable);
2910                setLocalInterchangeMovesEnabled(enable.equals(Xml.TRUE));
2911            }
2912            if ((a = operations.getChild(Xml.BUILD_OPTIONS).getAttribute(Xml.ALLOW_LOCAL_SPUR)) != null) {
2913                String enable = a.getValue();
2914                log.debug("allowLocalSpurMoves: {}", enable);
2915                setLocalSpurMovesEnabled(enable.equals(Xml.TRUE));
2916            } else if ((a = operations.getChild(Xml.BUILD_OPTIONS).getAttribute(Xml.ALLOW_LOCAL_SIDING)) != null) {
2917                String enable = a.getValue();
2918                log.debug("allowLocalSidingMoves: {}", enable);
2919                setLocalSpurMovesEnabled(enable.equals(Xml.TRUE));
2920            }
2921            if ((a = operations.getChild(Xml.BUILD_OPTIONS).getAttribute(Xml.ALLOW_LOCAL_YARD)) != null) {
2922                String enable = a.getValue();
2923                log.debug("allowLocalYardMoves: {}", enable);
2924                setLocalYardMovesEnabled(enable.equals(Xml.TRUE));
2925            }
2926            if ((a = operations.getChild(Xml.BUILD_OPTIONS).getAttribute(Xml.STAGING_RESTRICTION_ENABLED)) != null) {
2927                String enable = a.getValue();
2928                log.debug("stagingRestrictionEnabled: {}", enable);
2929                setStagingTrainCheckEnabled(enable.equals(Xml.TRUE));
2930            }
2931            if ((a = operations.getChild(Xml.BUILD_OPTIONS).getAttribute(Xml.STAGING_TRACK_AVAIL)) != null) {
2932                String enable = a.getValue();
2933                log.debug("stagingTrackAvail: {}", enable);
2934                setStagingTrackImmediatelyAvail(enable.equals(Xml.TRUE));
2935            }
2936            if ((a = operations.getChild(Xml.BUILD_OPTIONS).getAttribute(Xml.ALLOW_RETURN_STAGING)) != null) {
2937                String enable = a.getValue();
2938                log.debug("allowReturnStaging: {}", enable);
2939                getDefault().allowCarsReturnStaging = enable.equals(Xml.TRUE);
2940            }
2941            if ((a = operations.getChild(Xml.BUILD_OPTIONS).getAttribute(Xml.PROMPT_STAGING_ENABLED)) != null) {
2942                String enable = a.getValue();
2943                log.debug("promptStagingEnabled: {}", enable);
2944                setStagingPromptFromEnabled(enable.equals(Xml.TRUE));
2945            }
2946            if ((a = operations.getChild(Xml.BUILD_OPTIONS).getAttribute(Xml.PROMPT_TO_STAGING_ENABLED)) != null) {
2947                String enable = a.getValue();
2948                log.debug("promptToStagingEnabled: {}", enable);
2949                setStagingPromptToEnabled(enable.equals(Xml.TRUE));
2950            }
2951            if ((a = operations.getChild(Xml.BUILD_OPTIONS).getAttribute(Xml.STAGING_TRY_NORMAL)) != null) {
2952                String enable = a.getValue();
2953                log.debug("stagingTryNormalEnabled: {}", enable);
2954                setStagingTryNormalBuildEnabled(enable.equals(Xml.TRUE));
2955            }
2956            if ((a = operations.getChild(Xml.BUILD_OPTIONS).getAttribute(Xml.GENERATE_CSV_MANIFEST)) != null) {
2957                String enable = a.getValue();
2958                log.debug("generateCvsManifest: {}", enable);
2959                getDefault().generateCsvManifest = enable.equals(Xml.TRUE);
2960            }
2961            if ((a = operations.getChild(Xml.BUILD_OPTIONS).getAttribute(Xml.GENERATE_CSV_SWITCH_LIST)) != null) {
2962                String enable = a.getValue();
2963                log.debug("generateCvsSwitchList: {}", enable);
2964                getDefault().generateCsvSwitchList = enable.equals(Xml.TRUE);
2965            }
2966        }
2967        if (operations.getChild(Xml.BUILD_REPORT) != null) {
2968            if ((a = operations.getChild(Xml.BUILD_REPORT).getAttribute(Xml.LEVEL)) != null) {
2969                String level = a.getValue();
2970                log.debug("buildReportLevel: {}", level);
2971                setBuildReportLevel(level);
2972            }
2973            if ((a = operations.getChild(Xml.BUILD_REPORT).getAttribute(Xml.ROUTER_LEVEL)) != null) {
2974                String level = a.getValue();
2975                log.debug("routerBuildReportLevel: {}", level);
2976                setRouterBuildReportLevel(level);
2977            }
2978            if ((a = operations.getChild(Xml.BUILD_REPORT).getAttribute(Xml.USE_EDITOR)) != null) {
2979                String enable = a.getValue();
2980                log.debug("build report useEditor: {}", enable);
2981                setBuildReportEditorEnabled(enable.equals(Xml.TRUE));
2982            }
2983            if ((a = operations.getChild(Xml.BUILD_REPORT).getAttribute(Xml.INDENT)) != null) {
2984                String enable = a.getValue();
2985                log.debug("build report indent: {}", enable);
2986                setBuildReportIndentEnabled(enable.equals(Xml.TRUE));
2987            }
2988            if ((a = operations.getChild(Xml.BUILD_REPORT).getAttribute(Xml.FONT_SIZE)) != null) {
2989                String size = a.getValue();
2990                log.debug("build font size: {}", size);
2991                try {
2992                    setBuildReportFontSize(Integer.parseInt(size));
2993                } catch (NumberFormatException ee) {
2994                    log.error("Build report font size ({}) isn't a valid number", a.getValue());
2995                }
2996            }
2997            if ((a = operations.getChild(Xml.BUILD_REPORT).getAttribute(Xml.ALWAYS_PREVIEW)) != null) {
2998                String enable = a.getValue();
2999                log.debug("build report always preview: {}", enable);
3000                setBuildReportAlwaysPreviewEnabled(enable.equals(Xml.TRUE));
3001            }
3002        }
3003
3004        if (operations.getChild(Xml.ROUTER) != null) {
3005            if ((a = operations.getChild(Xml.ROUTER).getAttribute(Xml.CAR_ROUTING_ENABLED)) != null) {
3006                String enable = a.getValue();
3007                log.debug("carRoutingEnabled: {}", enable);
3008                setCarRoutingEnabled(enable.equals(Xml.TRUE));
3009            }
3010            if ((a = operations.getChild(Xml.ROUTER).getAttribute(Xml.CAR_ROUTING_VIA_YARDS)) != null) {
3011                String enable = a.getValue();
3012                log.debug("carRoutingViaYards: {}", enable);
3013                setCarRoutingViaYardsEnabled(enable.equals(Xml.TRUE));
3014            }
3015            if ((a = operations.getChild(Xml.ROUTER).getAttribute(Xml.CAR_ROUTING_VIA_STAGING)) != null) {
3016                String enable = a.getValue();
3017                log.debug("carRoutingViaStaging: {}", enable);
3018                setCarRoutingViaStagingEnabled(enable.equals(Xml.TRUE));
3019            }
3020            if ((a = operations.getChild(Xml.ROUTER).getAttribute(Xml.FORWARD_TO_YARD)) != null) {
3021                String enable = a.getValue();
3022                log.debug("forwardToYard: {}", enable);
3023                setForwardToYardEnabled(enable.equals(Xml.TRUE));
3024            }
3025            if ((a = operations.getChild(Xml.ROUTER).getAttribute(Xml.ONLY_ACTIVE_TRAINS)) != null) {
3026                String enable = a.getValue();
3027                log.debug("onlyActiveTrains: {}", enable);
3028                setOnlyActiveTrainsEnabled(enable.equals(Xml.TRUE));
3029            }
3030            if ((a = operations.getChild(Xml.ROUTER).getAttribute(Xml.CHECK_CAR_DESTINATION)) != null) {
3031                String enable = a.getValue();
3032                log.debug("checkCarDestination: {}", enable);
3033                setCheckCarDestinationEnabled(enable.equals(Xml.TRUE));
3034            }
3035        } else if (operations.getChild(Xml.SETTINGS) != null) {
3036            // the next four items are for backwards compatibility
3037            if ((a = operations.getChild(Xml.SETTINGS).getAttribute(Xml.CAR_ROUTING_ENABLED)) != null) {
3038                String enable = a.getValue();
3039                log.debug("carRoutingEnabled: {}", enable);
3040                setCarRoutingEnabled(enable.equals(Xml.TRUE));
3041            }
3042            if ((a = operations.getChild(Xml.SETTINGS).getAttribute(Xml.CAR_ROUTING_VIA_YARDS)) != null) {
3043                String enable = a.getValue();
3044                log.debug("carRoutingViaYards: {}", enable);
3045                setCarRoutingViaYardsEnabled(enable.equals(Xml.TRUE));
3046            }
3047            if ((a = operations.getChild(Xml.SETTINGS).getAttribute(Xml.CAR_ROUTING_VIA_STAGING)) != null) {
3048                String enable = a.getValue();
3049                log.debug("carRoutingViaStaging: {}", enable);
3050                setCarRoutingViaStagingEnabled(enable.equals(Xml.TRUE));
3051            }
3052            if ((a = operations.getChild(Xml.SETTINGS).getAttribute(Xml.FORWARD_TO_YARD)) != null) {
3053                String enable = a.getValue();
3054                log.debug("forwardToYard: {}", enable);
3055                setForwardToYardEnabled(enable.equals(Xml.TRUE));
3056            }
3057        }
3058
3059        if ((operations.getChild(Xml.OWNER) != null) &&
3060                (a = operations.getChild(Xml.OWNER).getAttribute(Xml.NAME)) != null) {
3061            String owner = a.getValue();
3062            log.debug("owner: {}", owner);
3063            setOwnerName(owner);
3064        }
3065        if (operations.getChild(Xml.ICON_COLOR) != null) {
3066            if ((a = operations.getChild(Xml.ICON_COLOR).getAttribute(Xml.NORTH)) != null) {
3067                String color = a.getValue();
3068                log.debug("north color: {}", color);
3069                setTrainIconColorNorth(color);
3070            }
3071            if ((a = operations.getChild(Xml.ICON_COLOR).getAttribute(Xml.SOUTH)) != null) {
3072                String color = a.getValue();
3073                log.debug("south color: {}", color);
3074                setTrainIconColorSouth(color);
3075            }
3076            if ((a = operations.getChild(Xml.ICON_COLOR).getAttribute(Xml.EAST)) != null) {
3077                String color = a.getValue();
3078                log.debug("east color: {}", color);
3079                setTrainIconColorEast(color);
3080            }
3081            if ((a = operations.getChild(Xml.ICON_COLOR).getAttribute(Xml.WEST)) != null) {
3082                String color = a.getValue();
3083                log.debug("west color: {}", color);
3084                setTrainIconColorWest(color);
3085            }
3086            if ((a = operations.getChild(Xml.ICON_COLOR).getAttribute(Xml.LOCAL)) != null) {
3087                String color = a.getValue();
3088                log.debug("local color: {}", color);
3089                setTrainIconColorLocal(color);
3090            }
3091            if ((a = operations.getChild(Xml.ICON_COLOR).getAttribute(Xml.TERMINATE)) != null) {
3092                String color = a.getValue();
3093                log.debug("terminate color: {}", color);
3094                setTrainIconColorTerminate(color);
3095            }
3096        }
3097        if (operations.getChild(Xml.COMMENTS) != null) {
3098            if ((a = operations.getChild(Xml.COMMENTS).getAttribute(Xml.MISPLACED_CARS)) != null) {
3099                String comment = a.getValue();
3100                log.debug("Misplaced comment: {}", comment);
3101                setMiaComment(comment);
3102            }
3103        }
3104
3105        if (operations.getChild(Xml.DISPLAY) != null) {
3106            if ((a = operations.getChild(Xml.DISPLAY).getAttribute(Xml.SHOW_TRACK_MOVES)) != null) {
3107                String enable = a.getValue();
3108                log.debug("show track moves: {}", enable);
3109                getDefault().showTrackMoves = enable.equals(Xml.TRUE);
3110            }
3111        }
3112
3113        if (operations.getChild(Xml.VSD) != null) {
3114            if ((a = operations.getChild(Xml.VSD).getAttribute(Xml.ENABLE_PHYSICAL_LOCATIONS)) != null) {
3115                String enable = a.getValue();
3116                setVsdPhysicalLocationEnabled(enable.equals(Xml.TRUE));
3117            }
3118        }
3119        if (operations.getChild(Xml.CATS) != null) {
3120            if ((a = operations.getChild(Xml.CATS).getAttribute(Xml.EXACT_LOCATION_NAME)) != null) {
3121                String enable = a.getValue();
3122                AbstractOperationsServer.setExactLocationName(enable.equals(Xml.TRUE));
3123            }
3124        }
3125
3126        if (operations.getChild(Xml.SETTINGS) != null) {
3127            if ((a = operations.getChild(Xml.SETTINGS).getAttribute(Xml.AUTO_SAVE)) != null) {
3128                String enabled = a.getValue();
3129                log.debug("autoSave: {}", enabled);
3130                setAutoSaveEnabled(enabled.equals(Xml.TRUE));
3131            }
3132            if ((a = operations.getChild(Xml.SETTINGS).getAttribute(Xml.AUTO_BACKUP)) != null) {
3133                String enabled = a.getValue();
3134                log.debug("autoBackup: {}", enabled);
3135                setAutoBackupEnabled(enabled.equals(Xml.TRUE));
3136            }
3137        }
3138
3139        if (operations.getChild(Xml.LOGGER) != null) {
3140            if ((a = operations.getChild(Xml.LOGGER).getAttribute(Xml.CAR_LOGGER)) != null) {
3141                String enable = a.getValue();
3142                log.debug("carLogger: {}", enable);
3143                getDefault().carLogger = enable.equals(Xml.TRUE);
3144            }
3145            if ((a = operations.getChild(Xml.LOGGER).getAttribute(Xml.ENGINE_LOGGER)) != null) {
3146                String enable = a.getValue();
3147                log.debug("engineLogger: {}", enable);
3148                getDefault().engineLogger = enable.equals(Xml.TRUE);
3149            }
3150            if ((a = operations.getChild(Xml.LOGGER).getAttribute(Xml.TRAIN_LOGGER)) != null) {
3151                String enable = a.getValue();
3152                log.debug("trainLogger: {}", enable);
3153                getDefault().trainLogger = enable.equals(Xml.TRUE);
3154            }
3155        } else if (operations.getChild(Xml.SETTINGS) != null) {
3156            // for backward compatibility
3157            if ((a = operations.getChild(Xml.SETTINGS).getAttribute(Xml.CAR_LOGGER)) != null) {
3158                String enable = a.getValue();
3159                log.debug("carLogger: {}", enable);
3160                getDefault().carLogger = enable.equals(Xml.TRUE);
3161            }
3162            if ((a = operations.getChild(Xml.SETTINGS).getAttribute(Xml.ENGINE_LOGGER)) != null) {
3163                String enable = a.getValue();
3164                log.debug("engineLogger: {}", enable);
3165                getDefault().engineLogger = enable.equals(Xml.TRUE);
3166            }
3167            if ((a = operations.getChild(Xml.SETTINGS).getAttribute(Xml.TRAIN_LOGGER)) != null) {
3168                String enable = a.getValue();
3169                log.debug("trainLogger: {}", enable);
3170                getDefault().trainLogger = enable.equals(Xml.TRUE);
3171            }
3172        }
3173        if (operations.getChild(Xml.DAY_NAME_MAP) != null) {
3174            List<Element> eMap = operations.getChild(Xml.DAY_NAME_MAP).getChildren(Xml.MAP);
3175            for (Element eDay : eMap) {
3176                if (eDay.getAttribute(Xml.DAY) != null && eDay.getAttribute(Xml.NAME) != null) {
3177                    String day = eDay.getAttribute(Xml.DAY).getValue();
3178                    String name = eDay.getAttribute(Xml.NAME).getValue();
3179                    setDayToName(day, name);
3180                    log.debug("Mapping day: {} to name: {}", day, name);
3181                }
3182            }
3183        }
3184    }
3185
3186    // replace old pickup and drop message keys
3187    // Change happened from 2.11.3 to 2.11.4
3188    // 4/16/2014
3189    private static void replaceOldFormat(String[] format) {
3190        for (int i = 0; i < format.length; i++) {
3191            if (format[i].equals("Pickup Msg")) // NOI18N
3192            {
3193                format[i] = PICKUP_COMMENT;
3194            } else if (format[i].equals("Drop Msg")) // NOI18N
3195            {
3196                format[i] = DROP_COMMENT;
3197            }
3198        }
3199    }
3200
3201    /**
3202     * Converts the xml key to the proper locale text
3203     *
3204     */
3205    private static void keyToStringConversion(String[] keys) {
3206        for (int i = 0; i < keys.length; i++) {
3207            if (keys[i].equals(BLANK)) {
3208                continue;
3209            }
3210            try {
3211                keys[i] = Bundle.getMessage(keys[i]);
3212            } catch (Exception e) {
3213                log.warn("Key {}: ({}) not found", i, keys[i]);
3214            }
3215        }
3216    }
3217
3218    /*
3219     * Converts the strings into English tags for xml storage
3220     *
3221     */
3222    public static void stringToTagConversion(String[] strings) {
3223        for (int i = 0; i < strings.length; i++) {
3224            if (strings[i].equals(BLANK)) {
3225                continue;
3226            }
3227            for (String key : KEYS) {
3228                if (strings[i].equals(Bundle.getMessage(key))) {
3229                    strings[i] = Bundle.getMessage(Locale.ROOT, key);
3230                    break;
3231                }
3232            }
3233            // log.debug("Converted {} to {}", old, strings[i]);
3234        }
3235    }
3236
3237    /*
3238     * The xml attributes stored using the English translation. This converts the
3239     * attribute to the appropriate key for language conversion.
3240     */
3241    private static void xmlAttributeToKeyConversion(String[] format) {
3242        for (int i = 0; i < format.length; i++) {
3243            for (String key : KEYS) {
3244                if (format[i].equals(Bundle.getMessage(Locale.ROOT, key))) {
3245                    format[i] = key;
3246                }
3247            }
3248        }
3249    }
3250
3251    protected static void setDirtyAndFirePropertyChange(String p, Object old, Object n) {
3252        InstanceManager.getDefault(OperationsSetupXml.class).setDirty(true);
3253        getDefault().firePropertyChange(p, old, n);
3254    }
3255
3256    public static Setup getDefault() {
3257        return InstanceManager.getDefault(Setup.class);
3258    }
3259
3260    private static final Logger log = LoggerFactory.getLogger(Setup.class);
3261
3262    @Override
3263    public void dispose() {
3264        AutoSave.stop();
3265    }
3266
3267}