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