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