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