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