001package jmri;
002
003/**
004 * This class holds information and options for a Action to be applied when an
005 * automated train enters, exits, or is inside of a Section in a Transit.
006 * <p>
007 * A TransitSection holds specified TrainsitSectionActions. A TransitSection may
008 * have as many TransitSectionActions as appropriate. Each TransitSectionAction
009 * belongs to one and only one TransitSection.
010 * <p>
011 * TransitSectionActions are specified in two parts: 1. The "When" part
012 * specifies when after the automated train enters the Section the action is to
013 * be initiated. Optionally, each "when" may be delayed by a specified time (in
014 * milliseconds). 2. The "What" part specified what action is to occur.
015 * <p>
016 * TransitSectionActions are created and edited in the Transit Table, when
017 * Transits are defined.
018 * <p>
019 * This class provides support for SENSORACTIVE and SENSORINACTIVE "when"'s.
020 *
021 * @author Dave Duchamp Copyright (C) 2009, 2010
022 */
023public class TransitSectionAction {
024
025    /**
026     * Constants representing the "when" (when the action is to be initiated) of
027     * the Action.
028     * 
029     * TODO: Convert to ENUM
030     */
031    public static final int NUM_WHENS = 10; // Must correspond to the number of entries below
032    public static final int SELECTWHEN = 0;
033    public static final int ENTRY = 1;   // On entry to Section
034    public static final int EXIT = 2;   // On exit from Section
035    public static final int BLOCKENTRY = 3; // On entry to specified Block in the Section
036    public static final int BLOCKEXIT = 4; // On exit from specified Block in the Section
037    public static final int TRAINSTOP = 5;  // When train stops
038    public static final int TRAINSTART = 6; // When train starts 
039    public static final int SENSORACTIVE = 7; // When specified Sensor changes to Active
040    public static final int SENSORINACTIVE = 8; // When specified Sensor changtes to Inactive
041    public static final int PRESTARTDELAY = 9; // delays the throttle going from 0
042    public static final int PRESTARTACTION = 10; // Actions timed of prestartdelay
043
044    // other action 'whens" may be defined here
045
046    /**
047     * Constants designating the "what" (the action to be taken) of the Action.
048     * 
049     * TODO: Convert to ENUM
050     */
051    public static final int SELECTWHAT = 0;
052    public static final int PAUSE = 1;    // pause for the number of fast minutes in mDataWhat (e.g. station stop)
053    public static final int SETMAXSPEED = 2; // set maximum train speed to value entered
054    public static final int SETCURRENTSPEED = 3; // set current speed to target speed immediately - no ramping
055    public static final int RAMPTRAINSPEED = 4; // set current speed to target with ramping
056    public static final int TOMANUALMODE = 5; // drop out of automated mode, and allow manual throttle control
057    public static final int SETLIGHT = 6; // set light on or off
058    public static final int STARTBELL = 7;  // start bell (only works with sound decoder, function 1 ON)
059    public static final int STOPBELL = 8;   // stop bell (only works with sound decoder, function 1 OFF)
060    public static final int SOUNDHORN = 9;  // sound horn for specified number of milliseconds 
061    // (only works with sound decoder, function 2)
062    public static final int SOUNDHORNPATTERN = 10; // sound horn according to specified pattern
063    // (only works with sound decoder, function 2)
064    public static final int LOCOFUNCTION = 11;  // execute the specified decoder function
065    public static final int SETSENSORACTIVE = 12; // set specified sensor active (offers access to Logix)
066    public static final int SETSENSORINACTIVE = 13; // set specified sensor inactive
067    public static final int HOLDSIGNAL = 14;    // set specified signalhead or signalmast to HELD
068    public static final int RELEASESIGNAL = 15; // set specified signalhead or signalmast to NOT HELD
069    public static final int ESTOP = 16;   // set ESTOP
070    public static final int PRESTARTRESUME = 17; // Resume after prestart
071    public static final int TERMINATETRAIN = 18; // terminate train
072    public static final int LOADTRAININFO = 19; // terminate train and run traininfo file
073    public static final int FORCEALLOCATEPASSSAFESECTION = 20;  // attempt to force allocation to safesection beyond next safe section.
074    public static final int NUM_WHATS = 20; // Must correspond to the number of entries above
075    // other action 'whats" may be defined above, increment NUM_WHATS to match
076
077    // For loadtraininfo loco address type
078    public static final int LOCOADDRESSTYPEDEFAULT = 0;
079    public static final int LOCOADDRESSTYPEROSTER = 1;
080    public static final int LOCOADDRESSTYPENUMBER = 2;
081    public static final int LOCOADDRESSTYPECURRENT = 3;
082
083    /**
084     * Create a TransitSectionAction.
085     *
086     * @param when one of
087     *             {@link #ENTRY}, {@link #EXIT}, {@link #BLOCKENTRY}, {@link #BLOCKEXIT}, {@link #TRAINSTOP}, {@link #TRAINSTART}, {@link #SENSORACTIVE}, {@link #SENSORINACTIVE}, {@link #PRESTARTRESUME}
088     * @param what one of
089     *             {@link #PAUSE}, {@link #SETMAXSPEED}, {@link #SETCURRENTSPEED}, {@link #RAMPTRAINSPEED}, {@link #TOMANUALMODE}, {@link #SETLIGHT}, {@link #STARTBELL}, {@link #STOPBELL}, {@link #SOUNDHORN}, {@link #SOUNDHORNPATTERN}, {@link #LOCOFUNCTION}, {@link #SETSENSORACTIVE}, {@link #SETSENSORINACTIVE}, {@link #HOLDSIGNAL}, {@link #RELEASESIGNAL}
090     */
091    public TransitSectionAction(int when, int what) {
092        mWhen = when;
093        mWhat = what;
094    }
095
096    /**
097     * Create a TransitSectionAction.
098     *
099     * @param when      one of
100     *                  {@link #ENTRY}, {@link #EXIT}, {@link #BLOCKENTRY}, {@link #BLOCKEXIT}, {@link #TRAINSTOP}, {@link #TRAINSTART}, {@link #SENSORACTIVE}, {@link #SENSORINACTIVE}
101     * @param what      one of
102     *                  {@link #PAUSE}, {@link #SETMAXSPEED}, {@link #SETCURRENTSPEED}, {@link #RAMPTRAINSPEED}, {@link #TOMANUALMODE}, {@link #SETLIGHT}, {@link #STARTBELL}, {@link #STOPBELL}, {@link #SOUNDHORN}, {@link #SOUNDHORNPATTERN}, {@link #LOCOFUNCTION}, {@link #SETSENSORACTIVE}, {@link #SETSENSORINACTIVE}, {@link #HOLDSIGNAL}, {@link #RELEASESIGNAL}
103     * @param dataWhen  a data element for when
104     * @param dataWhat1 a data element for what
105     * @param dataWhat2 a data element for what
106     * @param sWhen     typically a readable description of when or the name of
107     *                  the triggering sensors
108     * @param sWhat     typically a readable description of what
109     */
110    public TransitSectionAction(int when, int what, int dataWhen, int dataWhat1, int dataWhat2, String sWhen, String sWhat) {
111        mWhen = when;
112        mWhat = what;
113        mDataWhen = dataWhen;
114        mDataWhat1 = dataWhat1;
115        mDataWhat2 = dataWhat2;
116        mStringWhen = sWhen;
117        mStringWhat = sWhat;
118    }
119
120    /**
121     * Create a TransitSectionAction.
122     *
123     * @param when      one of
124     *                  {@link #ENTRY}, {@link #EXIT}, {@link #BLOCKENTRY}, {@link #BLOCKEXIT}, {@link #TRAINSTOP}, {@link #TRAINSTART}, {@link #SENSORACTIVE}, {@link #SENSORINACTIVE}
125     * @param what      one of
126     *                  {@link #PAUSE}, {@link #SETMAXSPEED}, {@link #SETCURRENTSPEED}, {@link #RAMPTRAINSPEED}, {@link #TOMANUALMODE}, {@link #SETLIGHT}, {@link #STARTBELL}, {@link #STOPBELL}, {@link #SOUNDHORN}, {@link #SOUNDHORNPATTERN}, {@link #LOCOFUNCTION}, {@link #SETSENSORACTIVE}, {@link #SETSENSORINACTIVE}, {@link #HOLDSIGNAL}, {@link #RELEASESIGNAL}
127     * @param dataWhen  a data element for when
128     * @param dataWhat1 a data element for what
129     * @param dataWhat2 a data element for what
130     * @param sWhen     typically a readable description of when or the name of
131     *                  the triggering sensors
132     * @param sWhat     typically a readable description of what or data such as TrainInfo File Name
133     * @param sWhat2    typically a second string parameter for the action such as DCCAddress or roster entry.
134     */
135    public TransitSectionAction(int when, int what, int dataWhen, int dataWhat1, int dataWhat2, String sWhen, String sWhat, String sWhat2) {
136        mWhen = when;
137        mWhat = what;
138        mDataWhen = dataWhen;
139        mDataWhat1 = dataWhat1;
140        mDataWhat2 = dataWhat2;
141        mStringWhen = sWhen;
142        mStringWhat = sWhat;
143        mStringWhat2 = sWhat2;
144    }
145
146
147    // instance variables
148    private int mWhen = 0;
149    private int mWhat = 0;
150    private int mDataWhen = -1; // negative number signified no data 
151    private int mDataWhat1 = -1;    // negative number signified no data 
152    private float mDataWhat1Float = -1.0f;
153    private int mDataWhat2 = -1;    // negative number signified no data 
154    private String mStringWhen = "";
155    private String mStringWhat = "";
156    private String mStringWhat2 = "";
157    private Object threadObject;
158
159    /*
160     * Access methods
161     */
162    public void setThreadObject(Object threadObj) {
163        threadObject = threadObj;
164    }
165    public Object getThreadObject() {
166        return threadObject;
167    }
168    public int getWhenCode() {
169        return mWhen;
170    }
171
172    public void setWhenCode(int n) {
173        mWhen = n;
174    }
175
176    public int getWhatCode() {
177        return mWhat;
178    }
179
180    public void setWhatCode(int n) {
181        mWhat = n;
182    }
183
184    public int getDataWhen() {
185        return mDataWhen;
186    }
187
188    public void setDataWhen(int n) {
189        mDataWhen = n;
190    }
191
192    public float getDataWhat1Float() {
193        return mDataWhat1Float;
194    }
195
196    public void setDataWhat1Float(float n) {
197        mDataWhat1Float = n;
198    }
199
200    public int getDataWhat1() {
201        return mDataWhat1;
202    }
203
204    public void setDataWhat1(int n) {
205        mDataWhat1 = n;
206    }
207
208    public int getDataWhat2() {
209        return mDataWhat2;
210    }
211
212    public void setDataWhat2(int n) {
213        mDataWhat2 = n;
214    }
215
216    public String getStringWhen() {
217        return mStringWhen;
218    }
219
220    public void setStringWhen(String s) {
221        mStringWhen = s;
222    }
223
224    public String getStringWhat() {
225        return mStringWhat;
226    }
227
228    public void setStringWhat(String s) {
229        mStringWhat = s;
230    }
231
232    public String getStringWhat2() {
233        return mStringWhat2;
234    }
235
236    public void setStringWhat2(String s) {
237        mStringWhat2 = s;
238    }
239
240    /*
241     * Operational instance variables - flags and data for executing the action
242     * (see jmri.jmrit.dispatcher.AutoActiveTrain.java)
243     */
244    private Thread _waitingThread = null;
245    private boolean _waitingForSectionExit = false;
246    private TransitSection _targetTransitSection = null;
247    private boolean _waitingForBlock = false;
248    private boolean _waitingForSensor = false;
249    private Sensor _triggerSensor = null;
250    private java.beans.PropertyChangeListener _sensorListener = null;
251
252    /**
253     * Initialize all operational instance variables (not saved between runs).
254     */
255    public void initialize() {
256        _waitingThread = null;
257        _waitingForSectionExit = false;
258        _targetTransitSection = null;
259        _waitingForBlock = false;
260        _waitingForSensor = false;
261        _triggerSensor = null;
262        _sensorListener = null;
263    }
264
265    /*
266     * Operational access methods
267     */
268    public Thread getWaitingThread() {
269        return _waitingThread;
270    }
271
272    public void setWaitingThread(Thread t) {
273        _waitingThread = t;
274    }
275
276    public boolean getWaitingForSectionExit() {
277        return _waitingForSectionExit;
278    }
279
280    public void setWaitingForSectionExit(boolean w) {
281        _waitingForSectionExit = w;
282    }
283
284    public TransitSection getTargetTransitSection() {
285        return _targetTransitSection;
286    }
287
288    public void setTargetTransitSection(TransitSection ts) {
289        _targetTransitSection = ts;
290    }
291
292    public boolean getWaitingForBlock() {
293        return _waitingForBlock;
294    }
295
296    public void setWaitingForBlock(boolean w) {
297        _waitingForBlock = w;
298    }
299
300    public boolean getWaitingForSensor() {
301        return _waitingForSensor;
302    }
303
304    public void setWaitingForSensor(boolean w) {
305        _waitingForSensor = w;
306    }
307
308    public Sensor getTriggerSensor() {
309        return _triggerSensor;
310    }
311
312    public void setTriggerSensor(Sensor s) {
313        _triggerSensor = s;
314    }
315
316    public java.beans.PropertyChangeListener getSensorListener() {
317        return _sensorListener;
318    }
319
320    public void setSensorListener(java.beans.PropertyChangeListener l) {
321        _sensorListener = l;
322    }
323
324    public void disposeSensorListener() {
325        // if this object has registered a listener, dispose of it
326        if (_sensorListener != null) {
327            _triggerSensor.removePropertyChangeListener(_sensorListener);
328            _sensorListener = null;
329            _waitingForSensor = false;
330        }
331    }
332
333    public void dispose() {
334        disposeSensorListener();
335    }
336
337}