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