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 NUM_WHATS = 19; // Must correspond to the number of entries above
074    // other action 'whats" may be defined above, increment NUM_WHATS to match
075
076    // For loadtraininfo loco address type
077    public static final int LOCOADDRESSTYPEDEFAULT = 0;
078    public static final int LOCOADDRESSTYPEROSTER = 1;
079    public static final int LOCOADDRESSTYPENUMBER = 2;
080    public static final int LOCOADDRESSTYPECURRENT = 3;
081
082    /**
083     * Create a TransitSectionAction.
084     *
085     * @param when one of
086     *             {@link #ENTRY}, {@link #EXIT}, {@link #BLOCKENTRY}, {@link #BLOCKEXIT}, {@link #TRAINSTOP}, {@link #TRAINSTART}, {@link #SENSORACTIVE}, {@link #SENSORINACTIVE}, {@link #PRESTARTRESUME}
087     * @param what one of
088     *             {@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}
089     */
090    public TransitSectionAction(int when, int what) {
091        mWhen = when;
092        mWhat = what;
093    }
094
095    /**
096     * Create a TransitSectionAction.
097     *
098     * @param when      one of
099     *                  {@link #ENTRY}, {@link #EXIT}, {@link #BLOCKENTRY}, {@link #BLOCKEXIT}, {@link #TRAINSTOP}, {@link #TRAINSTART}, {@link #SENSORACTIVE}, {@link #SENSORINACTIVE}
100     * @param what      one of
101     *                  {@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}
102     * @param dataWhen  a data element for when
103     * @param dataWhat1 a data element for what
104     * @param dataWhat2 a data element for what
105     * @param sWhen     typically a readable description of when or the name of
106     *                  the triggering sensors
107     * @param sWhat     typically a readable description of what
108     */
109    public TransitSectionAction(int when, int what, int dataWhen, int dataWhat1, int dataWhat2, String sWhen, String sWhat) {
110        mWhen = when;
111        mWhat = what;
112        mDataWhen = dataWhen;
113        mDataWhat1 = dataWhat1;
114        mDataWhat2 = dataWhat2;
115        mStringWhen = sWhen;
116        mStringWhat = sWhat;
117    }
118
119    /**
120     * Create a TransitSectionAction.
121     *
122     * @param when      one of
123     *                  {@link #ENTRY}, {@link #EXIT}, {@link #BLOCKENTRY}, {@link #BLOCKEXIT}, {@link #TRAINSTOP}, {@link #TRAINSTART}, {@link #SENSORACTIVE}, {@link #SENSORINACTIVE}
124     * @param what      one of
125     *                  {@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}
126     * @param dataWhen  a data element for when
127     * @param dataWhat1 a data element for what
128     * @param dataWhat2 a data element for what
129     * @param sWhen     typically a readable description of when or the name of
130     *                  the triggering sensors
131     * @param sWhat     typically a readable description of what or data such as TrainInfo File Name
132     * @param sWhat2    typically a second string parameter for the action such as DCCAddress or roster entry.
133     */
134    public TransitSectionAction(int when, int what, int dataWhen, int dataWhat1, int dataWhat2, String sWhen, String sWhat, String sWhat2) {
135        mWhen = when;
136        mWhat = what;
137        mDataWhen = dataWhen;
138        mDataWhat1 = dataWhat1;
139        mDataWhat2 = dataWhat2;
140        mStringWhen = sWhen;
141        mStringWhat = sWhat;
142        mStringWhat2 = sWhat2;
143    }
144
145
146    // instance variables
147    private int mWhen = 0;
148    private int mWhat = 0;
149    private int mDataWhen = -1; // negative number signified no data 
150    private int mDataWhat1 = -1;    // negative number signified no data 
151    private float mDataWhat1Float = -1.0f;
152    private int mDataWhat2 = -1;    // negative number signified no data 
153    private String mStringWhen = "";
154    private String mStringWhat = "";
155    private String mStringWhat2 = "";
156    private Object threadObject;
157
158    /*
159     * Access methods
160     */
161    public void setThreadObject(Object threadObj) {
162        threadObject = threadObj;
163    }
164    public Object getThreadObject() {
165        return threadObject;
166    }
167    public int getWhenCode() {
168        return mWhen;
169    }
170
171    public void setWhenCode(int n) {
172        mWhen = n;
173    }
174
175    public int getWhatCode() {
176        return mWhat;
177    }
178
179    public void setWhatCode(int n) {
180        mWhat = n;
181    }
182
183    public int getDataWhen() {
184        return mDataWhen;
185    }
186
187    public void setDataWhen(int n) {
188        mDataWhen = n;
189    }
190
191    public float getDataWhat1Float() {
192        return mDataWhat1Float;
193    }
194
195    public void setDataWhat1Float(float n) {
196        mDataWhat1Float = n;
197    }
198
199    public int getDataWhat1() {
200        return mDataWhat1;
201    }
202
203    public void setDataWhat1(int n) {
204        mDataWhat1 = n;
205    }
206
207    public int getDataWhat2() {
208        return mDataWhat2;
209    }
210
211    public void setDataWhat2(int n) {
212        mDataWhat2 = n;
213    }
214
215    public String getStringWhen() {
216        return mStringWhen;
217    }
218
219    public void setStringWhen(String s) {
220        mStringWhen = s;
221    }
222
223    public String getStringWhat() {
224        return mStringWhat;
225    }
226
227    public void setStringWhat(String s) {
228        mStringWhat = s;
229    }
230
231    public String getStringWhat2() {
232        return mStringWhat2;
233    }
234
235    public void setStringWhat2(String s) {
236        mStringWhat2 = s;
237    }
238
239    /*
240     * Operational instance variables - flags and data for executing the action
241     * (see jmri.jmrit.dispatcher.AutoActiveTrain.java)
242     */
243    private Thread _waitingThread = null;
244    private boolean _waitingForSectionExit = false;
245    private TransitSection _targetTransitSection = null;
246    private boolean _waitingForBlock = false;
247    private boolean _waitingForSensor = false;
248    private Sensor _triggerSensor = null;
249    private java.beans.PropertyChangeListener _sensorListener = null;
250
251    /**
252     * Initialize all operational instance variables (not saved between runs).
253     */
254    public void initialize() {
255        _waitingThread = null;
256        _waitingForSectionExit = false;
257        _targetTransitSection = null;
258        _waitingForBlock = false;
259        _waitingForSensor = false;
260        _triggerSensor = null;
261        _sensorListener = null;
262    }
263
264    /*
265     * Operational access methods
266     */
267    public Thread getWaitingThread() {
268        return _waitingThread;
269    }
270
271    public void setWaitingThread(Thread t) {
272        _waitingThread = t;
273    }
274
275    public boolean getWaitingForSectionExit() {
276        return _waitingForSectionExit;
277    }
278
279    public void setWaitingForSectionExit(boolean w) {
280        _waitingForSectionExit = w;
281    }
282
283    public TransitSection getTargetTransitSection() {
284        return _targetTransitSection;
285    }
286
287    public void setTargetTransitSection(TransitSection ts) {
288        _targetTransitSection = ts;
289    }
290
291    public boolean getWaitingForBlock() {
292        return _waitingForBlock;
293    }
294
295    public void setWaitingForBlock(boolean w) {
296        _waitingForBlock = w;
297    }
298
299    public boolean getWaitingForSensor() {
300        return _waitingForSensor;
301    }
302
303    public void setWaitingForSensor(boolean w) {
304        _waitingForSensor = w;
305    }
306
307    public Sensor getTriggerSensor() {
308        return _triggerSensor;
309    }
310
311    public void setTriggerSensor(Sensor s) {
312        _triggerSensor = s;
313    }
314
315    public java.beans.PropertyChangeListener getSensorListener() {
316        return _sensorListener;
317    }
318
319    public void setSensorListener(java.beans.PropertyChangeListener l) {
320        _sensorListener = l;
321    }
322
323    public void disposeSensorListener() {
324        // if this object has registered a listener, dispose of it
325        if (_sensorListener != null) {
326            _triggerSensor.removePropertyChangeListener(_sensorListener);
327            _sensorListener = null;
328            _waitingForSensor = false;
329        }
330    }
331
332    public void dispose() {
333        disposeSensorListener();
334    }
335
336}