001package jmri;
002
003import java.util.Hashtable;
004import java.util.LinkedHashMap;
005import java.util.List;
006import javax.annotation.CheckForNull;
007import javax.annotation.Nonnull;
008import jmri.jmrit.display.layoutEditor.LayoutBlock;
009import jmri.jmrit.display.layoutEditor.LevelXing;
010
011/**
012 * Generic interface for Signal Mast Logic. Signal Mast Logic allows to build up
013 * a set of criteria for a Signal Mast as to what Aspect it should be displaying
014 * for a specific route through to a destination Signal Mast.
015 *
016 *  * @see jmri.implementation.DefaultSignalMastLogic
017 *
018 * @author Kevin Dickerson Copyright (C) 2011
019 */
020public interface SignalMastLogic extends NamedBean {
021
022    /**
023     * Constant representing that all the user entered details relating to a
024     * signal mast logic are stored. Automatically generated details that have
025     * been entered via the setAutoBean are not stored.
026     */
027    public int STOREALL = 0;
028    /**
029     * Constant representing that only the basic Signal Mast Logic details are
030     * stored. All details that determine the triggering of the logic are not
031     * stored.
032     */
033    public int STOREMASTSONLY = 2;
034    /**
035     * Constant representing that this Signal Mast Logic is not stored with the
036     * panel file. This is used where another piece of code uses handles the
037     * dynamic creation of signalmast logic
038     */
039    public int STORENONE = 4;
040
041    /**
042     * Query if we are allowing the system to automatically generate a list of
043     * conflicting Signal Mast that have a direct effect on our logic.
044     *
045     * @param destination controlled signal mast
046     * @return true if this is allowed.
047     */
048    public boolean allowAutoMaticSignalMastGeneration(SignalMast destination);
049
050    /**
051     * Sets whether we should allow the system to automatically generate a list
052     * of signal masts that could cause a conflicting route.
053     *
054     * @param allow       set true if we are to allow automatic generation.
055     * @param destination controlled signal mast
056     */
057    public void allowAutoMaticSignalMastGeneration(boolean allow, SignalMast destination);
058
059    /**
060     * Sets whether we should lock all turnouts between the source and
061     * destination signal masts when the logic goes active, to prevent them from
062     * being changed. This is dependant upon the hardware allowing for this.
063     *
064     * @param lock        set true if the system should lock the turnout.
065     * @param destination controlled signal mast
066     */
067    public void allowTurnoutLock(boolean lock, SignalMast destination);
068
069    /**
070     * Returns true if any of the blocks in the supplied list are included in
071     * any of the logics that set this signal.
072     *
073     * @param blks A list of Layout Blocks to query against
074     * @return whether all supplied blocks are in at least one of the logics
075     */
076    public boolean areBlocksIncluded(List<Block> blks);
077
078    /**
079     * Replace the existing source Signal Mast with another signal mast. This is
080     * for use with such tools as the Layout Editor where a signal mast in a
081     * certain location can be replaced with another, while the remainder of the
082     * configuration stays the same.
083     *
084     * @param oldMast Signal Mast currently configured as the source mast
085     * @param newMast Signal Mast to act as the replacement source mast
086     */
087    public void replaceSourceMast(SignalMast oldMast, SignalMast newMast);
088
089    /**
090     * Replace the existing destination Signal Mast with another signal mast.
091     * This is for use with such tools as the Layout Editor where a signalmast
092     * in a certain location can be replaced with another, while the remainder
093     * of the configuration stays the same.
094     *
095     * @param oldMast Signal Mast currently configured as the destination mast
096     * @param newMast Signal Mast to act as the replacement destination mast
097     */
098    public void replaceDestinationMast(SignalMast oldMast, SignalMast newMast);
099
100    /**
101     * Remove references to and from this object, so that it can eventually be
102     * garbage-collected.
103     */
104    @Override
105    public void dispose();
106
107    /**
108     * Return the Section configured between the source and destination mast.
109     *
110     * @param destination controlled signal mast
111     * @return The section object
112     */
113    public Section getAssociatedSection(SignalMast destination);
114
115    /**
116     * Define a Section between the source and destination mast.
117     *
118     * @param sec         The section
119     * @param destination controlled signal mast
120     */
121    public void setAssociatedSection(Section sec, SignalMast destination);
122
123    /**
124     * Return the Set State of a control block as it is configured between the
125     * source and destination mast.
126     *
127     * @param block       The Control Layout Block.
128     * @param destination controlled signal mast
129     * @return The int value representing the occupancy state that the block
130     *         should show
131     */
132    public int getAutoBlockState(Block block, SignalMast destination);
133
134    /**
135     * Return all the blocks that have been detected as being in use for this
136     * logic. This includes blocks on level xings that are not directly in the
137     * path but do have an effect on the logic.
138     *
139     * @param destination controlled signal mast
140     * @return A list of Block objects
141     */
142    public List<Block> getAutoBlocks(SignalMast destination);
143
144    /**
145     * Return a list of blocks just that have been detected as being directly
146     * between the source and destination mast. The order of the blocks in the
147     * list is the order in which they are connected.
148     *
149     * @param destination controlled signal mast
150     * @return A list of block objects
151     */
152    public List<Block> getAutoBlocksBetweenMasts(SignalMast destination);
153
154    /**
155     * Return a list of control masts that have been automatically detected as
156     * being directly between the source and destination mast. The order of the
157     * control masts in the list is the order in which they are connected.
158     *
159     * @param destination controlled signal mast
160     * @return A list of signal mast objects
161     */
162    public List<SignalMast> getAutoMasts(SignalMast destination);
163
164    /**
165     * Return the Set State (Aspect) of a control mast as it is configured
166     * between the source and destination mast.
167     *
168     * @param mast        The Control Signal Mast
169     * @param destination controlled signal mast
170     * @return The name of the Aspect the Control Mast should display
171     */
172    public String getAutoSignalMastState(SignalMast mast, SignalMast destination);
173
174    /**
175     * Return the Set State of a control turnout as it is configured between the
176     * source and destination mast.
177     *
178     * @param turnout     The Control Turnout
179     * @param destination controlled signal mast
180     * @return The name of the Aspect the Control Mast should display
181     */
182    public int getAutoTurnoutState(Turnout turnout, SignalMast destination);
183
184    /**
185     * Return only the turnouts that have been detected as being directly
186     * between the source and destination mast. The order of the turnouts in the
187     * list is the order in which they are connected.
188     *
189     * @param destination controlled signal mast
190     * @return A list of turnout objects
191     */
192    public List<Turnout> getAutoTurnouts(SignalMast destination);
193
194    /**
195     * Return the Set To State of a control block as it is configured between
196     * the source and destination mast.
197     *
198     * @param block       The Control Layout Block
199     * @param destination controlled signal mast
200     * @return Integer representing the state the control block should be in
201     */
202    public int getBlockState(Block block, SignalMast destination);
203
204    /**
205     * Return the Layout Blocks that have been defined by the user to control
206     * the SML to the destination mast.
207     *
208     * @param destination controlled signal mast
209     * @return A list of Block objects
210     */
211    public List<Block> getBlocks(SignalMast destination);
212
213    /**
214     * Get the comment set on this SML.
215     *
216     * @param destination the mast to get the comment from
217     * @return the comment or an empty string
218     */
219    @Nonnull
220    public String getComment(SignalMast destination);
221
222    /**
223     * Return a list of all Signal Masts that have been configured as
224     * Destination Masts on this SML.
225     *
226     * @return A list of Signal Mast objects
227     */
228    public List<SignalMast> getDestinationList();
229
230    /**
231     * Get the Maximum Speed set for the destination Signal Mast in this SML.
232     *
233     * @param destination the destination mast
234     * @return A number representing the speed
235     */
236    public float getMaximumSpeed(SignalMast destination);
237
238    /**
239     * Return the number of current listeners defined on this SML.
240     *
241     * @return the number of listeners; -1 if the information is not available
242     *         for some reason.
243     */
244    @Override
245    public int getNumPropertyChangeListeners();
246
247    /**
248     * Return the Set To State of a control Sensor as it is configured between
249     * the source and destination mast.
250     *
251     * @param sensor      The Control Sensor
252     * @param destination controlled signal mast
253     * @return Integer representing the state the control Sensor should be in
254     */
255    public int getSensorState(Sensor sensor, SignalMast destination);
256
257    /**
258     * Return the Sensors that have been defined by the user to control the SML
259     * to the destination mast.
260     *
261     * @param destination controlled signal mast
262     * @return A list of Sensor objects
263     */
264    public List<Sensor> getSensors(SignalMast destination);
265
266    /**
267     * Return the Sensors that have been defined by the user to control the SML
268     * to the destination mast as NamedBeanHandles.
269     *
270     * @param destination controlled signal mast
271     * @return A list of Sensor NamedBeanHandles
272     */
273    public List<NamedBeanHandle<Sensor>> getNamedSensors(SignalMast destination);
274
275    /**
276     * Return the Set To State (Aspect) of a control Signal Mast as it is
277     * configured between the source and destination mast.
278     *
279     * @param mast        The Control Signal Mast
280     * @param destination controlled signal mast
281     * @return Integer representing the state the control Signal Mast should be
282     *         in
283     */
284    public String getSignalMastState(SignalMast mast, SignalMast destination);
285
286    /**
287     * Return the Signal Masts that have been defined by the user to control the
288     * SML to the destination mast.
289     *
290     * @param destination controlled signal mast
291     * @return A list of Signal Mast objects
292     */
293    public List<SignalMast> getSignalMasts(SignalMast destination);
294
295    public SignalMast getSourceMast();
296
297    /**
298     * Return the Set State of a control Turnout as it is configured between the
299     * source and destination mast.
300     *
301     * @param turnout     The Control Turnout
302     * @param destination controlled signal mast
303     * @return Integer representing the state the control Sensor should be in
304     */
305    public int getTurnoutState(Turnout turnout, SignalMast destination);
306
307    /**
308     * Return the Turnouts that have been defined by the user to control the SML
309     * to the destination mast.
310     *
311     * @param destination controlled signal mast
312     * @return A list of Turnout objects
313     */
314    public List<Turnout> getTurnouts(SignalMast destination);
315
316    /**
317     * Return the Turnouts that have been defined by the user to control the SML
318     * to the destination mast as NamedBeanHandles.
319     *
320     * @param destination controlled signal mast
321     * @return A list of Turnout NamedBeanHandles
322     */
323    public List<NamedBeanHandle<Turnout>> getNamedTurnouts(SignalMast destination);
324
325    /**
326     * General method to initialise all SMLs on the source SIgnal Mast using
327     * destList
328     */
329    public void initialise();
330
331    /**
332     * Initialise the signal mast after all the parameters have been set.
333     *
334     * @param destination controlled signal mast
335     */
336    public void initialise(SignalMast destination);
337
338    /**
339     * Query if the Signal Mast Logic from the current source signal mast to the
340     * destination signal mast is active.
341     *
342     * @param destination controlled signal mast
343     * @return true if active; false otherwise
344     */
345    public boolean isActive(SignalMast destination);
346
347    /**
348     * Get the active destination Signal Mast for this Signal Mast Logic.
349     *
350     * @return the active signal mast or null if none
351     */
352    @CheckForNull
353    public SignalMast getActiveDestination();
354
355    /**
356     * Check whether the Block is part of at least one of the logics.
357     *
358     * @param block       a layout block
359     * @param destination controlled signal mast
360     * @return true if block is included in any of the Signal Mast Logics that
361     *         set destination
362     */
363    public boolean isBlockIncluded(Block block, SignalMast destination);
364
365    /**
366     * Check if signal mast is a destination signal mast in one of the logics
367     *
368     * @param destination controlled signal mast
369     * @return true if destination is a destination mast in this object
370     */
371    public boolean isDestinationValid(SignalMast destination);
372
373    /**
374     * Query if the Signal Mast Logic from the current source signal mast to the
375     * specified destination signal mast is enabled.
376     *
377     * @param destination controlled signal mast
378     * @return true if enabled
379     */
380    public boolean isEnabled(SignalMast destination);
381
382    /**
383     * Check if a sensor is part of at least one of the logics that set a
384     * SignalMast.
385     *
386     * @param sensor      the sensor to check
387     * @param destination controlled signal
388     * @return true if sensor is included in any of the Signal Mast Logics that
389     *         set destination
390     */
391    public boolean isSensorIncluded(Sensor sensor, SignalMast destination);
392
393    /**
394     * Check if a signal mast is part of at least one of the logics that set
395     * another signal mast.
396     *
397     * @param signal      the signal mast to check
398     * @param destination controlled signal mast
399     * @return true if signal is included in any of the Signal Mast Logics that
400     *         set destination
401     */
402    public boolean isSignalMastIncluded(SignalMast signal, SignalMast destination);
403
404    /**
405     * Check if a turnout is part of at least one of the logics that set a
406     * signal mast.
407     *
408     * @param turnout     the turnout to check
409     * @param destination controlled signal mast
410     * @return true if turnout is included in any of the Signal Mast Logics that
411     *         set destination
412     */
413    public boolean isTurnoutIncluded(Turnout turnout, SignalMast destination);
414
415    /**
416     * Query if we are allowing the system to lock turnouts when the logic goes
417     * active.
418     *
419     * @param destination controlled signal mast
420     * @return true if locking is allowed.
421     */
422    public boolean isTurnoutLockAllowed(SignalMast destination);
423
424    /**
425     * Remove control elements for a SML pair containing a destination signal
426     * mast that itself is incompatible with an SML around a level crossing.
427     *
428     * @param sm The destination Signal Mast
429     * @param lx The LevelXing Layout Editor element
430     */
431    public void removeConflictingLogic(SignalMast sm, LevelXing lx);
432
433    /**
434     * Remove the destination signal mast as a pair in this SML.
435     *
436     * @param destination controlled signal mast
437     * @return true if there are no more destination signal masts
438     */
439    public boolean removeDestination(SignalMast destination);
440
441    /**
442     * Set which blocks must be in a given state for the signal mast not to be
443     * set to a Stop aspect. These blocks are not stored in the panel file.
444     *
445     * @param blocks      map of {@link Block}s and their respective set to
446     *                    state to be checked
447     * @param destination controlled signal mast
448     */
449    public void setAutoBlocks(LinkedHashMap<Block, Integer> blocks, SignalMast destination);
450
451    /**
452     * Set which control signal masts must be in a given state before our source
453     * mast can be set. These Signal Masts are not stored in the panel file.
454     *
455     * @param masts       list of control signal masts and their respective set
456     *                    to state to be checked
457     * @param destination controlled signal mast
458     */
459    public void setAutoMasts(Hashtable<SignalMast, String> masts, SignalMast destination);
460
461    /**
462     * Set which turnouts must be set to a given state for the signal mast not
463     * to be set to a Stop aspect. These Turnouts are not stored in the panel
464     * file.
465     *
466     * @param turnouts    map of turnouts and their respective set to state
467     * @param destination controlled signal mast
468     */
469    public void setAutoTurnouts(Hashtable<Turnout, Integer> turnouts, SignalMast destination);
470
471    /**
472     * Set which blocks must be in a given state for the signal mast not to be
473     * set to a Stop aspect.
474     *
475     * @param blocks      map of Blocks and their respective set to state
476     * @param destination controlled signal mast
477     */
478    public void setBlocks(Hashtable<Block, Integer> blocks, SignalMast destination);
479
480    /**
481     * Set the comment for this SML.
482     *
483     * @param comment     text to add as comment
484     * @param destination signal mast to add comment to
485     */
486    public void setComment(String comment, SignalMast destination);
487
488    /**
489     * Add control elements for a SML pair containing a destination signal mast
490     * that itself is skipped as it is incompatible with an SML around a level
491     * crossing.
492     *
493     * @param sm The destination Signal Mast
494     * @param lx The LevelXing Layout Editor element
495     */
496    public void setConflictingLogic(SignalMast sm, LevelXing lx);
497
498    /**
499     * Set the destination signal mast for this SML.
500     *
501     * @param destination controlled signal mast
502     */
503    public void setDestinationMast(SignalMast destination);
504
505    /**
506     * Set the logic to the destination signal mast to Disabled.
507     *
508     * @param destination controlled signal mast
509     */
510    public void setDisabled(SignalMast destination);
511
512    /**
513     * Set the logic to the destination signal mast to Enabled.
514     *
515     * @param destination controlled signal mast
516     */
517    public void setEnabled(SignalMast destination);
518
519    /**
520     * Set the block facing our source signal mast.
521     *
522     * @param facing The Layout Block facing the source Signal Mast
523     */
524    public void setFacingBlock(LayoutBlock facing);
525
526    /**
527     * Get the block defined as facing our source signal mast.
528     *
529     * @return The Layout Block facing the source Signal Mast
530     */
531    public LayoutBlock getFacingBlock();
532
533    /**
534     * Set which control signal masts must be in a given state before our source
535     * mast can be set.
536     *
537     * @param masts       map of control signal masts and respective set to
538     *                    states to be checked
539     * @param destination controlled signal mast
540     */
541    public void setMasts(Hashtable<SignalMast, String> masts, SignalMast destination);
542
543    /**
544     * Set which sensors must be in a given state before our source signal mast
545     * can be set.
546     *
547     * @param sensors     The {@link Sensor}s to be checked
548     * @param destination controlled signal mast
549     */
550    public void setSensors(Hashtable<NamedBeanHandle<Sensor>, Integer> sensors, SignalMast destination);
551
552    /**
553     * Add an individual control Sensor and its set to state to the Signal Mast
554     * Logic.
555     *
556     * @param sensorName  The sensor to be removed
557     * @param state       Integer representing the state the control Sensor
558     *                    should be in
559     * @param destination controlled signal mast
560     */
561    public void addSensor(String sensorName, int state, SignalMast destination);
562
563    /**
564     * Remove an individual control Sensor from the Signal Mast Logic.
565     *
566     * @param sensorName  The sensor to be removed
567     * @param destination controlled signal mast
568     */
569    public void removeSensor(String sensorName, SignalMast destination);
570
571    /**
572     * Determine if the signal mast logic is stored in the panel file and if all
573     * the information is stored.
574     *
575     * @param store       one of {@link #STOREALL}, {@link #STOREMASTSONLY} or
576     *                    {@link #STORENONE}
577     * @param destination controlled signal mast
578     */
579    public void setStore(int store, SignalMast destination);
580
581    /**
582     * Return where the signal mast logic should be stored, if so how much.
583     *
584     * @param destination controlled signal mast
585     * @return one of {@link #STOREALL}, {@link #STOREMASTSONLY} or
586     *         {@link #STORENONE}
587     */
588    public int getStoreState(SignalMast destination);
589
590    /**
591     * Set the states that each control turnout must be in for the source signal
592     * mast not to be set to a Stop aspect.
593     *
594     * @param turnouts    A list of named turnouts and their respective set to
595     *                    state to check
596     * @param destination controlled signal mast
597     */
598    public void setTurnouts(Hashtable<NamedBeanHandle<Turnout>, Integer> turnouts, SignalMast destination);
599
600    /**
601     * Set up a Signal Mast Logic from the Layout Editor panel where its source
602     * Signal Mast is present, when useLayoutEditor is set to true.
603     */
604    public void setupLayoutEditorDetails();
605
606    /**
607     * Set whether this logic should use the details stored in the Layout Editor
608     * to determine which blocks, turnouts will make up the logic between the
609     * source and destination signal mast.
610     *
611     * @param boo         Use the Layout Editor details to determine logic
612     *                    details
613     * @param destination the Destination Signal Mast
614     * @throws jmri.JmriException if a path on the layout editor is not valid
615     */
616    public void useLayoutEditor(boolean boo, SignalMast destination) throws JmriException;
617
618    /**
619     * Query if we are using the Layout Editor panels to build the signal mast
620     * logic, blocks, turnouts.
621     *
622     * @param destination Destination Signal Mast
623     * @return true if we are using the Layout Editor to build the signal mast
624     *         logic.
625     */
626    public boolean useLayoutEditor(SignalMast destination);
627
628    /**
629     * Query if we are using the Layout Editor block information in the signal
630     * mast logic.
631     *
632     * @param destination Destination Signal Mast
633     * @return true if we are using the block information from the Layout
634     *         Editor.
635     */
636    public boolean useLayoutEditorBlocks(SignalMast destination);
637
638    /**
639     * Set whether this logic should use the information from the Layout Editor
640     * for either blocks or turnouts.
641     *
642     * @param turnouts    set false if not to use the turnout information
643     *                    gathered from the layout editor
644     * @param blocks      set false if not to use the block information gathered
645     *                    from the layout editor
646     * @param destination Destination Signal Mast
647     * @throws jmri.JmriException if a path on the layout editor is not valid
648     */
649    public void useLayoutEditorDetails(boolean turnouts, boolean blocks, SignalMast destination) throws JmriException;
650
651    /**
652     * Query if we are using the Layout Editor turnout information in the signal
653     * mast logic.
654     *
655     * @param destination controlled signal mast
656     * @return true if we are using the turnout information from the Layout
657     *         Editor.
658     */
659    public boolean useLayoutEditorTurnouts(SignalMast destination);
660
661    public void disableLayoutEditorUse();
662
663    @Override
664    public void removePropertyChangeListener(java.beans.PropertyChangeListener l);
665
666    @Override
667    public void addPropertyChangeListener(java.beans.PropertyChangeListener l);
668
669    /**
670     * Get the block that the source signal is protecting on the path to the
671     * destination signal mast.
672     *
673     * @param destination controlled signal mast
674     * @return the Layout Block
675     */
676    public LayoutBlock getProtectingBlock(SignalMast destination);
677
678    /**
679     * Set the auto turnouts based upon a given list of layout blocks for a
680     * specific destination mast.
681     *
682     * @param blks        List of Layout Blocks.
683     * @param destination Destination Signal Mast
684     * @return A LinkedHashMap of the original blocks and their required state,
685     *         plus any blocks found on double cross-overs that also need to be
686     *         un-occupied.
687     */
688    public LinkedHashMap<Block, Integer> setupLayoutEditorTurnoutDetails(List<LayoutBlock> blks, SignalMast destination);
689
690    @Override
691    public void vetoableChange(java.beans.PropertyChangeEvent evt) throws java.beans.PropertyVetoException;
692
693}