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