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