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