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