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