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