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 float mDataWhat2Float = -1.0f;
155    private String mStringWhen = "";
156    private String mStringWhat = "";
157    private String mStringWhat2 = "";
158    private Object threadObject;
159
160    /*
161     * Access methods
162     */
163    public void setThreadObject(Object threadObj) {
164        threadObject = threadObj;
165    }
166    public Object getThreadObject() {
167        return threadObject;
168    }
169    public int getWhenCode() {
170        return mWhen;
171    }
172
173    public void setWhenCode(int n) {
174        mWhen = n;
175    }
176
177    public int getWhatCode() {
178        return mWhat;
179    }
180
181    public void setWhatCode(int n) {
182        mWhat = n;
183    }
184
185    public int getDataWhen() {
186        return mDataWhen;
187    }
188
189    public void setDataWhen(int n) {
190        mDataWhen = n;
191    }
192
193    public float getDataWhat1Float() {
194        return mDataWhat1Float;
195    }
196
197    public void setDataWhat1Float(float n) {
198        mDataWhat1Float = n;
199    }
200
201    public float getDataWhat2Float() {
202        return mDataWhat2Float;
203    }
204
205    public void setDataWhat2Float(float n) {
206        mDataWhat2Float = n;
207    }
208
209    public int getDataWhat1() {
210        return mDataWhat1;
211    }
212
213    public void setDataWhat1(int n) {
214        mDataWhat1 = n;
215    }
216
217    public int getDataWhat2() {
218        return mDataWhat2;
219    }
220
221    public void setDataWhat2(int n) {
222        mDataWhat2 = n;
223    }
224
225    public String getStringWhen() {
226        return mStringWhen;
227    }
228
229    public void setStringWhen(String s) {
230        mStringWhen = s;
231    }
232
233    public String getStringWhat() {
234        return mStringWhat;
235    }
236
237    public void setStringWhat(String s) {
238        mStringWhat = s;
239    }
240
241    public String getStringWhat2() {
242        return mStringWhat2;
243    }
244
245    public void setStringWhat2(String s) {
246        mStringWhat2 = s;
247    }
248
249    /*
250     * Operational instance variables - flags and data for executing the action
251     * (see jmri.jmrit.dispatcher.AutoActiveTrain.java)
252     */
253    private Thread _waitingThread = null;
254    private boolean _waitingForSectionExit = false;
255    private TransitSection _targetTransitSection = null;
256    private boolean _waitingForBlock = false;
257    private boolean _waitingForSensor = false;
258    private Sensor _triggerSensor = null;
259    private java.beans.PropertyChangeListener _sensorListener = null;
260
261    /**
262     * Initialize all operational instance variables (not saved between runs).
263     */
264    public void initialize() {
265        _waitingThread = null;
266        _waitingForSectionExit = false;
267        _targetTransitSection = null;
268        _waitingForBlock = false;
269        _waitingForSensor = false;
270        _triggerSensor = null;
271        _sensorListener = null;
272    }
273
274    /*
275     * Operational access methods
276     */
277    public Thread getWaitingThread() {
278        return _waitingThread;
279    }
280
281    public void setWaitingThread(Thread t) {
282        _waitingThread = t;
283    }
284
285    public boolean getWaitingForSectionExit() {
286        return _waitingForSectionExit;
287    }
288
289    public void setWaitingForSectionExit(boolean w) {
290        _waitingForSectionExit = w;
291    }
292
293    public TransitSection getTargetTransitSection() {
294        return _targetTransitSection;
295    }
296
297    public void setTargetTransitSection(TransitSection ts) {
298        _targetTransitSection = ts;
299    }
300
301    public boolean getWaitingForBlock() {
302        return _waitingForBlock;
303    }
304
305    public void setWaitingForBlock(boolean w) {
306        _waitingForBlock = w;
307    }
308
309    public boolean getWaitingForSensor() {
310        return _waitingForSensor;
311    }
312
313    public void setWaitingForSensor(boolean w) {
314        _waitingForSensor = w;
315    }
316
317    public Sensor getTriggerSensor() {
318        return _triggerSensor;
319    }
320
321    public void setTriggerSensor(Sensor s) {
322        _triggerSensor = s;
323    }
324
325    public java.beans.PropertyChangeListener getSensorListener() {
326        return _sensorListener;
327    }
328
329    public void setSensorListener(java.beans.PropertyChangeListener l) {
330        _sensorListener = l;
331    }
332
333    public void disposeSensorListener() {
334        // if this object has registered a listener, dispose of it
335        if (_sensorListener != null) {
336            _triggerSensor.removePropertyChangeListener(_sensorListener);
337            _sensorListener = null;
338            _waitingForSensor = false;
339        }
340    }
341
342    public void dispose() {
343        disposeSensorListener();
344    }
345
346}