001package jmri.jmrix.can.cbus;
002
003import java.util.prefs.BackingStoreException;
004import java.util.prefs.Preferences;
005
006import jmri.beans.PreferencesBean;
007import jmri.jmrix.can.cbus.node.CbusNode;
008import jmri.jmrix.can.cbus.swing.modeswitcher.SprogCbusSprog3PlusModeSwitcherFrame;
009import jmri.profile.ProfileManager;
010import jmri.profile.ProfileUtils;
011
012import org.slf4j.Logger;
013import org.slf4j.LoggerFactory;
014
015/**
016 * Preferences for the MERG CBUS connections.
017 *
018 * @author Steve Young (c) 2019
019 */
020public class CbusPreferences extends PreferencesBean {
021
022    // defaults
023    private boolean _addCommandStations = false;
024    private boolean _addNodes = false;
025    private boolean _allocateNnListener = true;
026    private long _nodeBackgroundFetchDelay = 100L; // needs to match an option in NodeConfigToolPane
027    private boolean _startupSearchForCs = false;
028    private boolean _startupSearchForNodes = false;
029    private boolean searchForNodesBackupXmlOnStartup = false;
030    private boolean _saveRestoreEventTable = true;
031    private int minimumNumBackupsToKeep = 10;
032    private int bootWriteDelay = CbusNode.BOOT_PROG_TIMEOUT_FAST;
033    // Default to no programmers available. The p[rogrammer manager will validate
034    // the preferences for the hardware connection in use.
035    private boolean _isGlobalProgrammerAvailable = true;
036    private boolean _isAddressedModePossible = true;
037    private int _progTrackMode = SprogCbusSprog3PlusModeSwitcherFrame.PROG_OFF_MODE;
038    private int _nodeTableSplit = 100;
039    
040    public CbusPreferences() {
041        super(ProfileManager.getDefault().getActiveProfile());
042        Preferences sharedPreferences = ProfileUtils.getPreferences(super.getProfile(), this.getClass(), true);
043        this.readPreferences(sharedPreferences);
044    }
045
046    private void readPreferences(Preferences sharedPreferences) {
047
048        this._addCommandStations = sharedPreferences.getBoolean("_addCommandStations",this.getAddCommandStations());
049        this._addNodes = sharedPreferences.getBoolean("_addNodes",this.getAddNodes());
050        this._allocateNnListener = sharedPreferences.getBoolean("_allocateNnListener",this.getAllocateNNListener());
051        this._nodeBackgroundFetchDelay = sharedPreferences.getLong("_nodeBgFetchDelay",this.getNodeBackgroundFetchDelay());
052        
053        this._startupSearchForCs = sharedPreferences.getBoolean("_startupSearchForCs",this.getStartupSearchForCs());
054        this._startupSearchForNodes = sharedPreferences.getBoolean("_startupSearchForNodes",this.getStartupSearchForNodes());
055        
056        this.searchForNodesBackupXmlOnStartup = sharedPreferences.getBoolean(
057            "searchForNodesBackupXmlOnStartup",this.getSearchForNodesBackupXmlOnStartup() );
058        this.minimumNumBackupsToKeep = sharedPreferences.getInt(
059            "minimumNumBackupsToKeep",this.getMinimumNumBackupsToKeep() );
060        this.bootWriteDelay = sharedPreferences.getInt(
061            "bootWriteDelay",this.getBootWriteDelay() );
062        this._saveRestoreEventTable = sharedPreferences.getBoolean(
063            "saveRestoreEventTable",this.getSaveRestoreEventTable() );
064
065        this._isGlobalProgrammerAvailable = sharedPreferences.getBoolean(
066            "globalprogrammer", this.isGlobalProgrammerAvailable() );
067        this._isAddressedModePossible = sharedPreferences.getBoolean(
068            "addressedprogrammer", this.isAddressedModePossible() );
069
070        this._progTrackMode = sharedPreferences.getInt("progtrackmode", this.getProgTrackMode() );
071        
072        this._nodeTableSplit = sharedPreferences.getInt("nodetablesplit", this.getNodeTableSplit() );
073    }
074
075    public void savePreferences() {
076
077        Preferences sharedPreferences = ProfileUtils.getPreferences(this.getProfile(), this.getClass(), true);
078        
079        sharedPreferences.putBoolean("_addCommandStations", this.getAddCommandStations() );
080        sharedPreferences.putBoolean("_addNodes", this.getAddNodes() );
081        sharedPreferences.putBoolean("_allocateNnListener", this.getAllocateNNListener() );
082        sharedPreferences.putLong("_nodeBgFetchDelay", this.getNodeBackgroundFetchDelay() );
083        
084        sharedPreferences.putBoolean("_startupSearchForCs", this.getStartupSearchForCs() );
085        sharedPreferences.putBoolean("_startupSearchForNodes", this.getStartupSearchForNodes() );
086        
087        sharedPreferences.putBoolean("searchForNodesBackupXmlOnStartup", this.getSearchForNodesBackupXmlOnStartup() );
088        sharedPreferences.putInt("minimumNumBackupsToKeep", this.getMinimumNumBackupsToKeep() );
089        sharedPreferences.putInt("bootWriteDelay", this.getBootWriteDelay() );
090        sharedPreferences.putBoolean("saveRestoreEventTable", this.getSaveRestoreEventTable() );
091
092        sharedPreferences.putBoolean("globalprogrammer", this.isGlobalProgrammerAvailable() );
093        sharedPreferences.putBoolean("addressedprogrammer", this.isAddressedModePossible() );
094        
095        sharedPreferences.putInt("progtrackmode", this.getProgTrackMode() );
096        
097        sharedPreferences.putInt("nodetablesplit", this.getNodeTableSplit() );
098        
099        try {
100            sharedPreferences.sync();
101            log.debug("Updated Cbus Preferences");
102          //  setIsDirty(false);  //  Resets only when stored
103        } catch (BackingStoreException ex) {
104            log.error("Exception while saving preferences", ex);
105        }
106    }
107
108    boolean isPreferencesValid() {
109        return true;
110    }
111    
112    /**
113     * Get if should add new command stations heard on network to CBUS Node Manager table
114     * @return true if adding command stations, else false
115     */
116    public boolean getAddCommandStations() {
117        return _addCommandStations;
118    }
119
120    /**
121     * Set if should add new command stations heard on network to CBUS Node Manager table
122     * @param newVal true if adding command stations, else false
123     */
124    public void setAddCommandStations( boolean newVal ) {
125        _addCommandStations = newVal;
126        savePreferences();
127    }
128    
129    /**
130     * Get if should add new nodes heard on network to CBUS Node Manager table
131     * @return true if adding nodes, else false
132     */
133    public boolean getAddNodes() {
134        return _addNodes;
135    }
136    
137    /**
138     * Set if should add new nodes heard on network to CBUS Node Manager table
139     * @param newVal true if adding nodes, else false
140     */
141    public void setAddNodes( boolean newVal ) {
142        _addNodes = newVal;
143        savePreferences();
144    }
145    
146    /**
147     * Get if should listen on network for new node number requests
148     * @return true if should listen, else false
149     */
150    public boolean getAllocateNNListener(){
151        return _allocateNnListener;
152    }
153    
154    /**
155     * Set if should listen on network for new node number requests
156     * @param newVal true if should listen, else false
157     */
158    public void setAllocateNNListener( boolean newVal ){
159        _allocateNnListener = newVal;
160        savePreferences();
161    }
162    
163    /**
164     * Get Background delay between CBUS Node Manager data fetch from nodes
165     * @return the delay
166     */
167    public long getNodeBackgroundFetchDelay() {
168        return _nodeBackgroundFetchDelay;
169    }
170    
171    /**
172     * Set Background delay between CBUS Node Manager data fetch from nodes
173     * @param newVal in ms can be 0 but defaults to 100ms
174     */
175    public void setNodeBackgroundFetchDelay( long newVal ) {
176        _nodeBackgroundFetchDelay = newVal;
177        savePreferences();
178    }
179    
180    /**
181     * Get Search for Command stations on CBUS Node Table Startup
182     * @return true to send CBUS search for CS, else false
183     */
184    public boolean getStartupSearchForCs(){
185        return _startupSearchForCs;
186    }
187    
188    /**
189     * Set Search for Command stations on CBUS Node Table Startup
190     * @param newVal true to send CBUS search for CS, else false
191     */
192    public void setStartupSearchForCs( boolean newVal ){
193        _startupSearchForCs = newVal;
194        savePreferences();
195    }    
196    
197    /**
198     * Get Search for Nodes on CBUS Node Table Startup
199     * @return true to send CBUS search for nodes, else false
200     */
201    public boolean getStartupSearchForNodes(){
202        return _startupSearchForNodes;
203    }
204    
205    /**
206     * Set Search for Nodes on CBUS Node Table Startup
207     * @param newVal true to send CBUS search for nodes, else false
208     */
209    public void setStartupSearchForNodes( boolean newVal ){
210        _startupSearchForNodes = newVal;
211        savePreferences();
212    }
213    
214    /**
215     * Get Save Restore CBUS Event Table
216     * <p>
217     * If enabled loads CBUS event table data from xml on table startup,
218     * and saves data to xml on shutdown.
219     *
220     * @return true to save and restore, else false
221     */
222    public boolean getSaveRestoreEventTable(){
223        return _saveRestoreEventTable;
224    }
225    
226    /**
227     * Set Save Restore CBUS Event Table
228     * @param newVal true to save and restore, else false
229     */
230    public void setSaveRestoreEventTable( boolean newVal ){
231        _saveRestoreEventTable = newVal;
232        savePreferences();
233    }
234
235    /**
236     * Get search CBUS node backup directory on startup for node xml files
237     * @return true to search, else false
238     */
239    public boolean getSearchForNodesBackupXmlOnStartup(){
240        return searchForNodesBackupXmlOnStartup;
241    }
242    
243    /**
244     * Set search CBUS node backup directory on startup for node xml files
245     * @param newVal true to lookup node xml files, else false
246     */
247    public void setSearchForNodesBackupXmlOnStartup( boolean newVal ){
248        searchForNodesBackupXmlOnStartup = newVal;
249        savePreferences();
250    }
251    
252    /**
253     * Get minimum number of CbusNode XML backups to retain
254     * @return number of backups, defaults to 10
255     */
256    public int getMinimumNumBackupsToKeep(){
257        return minimumNumBackupsToKeep;
258    }
259    
260    /**
261     * Set minimum number of CbusNode XML backups to retain
262     * @param newVal the new number of backups
263     */
264    public void setMinimumNumBackupsToKeep( int newVal ){
265        minimumNumBackupsToKeep = newVal;
266        savePreferences();
267    }
268    
269    /**
270     * Get delay between bootloader data writes
271     * @return delay, in ms, defaults to CbusNode.BOOT_PROG_TIMEOUT_FAST
272     */
273    public int getBootWriteDelay(){
274        return bootWriteDelay;
275    }
276    
277    /**
278     * Set delay between bootloader data writes
279     * @param newVal the delay in ms
280     */
281    public void setBootWriteDelay( int newVal ){
282        bootWriteDelay = newVal;
283        savePreferences();
284    }
285    
286    /**
287     * Get the global programmer state
288     * @return global programmer state
289     */
290    public boolean isGlobalProgrammerAvailable() {
291        return _isGlobalProgrammerAvailable;
292    }
293    
294    /**
295     * Get the addressed programmer state
296     * @return addressed programmer state
297     */
298    public boolean isAddressedModePossible() {
299        return _isAddressedModePossible;
300    }
301    
302    /**
303     * Set global (service mode) programmer availability
304     * @param state true if available
305     */
306    public void setGlobalProgrammerAvailable(boolean state) {
307        _isGlobalProgrammerAvailable = state;
308        savePreferences();
309    }
310    
311    /**
312     * Set global (service mode) programmer availability
313     * @param state true if available
314     */
315    public void setAddressedModePossible(boolean state) {
316        _isAddressedModePossible = state;
317        savePreferences();
318    }
319    
320    /**
321     * Set the programmer type
322     * @param global true if global (service mode) programmer is available
323     * @param addressed thru if addressed (ops mode) programmer is available
324     */
325    public void setProgrammersAvailable(boolean global, boolean addressed) {
326        setGlobalProgrammerAvailable(global);
327        setAddressedModePossible(addressed);
328    }
329    
330    /**
331     * Get the programming track mode
332     * @return the mode
333     */
334    public int getProgTrackMode() {
335        return _progTrackMode;
336    }
337    
338    /**
339     * Set programming track mode
340     * @param mode to be set
341     */
342    public void setProgTrackMode(int mode) {
343        _progTrackMode = mode;
344        savePreferences();
345    }
346    
347    /**
348     * Get the position of the node table split
349     * 
350     * @return position in pixels
351     */
352    public int getNodeTableSplit() {
353        return _nodeTableSplit;
354    }
355    
356    /**
357     * Set the position of the node table split from the top of thw window
358     * 
359     * @param pixels new position
360     */
361    public void setNodeTableSplit(int pixels) {
362        _nodeTableSplit = pixels;
363        savePreferences();
364    }
365    
366    private final static Logger log = LoggerFactory.getLogger(CbusPreferences.class);
367
368}