001package jmri;
002
003import java.beans.PropertyChangeEvent;
004import java.beans.PropertyChangeListener;
005import java.util.List;
006import java.util.ArrayList;
007import java.util.Arrays;
008import java.util.Collections;
009import java.util.Set;
010import java.util.HashSet;
011import java.util.ResourceBundle;
012import javax.annotation.Nonnull;
013
014/**
015 * A Conditional is layout control logic, consisting of a logical expression and
016 * an action.
017 * <p>
018 * A Conditional does not exist on its own, but is part of a Logix. The system
019 * name of each Conditional is set automatically when the conditional is
020 * created. It begins with the system name of its parent Logix. There is no
021 * Conditional Table. Conditionals are created, editted, and deleted via the
022 * Logix Table.
023 * <p>
024 * A Conditional has a "state", which changes depending on whether its logical
025 * expression calculates to TRUE or FALSE. The "state" may not be changed by the
026 * user. It only changes in response to changes in the "state variables" used in
027 * its logical expression.
028 * <p>
029 * Listeners may be set to monitor a change in the state of a conditional.
030 *
031 * <hr>
032 * This file is part of JMRI.
033 * <p>
034 * JMRI is free software; you can redistribute it and/or modify it under the
035 * terms of version 2 of the GNU General Public License as published by the Free
036 * Software Foundation. See the "COPYING" file for a copy of this license.
037 * <p>
038 * JMRI is distributed in the hope that it will be useful, but WITHOUT ANY
039 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
040 * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
041 *
042 * @author Dave Duchamp Copyright (C) 2007, 2008
043 * @author Pete Cressman Copyright (C) 2009, 2010, 2011
044 * @author Matthew Harris copyright (c) 2009
045 */
046public interface Conditional extends NamedBean {
047
048    ResourceBundle rbx = ResourceBundle.getBundle("jmri.jmrit.conditional.ConditionalBundle");
049    ResourceBundle rbxWarrant = ResourceBundle.getBundle("jmri.jmrit.logix.WarrantBundle");
050
051    // states
052    @SuppressWarnings("hiding")     // Field has same name as a field in the super class
053    enum State {
054        UNKNOWN(NamedBean.UNKNOWN, "StateUnknown"),
055        FALSE(Conditional.FALSE, "StateFalse"),
056        TRUE(Conditional.TRUE, "StateTrue");
057
058        private final int _state;
059        private final String _bundleKey;
060
061        private State(int state, String bundleKey) {
062            _state = state;
063            _bundleKey = bundleKey;
064        }
065
066        public int getIntValue() {
067            return _state;
068        }
069
070        public static State getOperatorFromIntValue(int stateInt) {
071            for (State state : State.values()) {
072                if (state.getIntValue() == stateInt) {
073                    return state;
074                }
075            }
076
077            throw new IllegalArgumentException("State is unknown");
078        }
079
080        @Override
081        public String toString() {
082            return Bundle.getMessage(_bundleKey);
083        }
084    }
085
086    public static final int FALSE = 0x02;
087    public static final int TRUE = 0x04;
088
089    @SuppressWarnings("hiding")     // Field has same name as a field in the super class
090    public enum AntecedentOperator {
091        ALL_AND(Conditional.ALL_AND, Bundle.getMessage("LogicAND")),
092        ALL_OR(Conditional.ALL_OR, Bundle.getMessage("LogicOR")),
093        MIXED(Conditional.MIXED, Bundle.getMessage("LogicMixed"));
094
095        private final int _value;
096        private final String _string;
097
098        private AntecedentOperator(int value, String string) {
099            _value = value;
100            _string = string;
101        }
102
103        public int getIntValue() {
104            return _value;
105        }
106
107        public static AntecedentOperator getOperatorFromIntValue(int value) {
108            for (AntecedentOperator antecedentOperators : AntecedentOperator.values()) {
109                if (antecedentOperators.getIntValue() == value) {
110                    return antecedentOperators;
111                }
112            }
113
114            throw new IllegalArgumentException("ItemType is unknown");
115        }
116
117        @Override
118        public String toString() {
119            return _string;
120        }
121    }
122
123    // logic operators used in antecedent
124    static final int ALL_AND = 0x01;
125    static final int ALL_OR = 0x02;
126    static final int MIXED = 0x03;
127
128    public enum Operator {
129        NONE,
130        AND,
131        OR;
132
133        // This method is used by DefaultConditionalManagerXml.store() for backward compatibility
134        public int getIntValue() {
135            switch (this) {
136                case NONE: return OPERATOR_NONE;
137                case AND: return OPERATOR_AND;
138                case OR: return OPERATOR_OR;
139                default: throw new IllegalArgumentException(String.format("operator %s is unknown", this.name()));
140            }
141        }
142
143        // This method is used by DefaultConditionalManagerXml.loadConditionals() for backward compatibility
144        public static Operator getOperatorFromIntValue(int opern) {
145            switch (opern) {
146                case OPERATOR_AND: return Operator.AND;
147                case OPERATOR_NONE: return Operator.NONE;
148                case OPERATOR_OR: return Operator.OR;
149                default: throw new IllegalArgumentException(String.format("operator %d is unknown", opern));
150            }
151        }
152    }
153
154    // state variable definitions. Keep these since they are needed
155    // for backward compatibility in DefaultConditionalManagerXml.
156    // But they are not used elsewhere.
157    static final int OPERATOR_AND = 1;
158    static final int OPERATOR_NONE = 4;
159    static final int OPERATOR_OR = 5;
160
161    // state variable and action items used by logix.
162    enum ItemType {
163        NONE(TYPE_NONE, IsStateVar.IS_STATE_VAR, "ItemTypeNone"),        // There is no ITEM_TYPE_NONE so use TYPE_NONE instead
164        SENSOR(ITEM_TYPE_SENSOR, IsStateVar.IS_STATE_VAR, "ItemTypeSensor"),
165        TURNOUT(ITEM_TYPE_TURNOUT, IsStateVar.IS_STATE_VAR, "ItemTypeTurnout"),
166        LIGHT(ITEM_TYPE_LIGHT, IsStateVar.IS_STATE_VAR, "ItemTypeLight"),
167        SIGNALHEAD(ITEM_TYPE_SIGNALHEAD, IsStateVar.IS_STATE_VAR, "ItemTypeSignalHead"),
168        SIGNALMAST(ITEM_TYPE_SIGNALMAST, IsStateVar.IS_STATE_VAR, "ItemTypeSignalMast"),
169        MEMORY(ITEM_TYPE_MEMORY, IsStateVar.IS_STATE_VAR, "ItemTypeMemory"),
170        CONDITIONAL(ITEM_TYPE_CONDITIONAL, IsStateVar.IS_STATE_VAR, "ItemTypeConditional"),  // used only by ConditionalVariable
171        LOGIX(ITEM_TYPE_LOGIX, IsStateVar.IS_STATE_VAR, "ItemTypeLogix"),                    // used only by ConditionalAction
172        WARRANT(ITEM_TYPE_WARRANT, IsStateVar.IS_STATE_VAR, "ItemTypeWarrant"),
173        CLOCK(ITEM_TYPE_CLOCK, IsStateVar.IS_STATE_VAR, "ItemTypeClock"),
174        OBLOCK(ITEM_TYPE_OBLOCK, IsStateVar.IS_STATE_VAR, "ItemTypeOBlock"),
175        ENTRYEXIT(ITEM_TYPE_ENTRYEXIT, IsStateVar.IS_STATE_VAR, "ItemTypeEntryExit"),
176
177        AUDIO(ITEM_TYPE_AUDIO, IsStateVar.IS_NOT_STATE_VAR, "ItemTypeAudio"),
178        SCRIPT(ITEM_TYPE_SCRIPT, IsStateVar.IS_NOT_STATE_VAR, "ItemTypeScript"),
179        OTHER(ITEM_TYPE_OTHER, IsStateVar.IS_NOT_STATE_VAR, "ItemTypeOther");
180
181        private final int _type;
182        private IsStateVar _isStateVar;
183        private final String _bundleKey;
184
185        private static final List<ItemType> stateVarList;
186
187        static
188        {
189            stateVarList = new ArrayList<>();
190
191            for (ItemType itemType : ItemType.values()) {
192                if (itemType._isStateVar == IsStateVar.IS_STATE_VAR) {
193                    stateVarList.add(itemType);
194                }
195            }
196        }
197
198        private ItemType(int type, IsStateVar isStateVar, String bundleKey) {
199            _type = type;
200            _isStateVar = isStateVar;
201            _bundleKey = bundleKey;
202        }
203
204        public static List<ItemType> getStateVarList() {
205            return stateVarList;
206        }
207
208        public int getIntValue() {
209            return _type;
210        }
211
212        public static ItemType getOperatorFromIntValue(int itemTypeInt) {
213            for (ItemType itemType : ItemType.values()) {
214                if (itemType.getIntValue() == itemTypeInt) {
215                    return itemType;
216                }
217            }
218
219            throw new IllegalArgumentException("ItemType is unknown");
220        }
221
222        @Override
223        public String toString() {
224            return Bundle.getMessage(_bundleKey);
225        }
226
227        // This enum is only used within the outer enum ItemType.
228        private enum IsStateVar {
229            IS_STATE_VAR,
230            IS_NOT_STATE_VAR
231        }
232    }
233
234    // items
235    enum Type {
236        ERROR(TYPE_ERROR, ItemType.NONE, "", ""), // NOI18N
237        NONE(TYPE_NONE, ItemType.NONE, "", ""), // NOI18N
238        SENSOR_ACTIVE(TYPE_SENSOR_ACTIVE, ItemType.SENSOR, Bundle.getMessage("SensorStateActive"), rbx.getString("TypeSensorActive")), // NOI18N
239        SENSOR_INACTIVE(TYPE_SENSOR_INACTIVE, ItemType.SENSOR, Bundle.getMessage("SensorStateInactive"), rbx.getString("TypeSensorInactive")), // NOI18N
240        TURNOUT_THROWN(TYPE_TURNOUT_THROWN, ItemType.TURNOUT, Bundle.getMessage("TurnoutStateThrown"), rbx.getString("TypeTurnoutThrown")), // NOI18N
241        TURNOUT_CLOSED(TYPE_TURNOUT_CLOSED, ItemType.TURNOUT, Bundle.getMessage("TurnoutStateClosed"), rbx.getString("TypeTurnoutClosed")), // NOI18N
242        CONDITIONAL_TRUE(TYPE_CONDITIONAL_TRUE, ItemType.CONDITIONAL, Bundle.getMessage("True"), rbx.getString("TypeConditionalTrue")), // NOI18N
243        CONDITIONAL_FALSE(TYPE_CONDITIONAL_FALSE, ItemType.CONDITIONAL, Bundle.getMessage("False"), rbx.getString("TypeConditionalFalse")), // NOI18N
244        LIGHT_ON(TYPE_LIGHT_ON, ItemType.LIGHT, rbx.getString("LightOn"), rbx.getString("TypeLightOn")), // NOI18N
245        LIGHT_OFF(TYPE_LIGHT_OFF, ItemType.LIGHT, rbx.getString("LightOff"), rbx.getString("TypeLightOff")), // NOI18N
246        MEMORY_EQUALS(TYPE_MEMORY_EQUALS, ItemType.MEMORY, rbx.getString("StateMemoryEquals"), rbx.getString("TypeMemoryEquals")), // NOI18N
247        MEMORY_COMPARE(TYPE_MEMORY_COMPARE, ItemType.MEMORY, rbx.getString("StateMemoryCompare"), rbx.getString("TypeMemoryCompare")), // NOI18N
248        MEMORY_EQUALS_INSENSITIVE(TYPE_MEMORY_EQUALS_INSENSITIVE, ItemType.MEMORY, rbx.getString("StateMemoryEqualsInsensitive"), rbx.getString("TypeMemoryEqualsInsensitive")), // NOI18N
249        MEMORY_COMPARE_INSENSITIVE(TYPE_MEMORY_COMPARE_INSENSITIVE, ItemType.MEMORY, rbx.getString("StateMemoryCompareInsensitive"), rbx.getString("TypeMemoryCompareInsensitive")), // NOI18N
250        FAST_CLOCK_RANGE(TYPE_FAST_CLOCK_RANGE, ItemType.CLOCK, rbx.getString("TypeFastClockRange"), rbx.getString("TypeFastClockRange")), // NOI18N
251
252        // Note the set signalHeadAppearanceSet below which holds those SignalHead types that are appearances.
253        SIGNAL_HEAD_RED(TYPE_SIGNAL_HEAD_RED, ItemType.SIGNALHEAD, Bundle.getMessage("SignalHeadStateRed"), Bundle.getMessage("SignalHeadStateRed")), // NOI18N
254        SIGNAL_HEAD_YELLOW(TYPE_SIGNAL_HEAD_YELLOW, ItemType.SIGNALHEAD, Bundle.getMessage("SignalHeadStateYellow"), Bundle.getMessage("SignalHeadStateYellow")), // NOI18N
255        SIGNAL_HEAD_GREEN(TYPE_SIGNAL_HEAD_GREEN, ItemType.SIGNALHEAD, Bundle.getMessage("SignalHeadStateGreen"), Bundle.getMessage("SignalHeadStateGreen")), // NOI18N
256        SIGNAL_HEAD_DARK(TYPE_SIGNAL_HEAD_DARK, ItemType.SIGNALHEAD, Bundle.getMessage("SignalHeadStateDark"), Bundle.getMessage("SignalHeadStateDark")), // NOI18N
257        SIGNAL_HEAD_FLASHRED(TYPE_SIGNAL_HEAD_FLASHRED, ItemType.SIGNALHEAD, Bundle.getMessage("SignalHeadStateFlashingRed"), Bundle.getMessage("SignalHeadStateFlashingRed")), // NOI18N
258        SIGNAL_HEAD_FLASHYELLOW(TYPE_SIGNAL_HEAD_FLASHYELLOW, ItemType.SIGNALHEAD, Bundle.getMessage("SignalHeadStateFlashingYellow"), Bundle.getMessage("SignalHeadStateFlashingYellow")), // NOI18N
259        SIGNAL_HEAD_FLASHGREEN(TYPE_SIGNAL_HEAD_FLASHGREEN, ItemType.SIGNALHEAD, Bundle.getMessage("SignalHeadStateFlashingGreen"), Bundle.getMessage("SignalHeadStateFlashingGreen")), // NOI18N
260        SIGNAL_HEAD_LIT(TYPE_SIGNAL_HEAD_LIT, ItemType.SIGNALHEAD, Bundle.getMessage("SignalHeadStateLit"), Bundle.getMessage("SignalHeadStateLit")), // NOI18N
261        SIGNAL_HEAD_HELD(TYPE_SIGNAL_HEAD_HELD, ItemType.SIGNALHEAD, Bundle.getMessage("SignalHeadStateHeld"), Bundle.getMessage("SignalHeadStateHeld")), // NOI18N
262        SIGNAL_HEAD_LUNAR(TYPE_SIGNAL_HEAD_LUNAR, ItemType.SIGNALHEAD, Bundle.getMessage("SignalHeadStateLunar"), Bundle.getMessage("SignalHeadStateLunar")), // NOI18N
263        SIGNAL_HEAD_FLASHLUNAR(TYPE_SIGNAL_HEAD_FLASHLUNAR, ItemType.SIGNALHEAD, Bundle.getMessage("SignalHeadStateFlashingLunar"), Bundle.getMessage("SignalHeadStateFlashingLunar")), // NOI18N
264        // Warrant variables
265        ROUTE_FREE(TYPE_ROUTE_FREE, ItemType.WARRANT, rbx.getString("StateRouteFree"), rbx.getString("TypeWarrantRouteFree")), // NOI18N
266        ROUTE_OCCUPIED(TYPE_ROUTE_OCCUPIED, ItemType.WARRANT, rbx.getString("stateRouteOccupied"), rbx.getString("TypeWarrantRouteOccupied")), // NOI18N
267        ROUTE_ALLOCATED(TYPE_ROUTE_ALLOCATED, ItemType.WARRANT, rbx.getString("StateRouteReserved"), rbx.getString("TypeWarrantRouteAllocated")), // NOI18N
268        ROUTE_SET(TYPE_ROUTE_SET, ItemType.WARRANT, rbx.getString("StateRouteIsSet"), rbx.getString("TypeRouteIsSet")), // NOI18N
269        TRAIN_RUNNING(TYPE_TRAIN_RUNNING, ItemType.WARRANT, rbx.getString("StateTrainRunning"), rbx.getString("TypeTrainRunning")), // NOI18N
270        SIGNAL_MAST_ASPECT_EQUALS(TYPE_SIGNAL_MAST_ASPECT_EQUALS, ItemType.SIGNALMAST, rbx.getString("TypeSignalMastAspectEquals"), rbx.getString("TypeSignalMastAspectEquals")), // NOI18N
271        SIGNAL_MAST_LIT(TYPE_SIGNAL_MAST_LIT, ItemType.SIGNALMAST, Bundle.getMessage("SignalMastStateLit"), Bundle.getMessage("SignalMastStateLit")), // NOI18N
272        SIGNAL_MAST_HELD(TYPE_SIGNAL_MAST_HELD, ItemType.SIGNALMAST, Bundle.getMessage("SignalMastStateHeld"), Bundle.getMessage("SignalMastStateHeld")), // NOI18N
273        SIGNAL_HEAD_APPEARANCE_EQUALS(TYPE_SIGNAL_HEAD_APPEARANCE_EQUALS, ItemType.SIGNALHEAD, rbx.getString("TypeSignalHeadAspectEquals"), rbx.getString("TypeSignalHeadAspectEquals")), // NOI18N
274        BLOCK_STATUS_EQUALS(TYPE_BLOCK_STATUS_EQUALS, ItemType.OBLOCK, "", ""), // NOI18N
275        //Entry Exit Rules
276        ENTRYEXIT_ACTIVE(TYPE_ENTRYEXIT_ACTIVE, ItemType.ENTRYEXIT, rbx.getString("TypeEntryExitActive"), rbx.getString("TypeEntryExitActive")), // NOI18N
277        ENTRYEXIT_INACTIVE(TYPE_ENTRYEXIT_INACTIVE, ItemType.ENTRYEXIT, rbx.getString("TypeEntryExitInactive"), rbx.getString("TypeEntryExitInactive")), // NOI18N
278        // OBlock
279        OBLOCK_UNOCCUPIED(TYPE_OBLOCK_UNOCCUPIED, ItemType.OBLOCK, rbxWarrant.getString("unoccupied"), rbxWarrant.getString("unoccupied")), // NOI18N
280        OBLOCK_OCCUPIED(TYPE_OBLOCK_OCCUPIED, ItemType.OBLOCK, rbxWarrant.getString("occupied"), rbxWarrant.getString("occupied")), // NOI18N
281        OBLOCK_ALLOCATED(TYPE_OBLOCK_ALLOCATED, ItemType.OBLOCK, rbxWarrant.getString("allocated"), rbxWarrant.getString("allocated")), // NOI18N
282        OBLOCK_RUNNING(TYPE_OBLOCK_RUNNING, ItemType.OBLOCK, rbxWarrant.getString("running"), rbxWarrant.getString("running")), // NOI18N
283        OBLOCK_OUT_OF_SERVICE(TYPE_OBLOCK_OUT_OF_SERVICE, ItemType.OBLOCK, rbxWarrant.getString("outOfService"), rbxWarrant.getString("outOfService")), // NOI18N
284        OBLOCK_DARK(TYPE_OBLOCK_DARK, ItemType.OBLOCK, rbxWarrant.getString("dark"), rbxWarrant.getString("dark")), // NOI18N
285        OBLOCK_POWER_ERROR(TYPE_OBLOCK_POWER_ERROR, ItemType.OBLOCK, rbxWarrant.getString("powerError"), rbxWarrant.getString("powerError")), // NOI18N
286        // This is used by ConditionalListEdit and ConditionalTreeEdit
287        XXXXXXX(TYPE_XXXXXXX, ItemType.NONE, "XXXXXXX", "XXXXXXX"); // NOI18N
288
289        private final int _item;
290        private final ItemType _itemType;
291        private final String _string;
292        private final String _testTypeString;
293
294        private static final List<Type> sensorItemsList;
295        private static final List<Type> turnoutItemsList;
296        private static final List<Type> conditionalItemsList;
297        private static final List<Type> lightItemsList;
298        private static final List<Type> warrantItemsList;
299        private static final List<Type> memoryItemsList;
300        private static final List<Type> entryExitItemsList;
301        private static final List<Type> signalHeadStateMachineItemsList;
302        private static final List<Type> signalMastItemsList;
303        private static final List<Type> oblockItemsList;
304
305        private static final Set<Type> signalHeadAppearanceSet;
306
307
308        static
309        {
310            Type[] typeArray1 = {SENSOR_ACTIVE, SENSOR_INACTIVE};
311            sensorItemsList = Collections.unmodifiableList(Arrays.asList(typeArray1));
312
313            Type[] typeArray2 = {TURNOUT_THROWN, TURNOUT_CLOSED};
314            turnoutItemsList = Collections.unmodifiableList(Arrays.asList(typeArray2));
315
316            Type[] typeArray3 = {CONDITIONAL_TRUE, CONDITIONAL_FALSE};
317            conditionalItemsList = Collections.unmodifiableList(Arrays.asList(typeArray3));
318
319            Type[] typeArray4 = {LIGHT_ON, LIGHT_OFF};
320            lightItemsList = Collections.unmodifiableList(Arrays.asList(typeArray4));
321
322            Type[] typeArray5 = {ROUTE_FREE, ROUTE_SET, ROUTE_ALLOCATED, ROUTE_OCCUPIED, TRAIN_RUNNING};
323            warrantItemsList = Collections.unmodifiableList(Arrays.asList(typeArray5));
324
325            Type[] typeArray6 = {MEMORY_EQUALS, MEMORY_EQUALS_INSENSITIVE,
326                MEMORY_COMPARE, MEMORY_COMPARE_INSENSITIVE};
327            memoryItemsList = Collections.unmodifiableList(Arrays.asList(typeArray6));
328
329            Type[] typeArray7 = {ENTRYEXIT_ACTIVE, ENTRYEXIT_INACTIVE};
330            entryExitItemsList = Collections.unmodifiableList(Arrays.asList(typeArray7));
331
332            Type[] typeArray8 = {NONE, SIGNAL_HEAD_APPEARANCE_EQUALS, SIGNAL_HEAD_LIT, SIGNAL_HEAD_HELD};
333            signalHeadStateMachineItemsList = Collections.unmodifiableList(Arrays.asList(typeArray8));
334
335            Type[] typeArray9 = {SIGNAL_HEAD_RED, SIGNAL_HEAD_YELLOW, SIGNAL_HEAD_GREEN,
336                SIGNAL_HEAD_DARK, SIGNAL_HEAD_FLASHRED, SIGNAL_HEAD_FLASHYELLOW,
337                SIGNAL_HEAD_FLASHGREEN, SIGNAL_HEAD_LUNAR, SIGNAL_HEAD_FLASHLUNAR,
338            };
339            signalHeadAppearanceSet = Collections.unmodifiableSet(new HashSet<>(Arrays.asList(typeArray9)));
340
341            Type[] typeArray10 = {NONE, SIGNAL_MAST_ASPECT_EQUALS, SIGNAL_MAST_LIT, SIGNAL_MAST_HELD};
342            signalMastItemsList = Collections.unmodifiableList(Arrays.asList(typeArray10));
343
344            Type[] typeArray11 = {OBLOCK_UNOCCUPIED, OBLOCK_OCCUPIED, OBLOCK_ALLOCATED,
345                OBLOCK_RUNNING, OBLOCK_OUT_OF_SERVICE, OBLOCK_DARK, OBLOCK_POWER_ERROR};
346            oblockItemsList = Collections.unmodifiableList(Arrays.asList(typeArray11));
347        }
348
349        private Type(int state, ItemType itemType, String string, String testTypeString) {
350            _item = state;
351            _itemType = itemType;
352            _string = string;
353            _testTypeString = testTypeString;
354        }
355
356        public ItemType getItemType() {
357            return _itemType;
358        }
359
360        public int getIntValue() {
361            return _item;
362        }
363
364        public static List<Type> getSensorItems() {
365            return sensorItemsList;
366        }
367
368        public static List<Type> getTurnoutItems() {
369            return turnoutItemsList;
370        }
371
372        public static List<Type> getConditionalItems() {
373            return conditionalItemsList;
374        }
375
376        public static List<Type> getLightItems() {
377            return lightItemsList;
378        }
379
380        public static List<Type> getWarrantItems() {
381            return warrantItemsList;
382        }
383
384        public static List<Type> getMemoryItems() {
385            return memoryItemsList;
386        }
387
388        public static List<Type> getEntryExitItems() {
389            return entryExitItemsList;
390        }
391
392        public static List<Type> getSignalHeadStateMachineItems() {
393            return signalHeadStateMachineItemsList;
394        }
395
396        public static boolean isSignalHeadApperance(Type type) {
397            return signalHeadAppearanceSet.contains(type);
398        }
399
400        public static List<Type> getSignalMastItems() {
401            return signalMastItemsList;
402        }
403
404        public static List<Type> getOBlockItems() {
405            return oblockItemsList;
406        }
407
408        public static int getIndexInList(List<Type> table, Type entry) {
409            for (int i = 0; i < table.size(); i++) {
410                if (entry == table.get(i)) {
411                    return i;
412                }
413            }
414            return -1;
415        }
416
417        public static Type getOperatorFromIntValue(int typeInt) {
418            for (Type type : Type.values()) {
419                if (type.getIntValue() == typeInt) {
420                    return type;
421                }
422            }
423
424            throw new IllegalArgumentException("Type is unknown");
425        }
426
427        // Some items uses Bundle.getString() and some items uses rbx.getString()
428        // and therefore the items must call getString() in the call to the constructor.
429        @Override
430        public String toString() {
431            return _string;
432        }
433
434        public String getTestTypeString() {
435            return _testTypeString;
436        }
437    }
438
439    // items
440    enum Action {
441        NONE(ACTION_NONE, ItemType.NONE, ""), // NOI18N
442        SET_TURNOUT(ACTION_SET_TURNOUT, ItemType.TURNOUT, rbx.getString("ActionSetTurnout")), // NOI18N
443        // allowed settings for turnout are Thrown and Closed (in data)
444        SET_SIGNAL_APPEARANCE(ACTION_SET_SIGNAL_APPEARANCE, ItemType.SIGNALHEAD, rbx.getString("ActionSetSignal")), // NOI18N
445        // allowed settings for signal head are the seven Appearances (in data)
446        SET_SIGNAL_HELD(ACTION_SET_SIGNAL_HELD, ItemType.SIGNALHEAD, rbx.getString("ActionSetSignalHeld")), // NOI18N
447        CLEAR_SIGNAL_HELD(ACTION_CLEAR_SIGNAL_HELD, ItemType.SIGNALHEAD, rbx.getString("ActionClearSignalHeld")), // NOI18N
448        SET_SIGNAL_DARK(ACTION_SET_SIGNAL_DARK, ItemType.SIGNALHEAD, rbx.getString("ActionSetSignalDark")), // NOI18N
449        SET_SIGNAL_LIT(ACTION_SET_SIGNAL_LIT, ItemType.SIGNALHEAD, rbx.getString("ActionSetSignalLit")), // NOI18N
450        TRIGGER_ROUTE(ACTION_TRIGGER_ROUTE, ItemType.OTHER, rbx.getString("ActionTriggerRoute")), // NOI18N
451        SET_SENSOR(ACTION_SET_SENSOR, ItemType.SENSOR, rbx.getString("ActionSetSensor")), // NOI18N
452        // allowed settings for sensor are active and inactive (in data)
453        DELAYED_SENSOR(ACTION_DELAYED_SENSOR, ItemType.SENSOR, rbx.getString("ActionDelayedSensor")), // NOI18N
454        // allowed settings for timed sensor are active and inactive (in data)
455        //   time in seconds before setting sensor should be in delay
456        SET_LIGHT(ACTION_SET_LIGHT, ItemType.LIGHT, rbx.getString("ActionSetLight")), // NOI18N
457        // allowed settings for light are ON and OFF (in data)
458        SET_MEMORY(ACTION_SET_MEMORY, ItemType.MEMORY, rbx.getString("ActionSetMemory")), // NOI18N
459        // text to set into the memory variable should be in string
460        ENABLE_LOGIX(ACTION_ENABLE_LOGIX, ItemType.LOGIX, rbx.getString("ActionEnableLogix")), // NOI18N
461        DISABLE_LOGIX(ACTION_DISABLE_LOGIX, ItemType.LOGIX, rbx.getString("ActionDisableLogix")), // NOI18N
462        PLAY_SOUND(ACTION_PLAY_SOUND, ItemType.AUDIO, rbx.getString("ActionPlaySound")), // NOI18N
463        // reference to sound should be in string
464        RUN_SCRIPT(ACTION_RUN_SCRIPT, ItemType.SCRIPT, rbx.getString("ActionRunScript")), // NOI18N
465        // reference to script should be in string
466        DELAYED_TURNOUT(ACTION_DELAYED_TURNOUT, ItemType.TURNOUT, rbx.getString("ActionDelayedTurnout")), // NOI18N
467        // allowed settings for timed turnout are Thrown and Closed (in data)
468        //   time in seconds before setting turnout should be in delay
469        LOCK_TURNOUT(ACTION_LOCK_TURNOUT, ItemType.TURNOUT, rbx.getString("ActionTurnoutLock")), // NOI18N
470        RESET_DELAYED_SENSOR(ACTION_RESET_DELAYED_SENSOR, ItemType.SENSOR, rbx.getString("ActionResetDelayedSensor")), // NOI18N
471        // allowed settings for timed sensor are active and inactive (in data)
472        //   time in seconds before setting sensor should be in delay
473        CANCEL_SENSOR_TIMERS(ACTION_CANCEL_SENSOR_TIMERS, ItemType.SENSOR, rbx.getString("ActionCancelSensorTimers")), // NOI18N
474        // cancels all timers delaying setting of specified sensor
475        RESET_DELAYED_TURNOUT(ACTION_RESET_DELAYED_TURNOUT, ItemType.TURNOUT, rbx.getString("ActionResetDelayedTurnout")), // NOI18N
476        // allowed settings for timed sensor are active and inactive (in data)
477        //   time in seconds before setting sensor should be in delay
478        CANCEL_TURNOUT_TIMERS(ACTION_CANCEL_TURNOUT_TIMERS, ItemType.TURNOUT, rbx.getString("ActionCancelTurnoutTimers")), // NOI18N
479        // cancels all timers delaying setting of specified sensor
480        SET_FAST_CLOCK_TIME(ACTION_SET_FAST_CLOCK_TIME, ItemType.CLOCK, rbx.getString("ActionSetFastClockTime")), // NOI18N
481        // sets the fast clock time to the time specified
482        START_FAST_CLOCK(ACTION_START_FAST_CLOCK, ItemType.CLOCK, rbx.getString("ActionStartFastClock")), // NOI18N
483        // starts the fast clock
484        STOP_FAST_CLOCK(ACTION_STOP_FAST_CLOCK, ItemType.CLOCK, rbx.getString("ActionStopFastClock")), // NOI18N
485        // stops the fast clock
486        COPY_MEMORY(ACTION_COPY_MEMORY, ItemType.MEMORY, rbx.getString("ActionCopyMemory")), // NOI18N
487        // copies value from memory variable (in name) to memory variable (in string)
488        SET_LIGHT_INTENSITY(ACTION_SET_LIGHT_INTENSITY, ItemType.LIGHT, rbx.getString("ActionSetLightIntensity")), // NOI18N
489        SET_LIGHT_TRANSITION_TIME(ACTION_SET_LIGHT_TRANSITION_TIME, ItemType.LIGHT, rbx.getString("ActionSetLightTransitionTime")), // NOI18N
490        // control the specified audio object
491        CONTROL_AUDIO(ACTION_CONTROL_AUDIO, ItemType.AUDIO, rbx.getString("ActionControlAudio")), // NOI18N
492        // execute a jython command
493        JYTHON_COMMAND(ACTION_JYTHON_COMMAND, ItemType.SCRIPT, rbx.getString("ActionJythonCommand")), // NOI18N
494        // Warrant actions
495        ALLOCATE_WARRANT_ROUTE(ACTION_ALLOCATE_WARRANT_ROUTE, ItemType.WARRANT, rbx.getString("ActionAllocateWarrant")), // NOI18N
496        DEALLOCATE_WARRANT_ROUTE(ACTION_DEALLOCATE_WARRANT_ROUTE, ItemType.WARRANT, rbx.getString("ActionDeallocateWarrant")), // NOI18N
497        SET_ROUTE_TURNOUTS(ACTION_SET_ROUTE_TURNOUTS, ItemType.WARRANT, rbx.getString("ActionSetWarrantTurnouts")), // NOI18N
498        AUTO_RUN_WARRANT(ACTION_AUTO_RUN_WARRANT, ItemType.WARRANT, rbx.getString("ActionAutoRunWarrant")), // NOI18N
499        MANUAL_RUN_WARRANT(ACTION_MANUAL_RUN_WARRANT, ItemType.WARRANT, rbx.getString("ActionManualRunWarrant")), // NOI18N
500        CONTROL_TRAIN(ACTION_CONTROL_TRAIN, ItemType.WARRANT, rbx.getString("ActionControlTrain")), // NOI18N
501        SET_TRAIN_ID(ACTION_SET_TRAIN_ID, ItemType.WARRANT, rbx.getString("ActionSetTrainId")), // NOI18N
502        SET_TRAIN_NAME(ACTION_SET_TRAIN_NAME, ItemType.WARRANT, rbx.getString("ActionSetTrainName")), // NOI18N
503        SET_SIGNALMAST_ASPECT(ACTION_SET_SIGNALMAST_ASPECT, ItemType.SIGNALMAST, rbx.getString("ActionSetSignalMastAspect")), // NOI18N
504        GET_TRAIN_LOCATION(ACTION_GET_TRAIN_LOCATION, ItemType.WARRANT, rbx.getString("ActionSetTrainLocation")), // NOI18N
505        GET_BLOCK_WARRANT(ACTION_GET_BLOCK_WARRANT, ItemType.OBLOCK, rbx.getString("ActionGetBlockWarrant")), // NOI18N
506        GET_BLOCK_TRAIN_NAME(ACTION_GET_BLOCK_TRAIN_NAME, ItemType.OBLOCK, rbx.getString("ActionGetBlockTrainName")), // NOI18N
507        SET_SIGNALMAST_HELD(ACTION_SET_SIGNALMAST_HELD, ItemType.SIGNALMAST, rbx.getString("ActionSetSignalMastHeld")), // NOI18N
508        CLEAR_SIGNALMAST_HELD(ACTION_CLEAR_SIGNALMAST_HELD, ItemType.SIGNALMAST, rbx.getString("ActionClearSignalMastHeld")), // NOI18N
509        SET_SIGNALMAST_DARK(ACTION_SET_SIGNALMAST_DARK, ItemType.SIGNALMAST, rbx.getString("ActionSetSignalMastDark")), // NOI18N
510        SET_SIGNALMAST_LIT(ACTION_SET_SIGNALMAST_LIT, ItemType.SIGNALMAST, rbx.getString("ActionClearSignalMastDark")), // NOI18N
511        SET_BLOCK_VALUE(ACTION_SET_BLOCK_VALUE, ItemType.OBLOCK, rbx.getString("ActionSetBlockValue")), // NOI18N
512        SET_BLOCK_ERROR(ACTION_SET_BLOCK_ERROR, ItemType.OBLOCK, rbx.getString("ActionSetBlockError")), // NOI18N
513        CLEAR_BLOCK_ERROR(ACTION_CLEAR_BLOCK_ERROR, ItemType.OBLOCK, rbx.getString("ActionClearBlockError")), // NOI18N
514        DEALLOCATE_BLOCK(ACTION_DEALLOCATE_BLOCK, ItemType.OBLOCK, rbx.getString("ActionDeallocateBlock")), // NOI18N
515        SET_BLOCK_OUT_OF_SERVICE(ACTION_SET_BLOCK_OUT_OF_SERVICE, ItemType.OBLOCK, rbx.getString("ActionSetBlockOutOfService")), // NOI18N
516        SET_BLOCK_IN_SERVICE(ACTION_SET_BLOCK_IN_SERVICE, ItemType.OBLOCK, rbx.getString("ActionBlockInService")), // NOI18N
517        // EntryExit Actions
518        SET_NXPAIR_ENABLED(ACTION_SET_NXPAIR_ENABLED, ItemType.ENTRYEXIT, rbx.getString("ActionNXPairEnabled")), // NOI18N
519        SET_NXPAIR_DISABLED(ACTION_SET_NXPAIR_DISABLED, ItemType.ENTRYEXIT, rbx.getString("ActionNXPairDisabled")), // NOI18N
520        SET_NXPAIR_SEGMENT(ACTION_SET_NXPAIR_SEGMENT, ItemType.ENTRYEXIT, rbx.getString("ActionNXPairSegment")); // NOI18N
521
522
523        private final int _item;
524        private final ItemType _itemType;
525        private final String _string;
526
527        private static final List<Action> sensorItemsList;
528        private static final List<Action> turnoutItemsList;
529        private static final List<Action> lightItemsList;
530        private static final List<Action> warrantItemsList;
531        private static final List<Action> memoryItemsList;
532        private static final List<Action> oblockItemsList;
533        private static final List<Action> entryExitItemsList;
534        private static final List<Action> signalHeadItemsList;
535        private static final List<Action> signalMastItemsList;
536        private static final List<Action> clockItemsList;
537        private static final List<Action> logixItemsList;
538        private static final List<Action> audioItemsList;
539        private static final List<Action> scriptItemsList;
540        private static final List<Action> otherItemsList;
541
542
543        static
544        {
545            Action[] typeArray1 = {SET_SENSOR, DELAYED_SENSOR,
546                RESET_DELAYED_SENSOR, CANCEL_SENSOR_TIMERS};
547            sensorItemsList = Collections.unmodifiableList(Arrays.asList(typeArray1));
548
549            Action[] typeArray2 = {SET_TURNOUT, DELAYED_TURNOUT, LOCK_TURNOUT,
550                CANCEL_TURNOUT_TIMERS, RESET_DELAYED_TURNOUT};
551            turnoutItemsList = Collections.unmodifiableList(Arrays.asList(typeArray2));
552
553            Action[] typeArray3 = {SET_LIGHT, SET_LIGHT_INTENSITY,
554                SET_LIGHT_TRANSITION_TIME};
555            lightItemsList = Collections.unmodifiableList(Arrays.asList(typeArray3));
556
557            Action[] typeArray4 = {ALLOCATE_WARRANT_ROUTE, DEALLOCATE_WARRANT_ROUTE,
558                SET_ROUTE_TURNOUTS, AUTO_RUN_WARRANT, MANUAL_RUN_WARRANT, CONTROL_TRAIN,
559                SET_TRAIN_ID, SET_TRAIN_NAME, GET_TRAIN_LOCATION};
560            warrantItemsList = Collections.unmodifiableList(Arrays.asList(typeArray4));
561
562            Action[] typeArray5 = {SET_MEMORY, COPY_MEMORY};
563            memoryItemsList = Collections.unmodifiableList(Arrays.asList(typeArray5));
564
565            Action[] typeArray6 = {SET_NXPAIR_ENABLED, SET_NXPAIR_DISABLED,
566                SET_NXPAIR_SEGMENT};
567            entryExitItemsList = Collections.unmodifiableList(Arrays.asList(typeArray6));
568
569            Action[] typeArray7 = {SET_SIGNAL_APPEARANCE, SET_SIGNAL_HELD,
570                CLEAR_SIGNAL_HELD, SET_SIGNAL_DARK, SET_SIGNAL_LIT};
571            signalHeadItemsList = Collections.unmodifiableList(Arrays.asList(typeArray7));
572
573            Action[] typeArray8 = {SET_SIGNALMAST_ASPECT, SET_SIGNALMAST_HELD,
574                CLEAR_SIGNALMAST_HELD, SET_SIGNALMAST_DARK, SET_SIGNALMAST_LIT};
575            signalMastItemsList = Collections.unmodifiableList(Arrays.asList(typeArray8));
576
577            Action[] typeArray9 = {SET_FAST_CLOCK_TIME, START_FAST_CLOCK,
578                STOP_FAST_CLOCK};
579            clockItemsList = Collections.unmodifiableList(Arrays.asList(typeArray9));
580
581            Action[] typeArray10 = {ENABLE_LOGIX, DISABLE_LOGIX};
582            logixItemsList = Collections.unmodifiableList(Arrays.asList(typeArray10));
583
584            Action[] typeArray11 = {DEALLOCATE_BLOCK, SET_BLOCK_VALUE,
585                SET_BLOCK_ERROR, CLEAR_BLOCK_ERROR, SET_BLOCK_OUT_OF_SERVICE,
586                SET_BLOCK_IN_SERVICE, GET_BLOCK_TRAIN_NAME, GET_BLOCK_WARRANT};
587            oblockItemsList = Collections.unmodifiableList(Arrays.asList(typeArray11));
588
589            Action[] typeArray12 = {PLAY_SOUND, CONTROL_AUDIO};
590            audioItemsList = Collections.unmodifiableList(Arrays.asList(typeArray12));
591
592            Action[] typeArray13 = {RUN_SCRIPT, JYTHON_COMMAND};
593            scriptItemsList = Collections.unmodifiableList(Arrays.asList(typeArray13));
594
595            Action[] typeArray14 = {TRIGGER_ROUTE};
596            otherItemsList = Collections.unmodifiableList(Arrays.asList(typeArray14));
597        }
598
599        private Action(int state, ItemType itemType, String string) {
600            _item = state;
601            _itemType = itemType;
602            _string = string;
603        }
604
605        public ItemType getItemType() {
606            return _itemType;
607        }
608
609        public int getIntValue() {
610            return _item;
611        }
612
613        public static List<Action> getSensorItems() {
614            return sensorItemsList;
615        }
616
617        public static List<Action> getTurnoutItems() {
618            return turnoutItemsList;
619        }
620
621        public static List<Action> getLightItems() {
622            return lightItemsList;
623        }
624
625        public static List<Action> getWarrantItems() {
626            return warrantItemsList;
627        }
628
629        public static List<Action> getMemoryItems() {
630            return memoryItemsList;
631        }
632
633        public static List<Action> getOBlockItems() {
634            return oblockItemsList;
635        }
636
637        public static List<Action> getEntryExitItems() {
638            return entryExitItemsList;
639        }
640
641        public static List<Action> getSignalHeadItems() {
642            return signalHeadItemsList;
643        }
644
645        public static List<Action> getSignalMastItems() {
646            return signalMastItemsList;
647        }
648
649        public static List<Action> getClockItems() {
650            return clockItemsList;
651        }
652
653        public static List<Action> getLogixItems() {
654            return logixItemsList;
655        }
656
657        public static List<Action> getAudioItems() {
658            return audioItemsList;
659        }
660
661        public static List<Action> getScriptItems() {
662            return scriptItemsList;
663        }
664
665        public static List<Action> getOtherItems() {
666            return otherItemsList;
667        }
668
669        public static Action getOperatorFromIntValue(int actionInt) {
670            for (Action action : Action.values()) {
671                if (action.getIntValue() == actionInt) {
672                    return action;
673                }
674            }
675
676            throw new IllegalArgumentException("Action is unknown");
677        }
678
679        // Some items uses Bundle.getString() and some items uses rbx.getString()
680        // and therefore the items must call getString() in the call to the constructor.
681        @Override
682        public String toString() {
683            return _string;
684        }
685
686    }
687
688    // state variable types
689    static final int TYPE_ERROR = -1;
690    static final int TYPE_NONE = 0;
691    static final int TYPE_SENSOR_ACTIVE = 1;
692    static final int TYPE_SENSOR_INACTIVE = 2;
693    static final int TYPE_TURNOUT_THROWN = 3;
694    static final int TYPE_TURNOUT_CLOSED = 4;
695    static final int TYPE_CONDITIONAL_TRUE = 5;
696    static final int TYPE_CONDITIONAL_FALSE = 6;
697    static final int TYPE_LIGHT_ON = 7;
698    static final int TYPE_LIGHT_OFF = 8;
699    static final int TYPE_MEMORY_EQUALS = 9;
700    static final int TYPE_FAST_CLOCK_RANGE = 10;
701    // Note - within the TYPE_SIGNAL_HEAD definitions, all must be together,
702    //  RED must be first, and HELD must be last
703    static final int TYPE_SIGNAL_HEAD_RED = 11;
704    static final int TYPE_SIGNAL_HEAD_YELLOW = 12;
705    static final int TYPE_SIGNAL_HEAD_GREEN = 13;
706    static final int TYPE_SIGNAL_HEAD_DARK = 14;
707    static final int TYPE_SIGNAL_HEAD_FLASHRED = 15;
708    static final int TYPE_SIGNAL_HEAD_FLASHYELLOW = 16;
709    static final int TYPE_SIGNAL_HEAD_FLASHGREEN = 17;
710    static final int TYPE_SIGNAL_HEAD_LIT = 18;
711    static final int TYPE_SIGNAL_HEAD_HELD = 19;
712    static final int TYPE_MEMORY_COMPARE = 20;
713    static final int TYPE_SIGNAL_HEAD_LUNAR = 21;
714    static final int TYPE_SIGNAL_HEAD_FLASHLUNAR = 22;
715    static final int TYPE_MEMORY_EQUALS_INSENSITIVE = 23;
716    static final int TYPE_MEMORY_COMPARE_INSENSITIVE = 24;
717    // Warrant variables
718    static final int TYPE_ROUTE_FREE = 25;
719    static final int TYPE_ROUTE_OCCUPIED = 26;
720    static final int TYPE_ROUTE_ALLOCATED = 27;
721    static final int TYPE_ROUTE_SET = 28;
722    static final int TYPE_TRAIN_RUNNING = 29;
723    static final int TYPE_SIGNAL_MAST_ASPECT_EQUALS = 30;
724    static final int TYPE_SIGNAL_MAST_LIT = 31;
725    static final int TYPE_SIGNAL_MAST_HELD = 32;
726    static final int TYPE_SIGNAL_HEAD_APPEARANCE_EQUALS = 33;
727
728    static final int TYPE_BLOCK_STATUS_EQUALS = 34;
729
730    //Entry Exit Rules
731    static final int TYPE_ENTRYEXIT_ACTIVE = 35;
732    static final int TYPE_ENTRYEXIT_INACTIVE = 36;
733
734    static final int TYPE_OBLOCK_UNOCCUPIED = 37;
735    static final int TYPE_OBLOCK_OCCUPIED = 38;
736    static final int TYPE_OBLOCK_ALLOCATED = 39;
737    static final int TYPE_OBLOCK_RUNNING = 40;
738    static final int TYPE_OBLOCK_OUT_OF_SERVICE = 41;
739    static final int TYPE_OBLOCK_DARK = 42;
740    static final int TYPE_OBLOCK_POWER_ERROR = 43;
741
742    static final int TYPE_XXXXXXX = 9999;
743
744    // action definitions
745    static final int ACTION_OPTION_ON_CHANGE_TO_TRUE = 1;
746    static final int ACTION_OPTION_ON_CHANGE_TO_FALSE = 2;
747    static final int ACTION_OPTION_ON_CHANGE = 3;
748    static final int NUM_ACTION_OPTIONS = 3;
749
750    // action types
751    static final int ACTION_NONE = 1;
752    static final int ACTION_SET_TURNOUT = 2;
753    // allowed settings for turnout are Thrown and Closed (in data)
754    static final int ACTION_SET_SIGNAL_APPEARANCE = 3;
755    // allowed settings for signal head are the seven Appearances (in data)
756    static final int ACTION_SET_SIGNAL_HELD = 4;
757    static final int ACTION_CLEAR_SIGNAL_HELD = 5;
758    static final int ACTION_SET_SIGNAL_DARK = 6;
759    static final int ACTION_SET_SIGNAL_LIT = 7;
760    static final int ACTION_TRIGGER_ROUTE = 8;
761    static final int ACTION_SET_SENSOR = 9;
762    // allowed settings for sensor are active and inactive (in data)
763    static final int ACTION_DELAYED_SENSOR = 10;
764    // allowed settings for timed sensor are active and inactive (in data)
765    //   time in seconds before setting sensor should be in delay
766    static final int ACTION_SET_LIGHT = 11;
767    // allowed settings for light are ON and OFF (in data)
768    static final int ACTION_SET_MEMORY = 12;
769    // text to set into the memory variable should be in string
770    static final int ACTION_ENABLE_LOGIX = 13;
771    static final int ACTION_DISABLE_LOGIX = 14;
772    static final int ACTION_PLAY_SOUND = 15;
773    // reference to sound should be in string
774    static final int ACTION_RUN_SCRIPT = 16;
775    // reference to script should be in string
776    static final int ACTION_DELAYED_TURNOUT = 17;
777    // allowed settings for timed turnout are Thrown and Closed (in data)
778    //   time in seconds before setting turnout should be in delay
779    static final int ACTION_LOCK_TURNOUT = 18;
780    static final int ACTION_RESET_DELAYED_SENSOR = 19;
781    // allowed settings for timed sensor are active and inactive (in data)
782    //   time in seconds before setting sensor should be in delay
783    static final int ACTION_CANCEL_SENSOR_TIMERS = 20;
784    // cancels all timers delaying setting of specified sensor
785    static final int ACTION_RESET_DELAYED_TURNOUT = 21;
786    // allowed settings for timed sensor are active and inactive (in data)
787    //   time in seconds before setting sensor should be in delay
788    static final int ACTION_CANCEL_TURNOUT_TIMERS = 22;
789    // cancels all timers delaying setting of specified sensor
790    static final int ACTION_SET_FAST_CLOCK_TIME = 23;
791    // sets the fast clock time to the time specified
792    static final int ACTION_START_FAST_CLOCK = 24;
793    // starts the fast clock
794    static final int ACTION_STOP_FAST_CLOCK = 25;
795    // stops the fast clock
796    static final int ACTION_COPY_MEMORY = 26;
797    // copies value from memory variable (in name) to memory variable (in string)
798    static final int ACTION_SET_LIGHT_INTENSITY = 27;
799    static final int ACTION_SET_LIGHT_TRANSITION_TIME = 28;
800    // control the specified audio object
801    static final int ACTION_CONTROL_AUDIO = 29;
802    // execute a jython command
803    static final int ACTION_JYTHON_COMMAND = 30;
804    // Warrant actions
805    static final int ACTION_ALLOCATE_WARRANT_ROUTE = 31;
806    static final int ACTION_DEALLOCATE_WARRANT_ROUTE = 32;
807    static final int ACTION_SET_ROUTE_TURNOUTS = 33;
808    static final int ACTION_AUTO_RUN_WARRANT = 34;
809    static final int ACTION_CONTROL_TRAIN = 35;
810    static final int ACTION_SET_TRAIN_ID = 36;
811    static final int ACTION_SET_SIGNALMAST_ASPECT = 37;
812    static final int ACTION_GET_TRAIN_LOCATION = 38;
813    static final int ACTION_SET_SIGNALMAST_HELD = 39;
814    static final int ACTION_CLEAR_SIGNALMAST_HELD = 40;
815    static final int ACTION_SET_SIGNALMAST_DARK = 41;
816    static final int ACTION_SET_SIGNALMAST_LIT = 42;
817    static final int ACTION_SET_BLOCK_ERROR = 43;
818    static final int ACTION_CLEAR_BLOCK_ERROR = 44;
819    static final int ACTION_DEALLOCATE_BLOCK = 45;
820    static final int ACTION_SET_BLOCK_OUT_OF_SERVICE = 46;
821    static final int ACTION_SET_BLOCK_IN_SERVICE = 47;
822    static final int ACTION_MANUAL_RUN_WARRANT = 48;
823    static final int ACTION_SET_TRAIN_NAME = 49;
824    static final int ACTION_SET_BLOCK_VALUE = 50;
825    // EntryExit Actions
826    static final int ACTION_SET_NXPAIR_ENABLED = 51;
827    static final int ACTION_SET_NXPAIR_DISABLED = 52;
828    static final int ACTION_SET_NXPAIR_SEGMENT = 53;
829
830    static final int ACTION_GET_BLOCK_WARRANT = 54;
831    static final int ACTION_GET_BLOCK_TRAIN_NAME = 55;
832
833    /**
834     * ***********************************************************************************
835     */
836    /* New Variable and Action type scheme for Logix UI
837     * State Variables and actions are grouped according to type.  Variable and action
838     * types share the following group categories:
839     */
840    // state variable and action items used by logix.
841    static final int ITEM_TYPE_SENSOR = 1;
842    static final int ITEM_TYPE_TURNOUT = 2;
843    static final int ITEM_TYPE_LIGHT = 3;
844    static final int ITEM_TYPE_SIGNALHEAD = 4;
845    static final int ITEM_TYPE_SIGNALMAST = 5;
846    static final int ITEM_TYPE_MEMORY = 6;
847    static final int ITEM_TYPE_CONDITIONAL = 7;  // used only by ConditionalVariable
848    static final int ITEM_TYPE_LOGIX = 7;        // used only by ConditionalAction
849    static final int ITEM_TYPE_WARRANT = 8;
850    static final int ITEM_TYPE_CLOCK = 9;
851    static final int ITEM_TYPE_OBLOCK = 10;
852    static final int ITEM_TYPE_ENTRYEXIT = 11;
853
854    static final int ITEM_TYPE_AUDIO = 12;
855    static final int ITEM_TYPE_SCRIPT = 13;
856    static final int ITEM_TYPE_OTHER = 14;
857
858    /**
859     * set the logic type (all AND's all OR's or mixed AND's and OR's set the
860     * antecedent expression - should be a well formed boolean statement with
861     * parenthesis indicating the order of evaluation
862     *
863     * @param type       the type
864     * @param antecedent the expression
865     */
866    public void setLogicType(Conditional.AntecedentOperator type, String antecedent);
867
868    /**
869     * Get antecedent (boolean expression) of Conditional
870     *
871     * @return the expression
872     */
873    public String getAntecedentExpression();
874
875    /**
876     * Get type of operators in the antecedent statement
877     *
878     * @return the type
879     */
880    public Conditional.AntecedentOperator getLogicType();
881
882    /**
883     * @return true if action list is executed only when state changes, false if
884     *         action list is executed on every calculation of state
885     */
886    public boolean getTriggerOnChange();
887
888    /**
889     * Set policy for execution of action list
890     *
891     * @param trigger true execute only on change of state
892     */
893    public void setTriggerOnChange(boolean trigger);
894
895    /**
896     * Set list of actions
897     *
898     * @param arrayList the actions
899     */
900    public void setAction(List<ConditionalAction> arrayList);
901
902    /**
903     * Make deep clone of actions.
904     *
905     * @return a list of copies of actions
906     */
907    @Nonnull
908    public List<ConditionalAction> getCopyOfActions();
909
910    /**
911     * Set State Variables for this Conditional. Each state variable will
912     * evaluate either True or False when this Conditional is calculated.
913     * <p>
914     * This method assumes that all information has been validated.
915     *
916     * @param arrayList the list of variables
917     */
918    public void setStateVariables(List<ConditionalVariable> arrayList);
919
920    /**
921     * Make deep clone of variables.
922     *
923     * @return a list containing copies of variables
924     */
925    @Nonnull
926    public List<ConditionalVariable> getCopyOfStateVariables();
927
928    /**
929     * Calculate this Conditional, triggering either or both actions if the user
930     * specified conditions are met, and the Logix is enabled. Sets the state of
931     * the conditional. Returns the calculated state of this Conditional.
932     *
933     * @param enabled true if Logix should be enabled; false otherwise
934     * @param evt     event to trigger if true
935     * @return the new state
936     */
937    public int calculate(boolean enabled, PropertyChangeEvent evt);
938
939    /**
940     * Check that an antecedent is well formed. If not, returns an error
941     * message. Otherwise returns null.
942     *
943     * @param ant          the expression
944     * @param variableList list of variables
945     * @return true if well formed; false otherwise
946     */
947    public String validateAntecedent(String ant, List<ConditionalVariable> variableList);
948
949    /**
950     * Stop a sensor timer if one is actively delaying setting of the specified
951     * sensor
952     *
953     * @param sname the name of the timer
954     */
955    public void cancelSensorTimer(String sname);
956
957    /**
958     * Stop a turnout timer if one is actively delaying setting of the specified
959     * turnout
960     *
961     * @param sname the name of the timer
962     */
963    public void cancelTurnoutTimer(String sname);
964
965    /**
966     * State of the Conditional is returned.
967     *
968     * @return state value
969     */
970    @Override
971    public int getState();
972
973    /**
974     * Request a call-back when the bound KnownState property changes.
975     *
976     * @param l the listener
977     */
978    @Override
979    public void addPropertyChangeListener(PropertyChangeListener l);
980
981    /**
982     * Remove a request for a call-back when a bound property changes.
983     *
984     * @param l the listener
985     */
986    @Override
987    public void removePropertyChangeListener(PropertyChangeListener l);
988
989    /**
990     * Remove references to and from this object, so that it can eventually be
991     * garbage-collected.
992     */
993    @Override
994    public void dispose();  // remove _all_ connections!
995
996}