001package jmri.jmrit.logixng.expressions;
002
003import java.beans.PropertyChangeEvent;
004import java.beans.PropertyChangeListener;
005import java.beans.VetoableChangeListener;
006import java.util.Locale;
007import java.util.Map;
008import jmri.*;
009import jmri.jmrit.logixng.*;
010import jmri.jmrit.logixng.util.ReferenceUtil;
011
012/**
013 * Evaluates what a reference points to.
014 * 
015 * @author Daniel Bergqvist Copyright 2018
016 */
017public class ExpressionReference extends AbstractDigitalExpression
018        implements PropertyChangeListener {
019//        implements PropertyChangeListener, VetoableChangeListener {
020
021    private String _reference;
022    private Is_IsNot_Enum _is_IsNot = Is_IsNot_Enum.Is;
023    private PointsTo _pointsTo = PointsTo.Nothing;
024
025    public ExpressionReference(String sys, String user)
026            throws BadUserNameException, BadSystemNameException {
027        super(sys, user);
028    }
029    
030    @Override
031    public Base getDeepCopy(Map<String, String> systemNames, Map<String, String> userNames) throws JmriException {
032        DigitalExpressionManager manager = InstanceManager.getDefault(DigitalExpressionManager.class);
033        String sysName = systemNames.get(getSystemName());
034        String userName = userNames.get(getSystemName());
035        if (sysName == null) sysName = manager.getAutoSystemName();
036        ExpressionReference copy = new ExpressionReference(sysName, userName);
037        copy.setComment(getComment());
038        copy.setReference(_reference);
039        copy.set_Is_IsNot(_is_IsNot);
040        copy.setPointsTo(_pointsTo);
041        return manager.registerExpression(copy).deepCopyChildren(this, systemNames, userNames);
042    }
043    
044    public void setReference(String reference) {
045        assertListenersAreNotRegistered(log, "setReference");
046        _reference = reference;
047    }
048    
049    public String getReference() {
050        return _reference;
051    }
052    
053    public void set_Is_IsNot(Is_IsNot_Enum is_IsNot) {
054        _is_IsNot = is_IsNot;
055    }
056    
057    public Is_IsNot_Enum get_Is_IsNot() {
058        return _is_IsNot;
059    }
060    
061    public void setPointsTo(PointsTo pointsTo) {
062        _pointsTo = pointsTo;
063    }
064    
065    public PointsTo getPointsTo() {
066        return _pointsTo;
067    }
068/*
069    @Override
070    public void vetoableChange(java.beans.PropertyChangeEvent evt) throws java.beans.PropertyVetoException {
071        if ("CanDelete".equals(evt.getPropertyName())) { // No I18N
072            if (evt.getOldValue() instanceof String) {
073                if (evt.getOldValue().equals(getReference().getBean())) {
074                    throw new PropertyVetoException(getDisplayName(), evt);
075                }
076            }
077        } else if ("DoDelete".equals(evt.getPropertyName())) { // No I18N
078            if (evt.getOldValue() instanceof String) {
079                if (evt.getOldValue().equals(getReference().getBean())) {
080                    setReference((Turnout)null);
081                }
082            }
083        }
084    }
085*/    
086    /** {@inheritDoc} */
087    @Override
088    public Category getCategory() {
089        return Category.ITEM;
090    }
091
092    /** {@inheritDoc} */
093    @Override
094    public boolean evaluate() {
095        if (_reference == null) return false;
096        
097        boolean result;
098        String ref = ReferenceUtil.getReference(
099                getConditionalNG().getSymbolTable(), _reference);
100        NamedBean t;
101
102        switch (_pointsTo) {
103            case Nothing:
104                result = "".equals(ref);
105                break;
106            
107            case LogixNGTable:
108                t = InstanceManager.getDefault(NamedTableManager.class).getNamedBean(ref);
109                result = (t != null);
110                break;
111            
112            case Audio:
113                t = InstanceManager.getDefault(AudioManager.class).getNamedBean(ref);
114                result = (t != null);
115                break;
116            
117            case Light:
118                t = InstanceManager.getDefault(LightManager.class).getNamedBean(ref);
119                result = (t != null);
120                break;
121            
122            case Memory:
123                t = InstanceManager.getDefault(MemoryManager.class).getNamedBean(ref);
124                result = (t != null);
125                break;
126            
127            case Sensor:
128                t = InstanceManager.getDefault(SensorManager.class).getNamedBean(ref);
129                result = (t != null);
130                break;
131            
132            case SignalHead:
133                t = InstanceManager.getDefault(SignalHeadManager.class).getNamedBean(ref);
134                result = (t != null);
135                break;
136            
137            case SignalMast:
138                t = InstanceManager.getDefault(SignalMastManager.class).getNamedBean(ref);
139                result = (t != null);
140                break;
141            
142            case Turnout:
143                t = InstanceManager.getDefault(TurnoutManager.class).getNamedBean(ref);
144                result = (t != null);
145                break;
146            
147            default:
148                throw new UnsupportedOperationException("_pointsTo has unknown value: "+_pointsTo.name());
149        }
150        
151        if (_is_IsNot == Is_IsNot_Enum.Is) {
152            return result;
153        } else {
154            return !result;
155        }
156    }
157
158    @Override
159    public FemaleSocket getChild(int index) throws IllegalArgumentException, UnsupportedOperationException {
160        throw new UnsupportedOperationException("Not supported.");
161    }
162
163    @Override
164    public int getChildCount() {
165        return 0;
166    }
167
168    @Override
169    public String getShortDescription(Locale locale) {
170        return Bundle.getMessage(locale, "Reference_Short");
171    }
172
173    @Override
174    public String getLongDescription(Locale locale) {
175        String reference;
176        if (_reference != null) {
177            reference = _reference;
178        } else {
179            reference = Bundle.getMessage(locale, "ReferenceNotSelected");
180        }
181        
182        return Bundle.getMessage(
183                locale,
184                "Reference_Long",
185                reference.isEmpty() ? "''" : reference,
186                _is_IsNot.toString(),
187                _pointsTo._text);
188    }
189    
190    /** {@inheritDoc} */
191    @Override
192    public void setup() {
193        // Do nothing
194    }
195    
196    /** {@inheritDoc} */
197    @Override
198    public void registerListenersForThisClass() {
199        if (!_listenersAreRegistered && (_reference != null)) {
200//            _reference.getBean().addPropertyChangeListener("KnownState", this);
201            _listenersAreRegistered = true;
202        }
203    }
204    
205    /** {@inheritDoc} */
206    @Override
207    public void unregisterListenersForThisClass() {
208        if (_listenersAreRegistered) {
209//            _reference.getBean().removePropertyChangeListener("KnownState", this);
210            _listenersAreRegistered = false;
211        }
212    }
213    
214    /** {@inheritDoc} */
215    @Override
216    public void propertyChange(PropertyChangeEvent evt) {
217        getConditionalNG().execute();
218    }
219    
220    /** {@inheritDoc} */
221    @Override
222    public void disposeMe() {
223    }
224    
225    
226    
227    public enum PointsTo {
228        Nothing(Bundle.getMessage("ReferencePointsTo_Nothing")),
229        Audio(Bundle.getMessage("ReferencePointsTo_Audio")),
230        Light(Bundle.getMessage("ReferencePointsTo_Light")),
231        Memory(Bundle.getMessage("ReferencePointsTo_Memory")),
232        Sensor(Bundle.getMessage("ReferencePointsTo_Sensor")),
233        SignalHead(Bundle.getMessage("ReferencePointsTo_SignalHead")),
234        SignalMast(Bundle.getMessage("ReferencePointsTo_SignalMast")),
235        Turnout(Bundle.getMessage("ReferencePointsTo_Turnout")),
236        LogixNGTable(Bundle.getMessage("ReferencePointsTo_LogixNGTable"));
237        
238        private final String _text;
239        
240        private PointsTo(String text) {
241            this._text = text;
242        }
243        
244        @Override
245        public String toString() {
246            return _text;
247        }
248        
249    }
250    
251    
252    private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(ExpressionReference.class);
253    
254}