001package jmri;
002
003import java.beans.PropertyChangeListener;
004import java.time.Instant;
005import java.util.Date;
006import javax.annotation.Nonnull;
007
008/**
009 * Provide access to clock capabilities in hardware or software.
010 * <p>
011 * The {@code rate} property determines how much faster than real time this
012 * runs. For example, a value of 2.0 means that the value returned by getTime
013 * will advance an hour for every half-hour of wall-clock time elapsed.
014 * <p>
015 * The {@code rate} and {@code run} properties are bound, so you can listen for
016 * changes to them. The {@code time} property is bound, but listeners only
017 * receive change notifications if the change is a minute or more, because it
018 * changes continuously; query to {@code time} property when needed to get the
019 * current value.
020 * 
021 * @author Bob Jacobsen Copyright (C) 2004, 2007, 2008
022 */
023public interface Timebase extends NamedBean {
024
025    /**
026     * Set the current time.
027     *
028     * @param d the new time
029     */
030    void setTime(@Nonnull Date d);
031
032    /**
033     * Set the current time.
034     *
035     * @param i the new time
036     */
037    void setTime(@Nonnull Instant i);
038
039    /**
040     * Set the current time and force a synchronization with the DCC system.
041     *
042     * @param d the new time
043     */
044    void userSetTime(@Nonnull Date d);
045
046    /**
047     * Get the current time.
048     * @return current time.
049     */
050    @Nonnull
051    Date getTime();
052
053    /**
054     * Set if Timebase is running.
055     * @param y true if running else false.
056     */
057    void setRun(boolean y);
058
059    /**
060     * Get if Timebase is running.
061     * @return true if running, else false.
062     */
063    boolean getRun();
064
065    /**
066     * Set fast clock rate.
067     *
068     * @param factor the fast clock rate
069     * @throws jmri.TimebaseRateException if the implementation can not use the
070     *                                        requested rate
071     */
072    void setRate(double factor) throws TimebaseRateException;
073
074    /**
075     * Set fast clock rate and force a synchronization with the DCC hardware.
076     *
077     * @param factor the fast clock rate
078     * @throws jmri.TimebaseRateException if the implementation can not use the
079     *                                        requested rate
080     */
081    void userSetRate(double factor) throws TimebaseRateException;
082
083    /**
084     * Caution: This method may return a fiddled clock rate if certain hardware
085     * clocks are the Time Source. Use {@link #userGetRate()} if you want the
086     * real clock rate instead.
087     *
088     * @return the rate
089     */
090    double getRate();
091
092    /**
093     * Get the true fast clock rate even if the master timebase rate has been
094     * modified by a hardware clock. External changes in fast clock rate occur
095     * because of the peculiar way some hardware clocks attempt to synchronize
096     * with the JMRI fast clock.
097     *
098     * @return the rate
099     */
100    double userGetRate();
101
102    // methods for setting and getting master time source
103    /**
104     * Set internalMaster and update fields.
105     *
106     * @param master true if fast clock time is derived from internal computer clock, 
107     *                  false if derived from hardware clock.
108     * @param update true to send update, else false.
109     */
110    void setInternalMaster(boolean master, boolean update);
111
112    /**
113     * Get internalMaster field.
114     *
115     * @return true if fast clock time is derived from internal computer clock, 
116     *  false if derived from hardware clock
117     */
118    boolean getInternalMaster();
119
120    /**
121     * Set the Master Clock Name.
122     * @param name master clock name.
123     */
124    void setMasterName(@Nonnull String name);
125
126    /**
127     * Get the Master Clock Name.
128     * @return master clock name.
129     */
130    String getMasterName();
131
132    /**
133     * Set if clock should synchronise.
134     * @param synchronize  set true to synchronise hardware clocks with Time base.
135     * @param update set true to update clock when function called.
136     */
137    void setSynchronize(boolean synchronize, boolean update);
138
139    /**
140     * Get if clock should synchronise with Time base.
141     * @return true if should synchronise hardware clocks.
142     */
143    boolean getSynchronize();
144
145    /**
146     * Set if should correct or update hardware.
147     * @param correct set true to correct hardware clocks.
148     * @param update set true to update clock when function called.
149     */
150    void setCorrectHardware(boolean correct, boolean update);
151
152    /**
153     * Get if should correct Hardware clocks.
154     * @return true to correct, else false.
155     */
156    boolean getCorrectHardware();
157
158    /**
159     * Set 12 or 24 hour display option.
160     *
161     * @param display true for a 12-hour display; false for a 24-hour display
162     * @param update true to update clock when function called.
163     */
164    void set12HourDisplay(boolean display, boolean update);
165
166    /**
167     * Get 12 or 24 hour display option.
168     *
169     * @return true for a 12-hour display; false for a 24-hour display
170     */
171    boolean use12HourDisplay();
172
173    /**
174     * Defines what to do with the fast clock when JMRI starts up.
175     */
176    enum ClockInitialRunState {
177        /**
178         * Changes the clock to stopped when JMRI starts.
179         */
180        DO_STOP,
181        /**
182         * Changes the clock to running when JMRI starts.
183         */
184        DO_START,
185        /**
186         * Does not change the clock when JMRI starts.
187         */
188        DO_NOTHING
189    }
190
191    /**
192     * Set the Clock Initial Run State ENUM.
193     * @param initialState Initial state.
194     */
195
196    void setClockInitialRunState(ClockInitialRunState initialState);
197
198    /**
199     * Get the Clock Initial Run State ENUM.
200     * @return Initial state.
201     */
202    ClockInitialRunState getClockInitialRunState();
203
204    /**
205     * Set if to show a Stop / Resume button next to the clock.
206     * @param displayed true if to display, else false.
207     */
208    void setShowStopButton(boolean displayed);
209
210    /**
211     * Get if to show a Stop / Resume button next to the clock.
212     * @return true if to display, else false.
213     */
214    boolean getShowStopButton();
215
216    /**
217     * Set time at start up option, and start up time.
218     * @param set true for set time at startup, else false.
219     * @param time startup time.
220     */
221    void setStartSetTime(boolean set, Date time);
222
223    /**
224     * Get if to use a set start time.
225     * @return true if using set start time.
226     */
227    boolean getStartSetTime();
228
229    /**
230     * Set the start clock speed rate.
231     * @param factor start clock speed factor.
232     */
233    void setStartRate(double factor);
234
235    /**
236     * Get the startup clock speed rate.
237     * @return startup clock speed rate factor.
238     */
239    double getStartRate();
240
241    /**
242     * Set Set Rate at Start option.
243     * @param set If true, the rate at startup will be set to the value of getStartRate().
244     */
245    void setSetRateAtStart(boolean set);
246
247    /**
248     * Get if to Set Rate at Start option checked.
249     * @return If true, the rate at startup should be set to the value of getStartRate()
250     */
251    boolean getSetRateAtStart();
252
253    /**
254     * Get the Clock Start Time.
255     * @return Clock Start Time.
256     */
257    @Nonnull
258    Date getStartTime();
259
260    /**
261     * Set the Start Clock type Option.
262     * @param option Clock type, e.g. NIXIE_CLOCK or PRAGOTRON_CLOCK
263     */
264    void setStartClockOption(int option);
265
266    
267    /**
268     * Get the Start Clock Type.
269     * @return Clock type, e.g. NIXIE_CLOCK or PRAGOTRON_CLOCK
270     */
271    int getStartClockOption();
272
273    /**
274     * Initialise the clock.
275     * Should only be invoked at start up.
276     */
277    void initializeClock();
278
279    /**
280     * Clock start option.
281     * No startup clock type.
282     */
283    int NONE = 0x00;
284    /**
285     * Clock start option.
286     * Startup Nixie clock type.
287     */
288    int NIXIE_CLOCK = 0x01;
289    /**
290     * Clock start option.
291     * Startup Analogue clock type.
292     */
293    int ANALOG_CLOCK = 0x02;
294    /**
295     * Clock start option.
296     * Startup LCD clock type.
297     */
298    int LCD_CLOCK = 0x04;
299    /**
300     * Clock start option.
301     * Startup Pragotron clock type.
302     */
303    int PRAGOTRON_CLOCK = 0x08;
304
305    /**
306     * Initialize hardware clock at start up after all options are set up.
307     * <p>
308     * Note: This method is always called at start up. It should be ignored if
309     * there is no communication with a hardware clock
310     */
311    void initializeHardwareClock();
312
313    /**
314     * @return true if call to initialize Hardware Clock has occurred
315     */
316    boolean getIsInitialized();
317
318    /**
319     * Request a callback when the minutes place of the time changes. This is
320     * the same as calling
321     * {@link #addPropertyChangeListener(String, PropertyChangeListener)} with
322     * the propertyName {@code minutes}.
323     *
324     * @param l the listener to receive the callback
325     */
326    void addMinuteChangeListener(@Nonnull PropertyChangeListener l);
327
328    /**
329     * Remove a request for callback when the minutes place of the time changes.
330     * This is the same as calling
331     * {@link #removePropertyChangeListener(String, PropertyChangeListener)}
332     * with the propertyName {@code minutes}.
333     *
334     * @param l the listener to receive the callback
335     */
336    void removeMinuteChangeListener(@Nonnull PropertyChangeListener l);
337
338    /**
339     * Get the list of minute change listeners. This is the same as calling
340     * {@link #getPropertyChangeListeners(String)} with the propertyName
341     * {@code minutes}.
342     *
343     * @return the list of listeners
344     */
345    @Nonnull
346    PropertyChangeListener[] getMinuteChangeListeners();
347
348    /**
349     * Remove references to and from this object, so that it can eventually be
350     * garbage-collected.
351     */
352    @Override
353    void dispose();
354
355}