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