001package jmri.jmrix.acela;
002
003import jmri.implementation.AbstractLight;
004import org.slf4j.Logger;
005import org.slf4j.LoggerFactory;
006
007/**
008 * AcelaLight.java
009 * <p>
010 * Implementation of the Light Object for Acela
011 * <p>
012 * Based in part on SerialTurnout.java
013 *
014 * @author Dave Duchamp Copyright (C) 2004
015 *
016 * @author Bob Coleman Copyright (C) 2007, 2008 Based on CMRI serial example,
017 * modified to establish Acela support.
018 */
019public class AcelaLight extends AbstractLight {
020
021    AcelaSystemConnectionMemo _memo = null;
022
023    /**
024     * Create a Light object, with only system name.
025     * <p>
026     * 'systemName' was previously validated in AcelaLightManager
027     *
028     * @param systemName the system name for this Light
029     * @param memo       the memo for the system connection
030     */
031    public AcelaLight(String systemName, AcelaSystemConnectionMemo memo) {
032        super(systemName);
033        _memo = memo;
034        initializeLight(systemName);
035    }
036
037    /**
038     * Create a Light object, with both system and user names.
039     * <p>
040     * 'systemName' was previously validated in AcelaLightManager
041     *
042     * @param systemName the system name for this Light
043     * @param userName   the user name for this Light
044     * @param memo       the memo for the system connection
045     */
046    public AcelaLight(String systemName, String userName, AcelaSystemConnectionMemo memo) {
047        super(systemName, userName);
048        _memo = memo;
049        initializeLight(systemName);
050    }
051
052    /**
053     * Sets up system dependent instance variables and sets system independent
054     * instance variables to default values.
055     * <p>
056     * Note: most instance variables are in AbstractLight.java
057     */
058    private void initializeLight(String systemName) {
059        // Extract the Bit from the name
060        mBit = AcelaAddress.getBitFromSystemName(systemName, _memo.getSystemPrefix());
061        // Set initial state
062        AcelaNode mNode = AcelaAddress.getNodeFromSystemName(mSystemName, _memo);
063
064        if (mNode != null) {
065            int initstate;
066            int initbit;
067            initbit = mBit - mNode.getStartingOutputAddress();
068            initstate = mNode.getOutputInit(initbit);
069            if (initstate == 1) {
070                setState(ON);
071            } else {
072                setState(OFF);
073            }
074        }
075    }
076
077    /**
078     * System dependent instance variables
079     */
080    int mBit = -1;                // global address from 0
081
082    /**
083     * Set the current state of this Light. This routine requests the hardware to
084     * change. If this is really a change in state of this bit (tested in
085     * AcelaNode), a Transmit packet will be sent before this Node is next
086     * polled.
087     */
088    @Override
089    public void setState(int newState) {
090        AcelaNode mNode = AcelaAddress.getNodeFromSystemName(mSystemName, _memo);
091
092        if (mNode != null) {
093            switch (newState) {
094                case ON:
095                    mNode.setOutputBit(mBit, true);
096                    break;
097                case OFF:
098                    mNode.setOutputBit(mBit, false);
099                    break;
100                default:
101                    log.warn("illegal state requested for Light: {}", getSystemName());
102                    break;
103            }
104        }
105
106        if (newState != mState) {
107            int oldState = mState;
108            mState = newState;
109
110            // notify listeners, if any
111            firePropertyChange("KnownState", oldState, newState);
112        }
113    }
114
115    private final static Logger log = LoggerFactory.getLogger(AcelaLight.class);
116
117}