001package jmri.jmrit.logixng.expressions;
002
003import java.beans.PropertyChangeEvent;
004import java.beans.PropertyChangeListener;
005import java.beans.PropertyVetoException;
006import java.beans.VetoableChangeListener;
007import java.util.*;
008
009import javax.annotation.Nonnull;
010
011import jmri.*;
012import jmri.jmrit.logixng.*;
013
014/**
015 * Reads a AnalogIO.
016 *
017 * @author Daniel Bergqvist Copyright 2021
018 */
019public class AnalogExpressionAnalogIO extends AbstractAnalogExpression
020        implements PropertyChangeListener, VetoableChangeListener {
021
022    private NamedBeanHandle<AnalogIO> _analogIOHandle;
023
024    public AnalogExpressionAnalogIO(String sys, String user)
025            throws BadUserNameException, BadSystemNameException {
026
027        super(sys, user);
028    }
029
030    @Override
031    public Base getDeepCopy(Map<String, String> systemNames, Map<String, String> userNames) throws JmriException {
032        AnalogExpressionManager manager = InstanceManager.getDefault(AnalogExpressionManager.class);
033        String sysName = systemNames.get(getSystemName());
034        String userName = userNames.get(getSystemName());
035        if (sysName == null) sysName = manager.getAutoSystemName();
036        AnalogExpressionAnalogIO copy = new AnalogExpressionAnalogIO(sysName, userName);
037        copy.setComment(getComment());
038        if (_analogIOHandle != null) copy.setAnalogIO(_analogIOHandle);
039        return manager.registerExpression(copy).deepCopyChildren(this, systemNames, userNames);
040    }
041
042    /** {@inheritDoc} */
043    @Override
044    public void vetoableChange(PropertyChangeEvent evt) throws PropertyVetoException {
045        if ("CanDelete".equals(evt.getPropertyName())) { // No I18N
046            if (evt.getOldValue() instanceof AnalogIO) {
047                if (evt.getOldValue().equals(getAnalogIO().getBean())) {
048                    PropertyChangeEvent e = new PropertyChangeEvent(this, "DoNotDelete", null, null);
049                    throw new PropertyVetoException(Bundle.getMessage("AnalogIO_AnalogIOInUseAnalogIOExpressionVeto", getDisplayName()), e); // NOI18N
050                }
051            }
052        } else if ("DoDelete".equals(evt.getPropertyName())) { // No I18N
053            if (evt.getOldValue() instanceof AnalogIO) {
054                if (evt.getOldValue().equals(getAnalogIO().getBean())) {
055                    removeAnalogIO();
056                }
057            }
058        }
059    }
060
061    /** {@inheritDoc} */
062    @Override
063    public Category getCategory() {
064        return Category.ITEM;
065    }
066
067    public void setAnalogIO(@Nonnull String analogIOName) {
068        assertListenersAreNotRegistered(log, "setAnalogIO");
069        AnalogIO analogIO = InstanceManager.getDefault(AnalogIOManager.class).getNamedBean(analogIOName);
070        if (analogIO != null) {
071            setAnalogIO(analogIO);
072        } else {
073            removeAnalogIO();
074            log.error("analogIO \"{}\" is not found", analogIOName);
075        }
076    }
077
078    public void setAnalogIO(@Nonnull NamedBeanHandle<AnalogIO> handle) {
079        assertListenersAreNotRegistered(log, "setAnalogIO");
080        _analogIOHandle = handle;
081        InstanceManager.getDefault(AnalogIOManager.class).addVetoableChangeListener(this);
082    }
083
084    public void setAnalogIO(@Nonnull AnalogIO analogIO) {
085        assertListenersAreNotRegistered(log, "setAnalogIO");
086        setAnalogIO(InstanceManager.getDefault(NamedBeanHandleManager.class)
087                .getNamedBeanHandle(analogIO.getDisplayName(), analogIO));
088    }
089
090    public void removeAnalogIO() {
091        assertListenersAreNotRegistered(log, "setAnalogIO");
092        if (_analogIOHandle != null) {
093            InstanceManager.getDefault(AnalogIOManager.class).removeVetoableChangeListener(this);
094            _analogIOHandle = null;
095        }
096    }
097
098    public NamedBeanHandle<AnalogIO> getAnalogIO() {
099        return _analogIOHandle;
100    }
101
102    /** {@inheritDoc} */
103    @Override
104    public double evaluate() {
105        if (_analogIOHandle != null) {
106            return jmri.util.TypeConversionUtil.convertToDouble(_analogIOHandle.getBean().getKnownAnalogValue(), false);
107        } else {
108            return 0.0;
109        }
110    }
111
112    /** {@inheritDoc} */
113    @Override
114    public FemaleSocket getChild(int index)
115            throws IllegalArgumentException, UnsupportedOperationException {
116        throw new UnsupportedOperationException("Not supported.");
117    }
118
119    /** {@inheritDoc} */
120    @Override
121    public int getChildCount() {
122        return 0;
123    }
124
125    /** {@inheritDoc} */
126    @Override
127    public String getShortDescription(Locale locale) {
128        return Bundle.getMessage(locale, "AnalogExpressionAnalogIO_Short");
129    }
130
131    /** {@inheritDoc} */
132    @Override
133    public String getLongDescription(Locale locale) {
134        if (_analogIOHandle != null) {
135            return Bundle.getMessage(locale, "AnalogExpressionAnalogIO_Long", _analogIOHandle.getBean().getDisplayName());
136        } else {
137            return Bundle.getMessage(locale, "AnalogExpressionAnalogIO_Long", "none");
138        }
139    }
140
141    /** {@inheritDoc} */
142    @Override
143    public void setup() {
144        // Do nothing
145    }
146
147    /** {@inheritDoc} */
148    @Override
149    public void registerListenersForThisClass() {
150        if ((! _listenersAreRegistered) && (_analogIOHandle != null)) {
151            _analogIOHandle.getBean().addPropertyChangeListener("value", this);
152            _listenersAreRegistered = true;
153        }
154    }
155
156    /** {@inheritDoc} */
157    @Override
158    public void unregisterListenersForThisClass() {
159        if (_listenersAreRegistered) {
160            _analogIOHandle.getBean().removePropertyChangeListener("value", this);
161            _listenersAreRegistered = false;
162        }
163    }
164
165    /** {@inheritDoc} */
166    @Override
167    public void propertyChange(PropertyChangeEvent evt) {
168        if (getTriggerOnChange()) {
169            getConditionalNG().execute();
170        }
171    }
172
173    /** {@inheritDoc} */
174    @Override
175    public void disposeMe() {
176    }
177
178    /** {@inheritDoc} */
179    @Override
180    public void getUsageDetail(int level, NamedBean bean, List<NamedBeanUsageReport> report, NamedBean cdl) {
181        log.debug("getUsageReport :: AnalogExpressionAnalogIO: bean = {}, report = {}", cdl, report);
182        if (getAnalogIO() != null && bean.equals(getAnalogIO().getBean())) {
183            report.add(new NamedBeanUsageReport("LogixNGExpression", cdl, getLongDescription()));
184        }
185    }
186
187    private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(AnalogExpressionAnalogIO.class);
188
189}