001package jmri;
002
003import javax.annotation.CheckForNull;
004
005/**
006 * Signal Groups are used to represent European subsidary signals that would
007 * be sited with a signal mast. Such subsidary signals would be used to
008 * indicated routes, junctions and allowable speeds. Each such
009 * route/junction/speed would be represented by a single output signal (head),
010 * that is either Off or On. Within the group only one such signal head would be
011 * allowed on at any one time.
012 * <p>
013 * The group is attached to a main signal mast, and can be configured to be
014 * activated depending upon one or more aspects when displayed on that signal
015 * mast.
016 * <p>
017 * Each signal head within the group is defined with an On and Off appearance,
018 * and a set of criteria in the form of matching turnouts and sensor states,
019 * that must be met for the head to be set On.
020 * <p>
021 * For code clarity, JMRI uses the terms (signal)Mast and (signal)Head instead
022 * of Signal. Masts show Aspects, Heads show Appearances, though outside the USA
023 * this will vary. Use localization to address this in the user interface.
024 *
025 * @see jmri.implementation.DefaultSignalGroup DefaultSignalGroup
026 *
027 * @author Pete Cressman Copyright (C) 2009
028 * @author Egbert Broerse Copyright (C) 2017
029 */
030public interface SignalGroup extends NamedBean {
031
032    /**
033     * Set enabled status of the signal group.
034     *
035     * @param boo true if signal group should be enabled; false otherwise
036     */
037    void setEnabled(boolean boo);
038
039    /**
040     * Get enabled status of the signal group.
041     *
042     * @return true if signal group is enabled; false otherwise
043     */
044    boolean getEnabled();
045
046    /**
047     * Set the main Signal Mast for the Group by name.
048     *
049     * @param mastName Name of the (existing) Signal Mast to set as main mast
050     *                 for the group
051     */
052    void setSignalMast(String mastName);
053
054    /**
055     * Set the main Signal Mast for the Group.
056     *
057     * @param signalMast Mast object to attach
058     * @param mastName   Name of the (existing) Signal Mast to set as main mast
059     *                   for the group
060     */
061    void setSignalMast(SignalMast signalMast, String mastName);
062
063    /**
064     * Get the name of the main Signal Mast in a group.
065     *
066     * @return Name of the mast as string
067     */
068    String getSignalMastName();
069
070    /**
071     * Get the main Signal Mast in a group.
072     *
073     * @return The main Signal Mast as bean
074     */
075    SignalMast getSignalMast();
076
077    /**
078     * Clear the list of SignalMast Aspects that may trigger the group. Causes
079     * the Aspect list to be rebuilt next time it is called
080     */
081    void clearSignalMastAspect();
082
083    /**
084     * Add an Aspect that can trigger the group activation.
085     *
086     * @param aspect Name of an aspect for the Main Signal Mast in the Group,
087     *               must be valid for the Mast type
088     */
089    void addSignalMastAspect(String aspect);
090
091    /**
092     * Get the total number of Signal Mast Aspects available in this group.
093     *
094     * @return the number of Aspects on the main Signal Mast, null if no Main
095     *         Mast is assigned
096     */
097    int getNumSignalMastAspects();
098
099    /**
100     * Get a SignalMast Aspect for the Main Signal Mast by its Index.
101     *
102     * @param x index of the Signal Mast Aspect in the list
103     * @return the aspect or null if there are no aspects with that index
104     */
105    @CheckForNull
106    String getSignalMastAspectByIndex(int x);
107
108    /**
109     * Inquire if a Signal Mast Aspect is included in the group.
110     *
111     * @param aspect name of the Aspect, i.e. "Clear"
112     * @return true if aspect is included in group
113     */
114    boolean isSignalMastAspectIncluded(String aspect);
115
116    /**
117     * Remove a SignalMast Aspect from the set of triggers.
118     *
119     * @param aspect Name of the Aspect, i.e. "Clear"
120     */
121    void deleteSignalMastAspect(String aspect);
122
123    /**
124     * Add a Signal Head item for this Signal Head to the list in the Group.
125     *
126     * @param headBean The Signal Head as a Named Bean
127     */
128    void addSignalHead(NamedBeanHandle<SignalHead> headBean);
129
130    /**
131     * Add a Signal Head item for this Signal Head to the list in the Group.
132     *
133     * @param signalHead The Signal Head object
134     */
135    void addSignalHead(SignalHead signalHead);
136
137    /**
138     * Get a Signal Head by Index.
139     *
140     * @param x Index of the SignalHead in the Group
141     * @return null if there are no Signal Heads with that index in the group
142     */
143    SignalHead getHeadItemBeanByIndex(int x);
144
145    /**
146     * Get the name of a Signal Head by Index.
147     *
148     * @param x Index of the SignalHead in the Group
149     * @return null if there are no Signal Heads with that index in the group
150     */
151    @CheckForNull
152    String getHeadItemNameByIndex(int x);
153
154    /**
155     * Get the On State for the Signal Head item at Index x in the group.
156     *
157     * @param x Index of the SignalHead in Group
158     * @return -1 if there are less than 'x' Signal Heads defined
159     */
160    int getHeadOnStateByIndex(int x);
161
162    /**
163     * Get the Off State for the Signal Head item at Index x in the group.
164     *
165     * @param x Index of the SignalHead in Group
166     * @return -1 if there are less than 'x' Signal Heads defined
167     */
168    int getHeadOffStateByIndex(int x);
169
170    /**
171     * Remove the Signal Head item for this Signal Head from the group by Name.
172     *
173     * @param sh The Signal Head to be deleted from the group.
174     */
175    void deleteSignalHead(SignalHead sh);
176
177    /**
178     * Remove the Signal Head item for this Signal Head from the group by
179     * NamedBean
180     *
181     * @param headBean The Named Bean to be removed from the group.
182     */
183    void deleteSignalHead(NamedBeanHandle<SignalHead> headBean);
184
185    /**
186     * Get the number of Signal Heads configured as items in this group.
187     *
188     * @return the number of Signal Heads
189     */
190    int getNumHeadItems();
191
192    /**
193     * Inquire if a Signal Head item for this head is included in this Group.
194     *
195     * @param signalHead The Signal Head object we are querying
196     * @return true if the signal head is included in the group; false otherwise
197     */
198    boolean isHeadIncluded(SignalHead signalHead);
199
200    /**
201     * Get the On (conditions met) State of a Signal Head item in the group.
202     *
203     * @param signalHead The Signal Head object we are querying
204     * @return state value for the On state (appearance)
205     */
206    int getHeadOnState(SignalHead signalHead);
207
208    /**
209     * Get the Off (conditions NOT met) State of a Signal Head item in the
210     * group.
211     *
212     * @param signalHead The Signal Head Bean object we are querying
213     * @return state value for the Off state (appearance)
214     */
215    int getHeadOffState(SignalHead signalHead);
216
217    /**
218     * Set the On (conditions met) State of a Signal Head item in the Group.
219     *
220     * @param signalHead The SignalHead Bean
221     * @param state      The Appearance that the SignalHead will change to when
222     *                   the conditions are met.
223     */
224    void setHeadOnState(SignalHead signalHead, int state);
225
226    /**
227     * Set the Off (conditions NOT met) State of a Signal Head item in the
228     * Group.
229     *
230     * @param signalHead The SignalHead Bean
231     * @param state      The Apperance that the SignalHead will change to when
232     *                   the conditions are NOT met.
233     */
234    void setHeadOffState(SignalHead signalHead, int state);
235
236    /**
237     * Set whether the sensors and turnouts should be treated as separate
238     * calculations (OR) or as one (AND) when determining if the Signal Head
239     * should be On or Off.
240     *
241     * @param signalHead The SignalHead Bean
242     * @param boo        Provide true for AND, false for OR
243     */
244    void setSensorTurnoutOper(SignalHead signalHead, boolean boo);
245
246    /**
247     * Get the state of the AND/OR conditional operand for Signal Head at Index.
248     *
249     * @param x Index of the SignalHead in Group
250     * @return true when set to AND, false for OR
251     */
252    boolean getSensorTurnoutOperByIndex(int x);
253
254    /**
255     * Get the number of turnouts configured for the Signal Head at index x.
256     *
257     * @param x Index of the SignalHead in Group
258     * @return -1 if there are less than 'x' Signal Heads defined
259     */
260    int getNumHeadTurnoutsByIndex(int x);
261
262    /**
263     * Add a Turnout and its On state to a Signal Head.
264     *
265     * @param signalHead SignalHead we are adding the turnout to
266     * @param turnout    Turnout Bean
267     * @param state      Value for the turnout On state (Turnout.THROWN or
268     *                   Turnout.CLOSED).
269     */
270    void setHeadAlignTurnout(SignalHead signalHead, Turnout turnout, int state);
271
272    /**
273     * Inquire if a Turnout is included in the Signal Head Calculation.
274     *
275     * @param signalHead signalHead that may consider turnout
276     * @param turnout    turnout to consider
277     * @return true if turnout state is considered; false otherwise
278     */
279    boolean isTurnoutIncluded(SignalHead signalHead, Turnout turnout);
280
281    /**
282     * Get the On state of the Turnout for the given Signal Head in the group.
283     *
284     * @param signalHead Signal Head Bean
285     * @param turnout    The Turnout within the Group
286     * @return -1 if the Turnout or Signal Head is invalid
287     */
288    int getTurnoutState(SignalHead signalHead, Turnout turnout);
289
290    /**
291     * Get the On state of a given Turnout for the Signal Head at index x.
292     *
293     * @param x       Index for the Signal Head in the group
294     * @param turnout Name of the Turnout configured for the head
295     * @return -1 if the Turnout or Signal Head is invalid
296     */
297    int getTurnoutStateByIndex(int x, Turnout turnout);
298
299    /**
300     * Get the On state of the Turnout at index pTurnout, for the Signal Head at
301     * index x in the group.
302     *
303     * @param x        Index for the Signal Head in the group
304     * @param pTurnout Index of the Turnout configured for the head
305     * @return -1 if the Turnout or Signal Head is invalid
306     */
307    int getTurnoutStateByIndex(int x, int pTurnout);
308
309    /**
310     * Get the Name of the Turnout at index pTurnout, for the Signal Head at
311     * index x in the group.
312     *
313     * @param x        Index for the Signal Head in the group
314     * @param pTurnout Index for the turnout in the signal head item
315     * @return null if the Turnout or Signal Head is invalid
316     */
317    @CheckForNull
318    String getTurnoutNameByIndex(int x, int pTurnout);
319
320    /**
321     * Get the Turnout at index x, for the Signal Head at index x in the group.
322     *
323     * @param x        Index for the Signal Head in the group
324     * @param pTurnout Index for the turnout in the signal head item
325     * @return null if the Turnout or Signal Head is invalid
326     */
327    @CheckForNull
328    Turnout getTurnoutByIndex(int x, int pTurnout);
329
330    /**
331     * Add a Sensor and its On state to a Signal Head.
332     *
333     * @param signalHead Signal Head we are adding the sensor to
334     * @param sensor     Sensor Bean
335     * @param state      Value for the Sensor On state (Sensor.ACTIVE or
336     *                   Sensor.INACTIVE).
337     */
338    void setHeadAlignSensor(SignalHead signalHead, Sensor sensor, int state);
339
340    /**
341     * Inquire if a Sensor is included in the Signal Head Calculation.
342     *
343     * @param signalHead Signal Head Bean
344     * @param sensor     Sensor Bean
345     * @return true if sensor is considered for signalHead state; false
346     *         otherwise
347     */
348    boolean isSensorIncluded(SignalHead signalHead, Sensor sensor);
349
350    /**
351     * Get the On state of the Sensor for the Signal Head in the group.
352     *
353     * @param signalHead The Signal Head Bean
354     * @param sensor     Name of the Sensor in the head item
355     * @return -1 if the Sensor or Signal Head is invalid
356     */
357    int getSensorState(SignalHead signalHead, Sensor sensor);
358
359    /**
360     * Get the On state of the Sensor at index pSensor for the Signal Head at
361     * index x.
362     *
363     * @param x       Index for the Signal Head in the group
364     * @param pSensor Index of the Sensor in the head item
365     * @return -1 if the Sensor or Signal Head is invalid
366     */
367    int getSensorStateByIndex(int x, int pSensor);
368
369    /**
370     * Get the name of the Sensor at index pSensor for the Signal Head at index
371     * x.
372     *
373     * @param x       Index for the Signal Head in the group
374     * @param pSensor Index of the Sensor in the head item
375     * @return null if the Sensor or Signal Head is invalid
376     */
377    @CheckForNull
378    String getSensorNameByIndex(int x, int pSensor);
379
380    /**
381     * Get the Sensor at index pSensor, for the Signal Head at index x.
382     *
383     * @param x       Index for the Signal Head in the group
384     * @param pSensor Index of the Sensor in the head item
385     * @return null if the Sensor or Signal Head is invalid
386     */
387    @CheckForNull
388    Sensor getSensorByIndex(int x, int pSensor);
389
390    /**
391     * Get the AND/OR conditional operand set for a Signal Head in the group.
392     *
393     * @param signalHead The Signal Head Bean
394     * @return true when set to AND, false for OR
395     */
396    boolean getSensorTurnoutOper(SignalHead signalHead);
397
398    /**
399     * Get the number of Sensors configured for the Signal Head at index x.
400     *
401     * @param x Index for the Signal Head in the group
402     * @return -1 if there are less than 'x' Signal Heads defined
403     */
404    int getNumHeadSensorsByIndex(int x);
405
406    /**
407     * Delete all Turnouts for a given Signal Head in the group.
408     *
409     * @param signalHead The Signal Head Bean from which the Turnouts will be
410     *                   removed
411     */
412    void clearHeadTurnout(SignalHead signalHead);
413
414    /**
415     * Delete all Sensors for a given Signal Head in the group.
416     *
417     * @param signalHead The Signal Head Bean from which the Turnouts will be
418     *                   removed
419     */
420    void clearHeadSensor(SignalHead signalHead);
421
422    @Override
423    int getState();
424
425    @Override
426    void setState(int state);
427
428    int ONACTIVE = 0;    // group head conditional fires if sensor goes active
429    int ONINACTIVE = 1;  // group head conditional fires if sensor goes inactive
430
431    int ONCLOSED = 2;    // group head conditional fires if turnout goes closed
432    int ONTHROWN = 4;  // group head conditional fires if turnout goes thrown
433}