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