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