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