001package jmri.jmrix.jmriclient;
002
003import jmri.Light;
004import jmri.implementation.AbstractLight;
005import org.slf4j.Logger;
006import org.slf4j.LoggerFactory;
007
008/**
009 * JMRIClient implementation of the Light interface.
010 *
011 * @author Bob Jacobsen Copyright (C) 2001, 2008
012 * @author Paul Bender Copyright (C) 2010
013 */
014public class JMRIClientLight extends AbstractLight implements JMRIClientListener {
015
016    // data members
017    private int _number;   // light number
018    private JMRIClientTrafficController tc = null;
019    private String transmitName = null;
020
021    /**
022     * JMRIClient lights use the light number on the remote host.
023     * @param number light number.
024     * @param memo system connection.
025     */
026    public JMRIClientLight(int number, JMRIClientSystemConnectionMemo memo) {
027        super(memo.getSystemPrefix() + "l" + number);
028        _number = number;
029        transmitName = memo.getTransmitPrefix() + "L" + number;
030        tc = memo.getJMRIClientTrafficController();
031        // At construction, register for messages
032        tc.addJMRIClientListener(this);
033        // then request status
034        requestUpdateFromLayout();
035    }
036
037    public int getNumber() {
038        return _number;
039    }
040
041    //request a status update from the layout
042    @Override
043    public void requestUpdateFromLayout() {
044        // create the message
045        String text = "LIGHT " + transmitName + "\n";
046        // create and send the message
047        tc.sendJMRIClientMessage(new JMRIClientMessage(text), this);
048    }
049
050    // Handle a request to change state by sending a formatted packet
051    // to the server.
052    @Override
053    public synchronized void doNewState(int oldState, int s) {
054        if (oldState == s) {
055            return; //no change, just quit.
056        }  // sort out states
057        if ((s & Light.ON) != 0) {
058            // first look for the double case, which we can't handle
059            if ((s & Light.OFF) != 0) {
060                // this is the disaster case!
061                log.error("Cannot command both ON and OFF {}", s);
062                return;
063            } else {
064                // send a ON command
065                sendMessage(true);
066            }
067        } else {
068            // send a OFF command
069            sendMessage(false);
070        }
071
072        notifyStateChange(oldState, s);
073
074    }
075
076    protected void sendMessage(boolean on) {
077        // get the message text
078        String text;
079        if (on) {
080            text = "LIGHT " + transmitName + " ON\n";
081        } else // thrown
082        {
083            text = "LIGHT " + transmitName + " OFF\n";
084        }
085
086        // create and send the message itself
087        tc.sendJMRIClientMessage(new JMRIClientMessage(text), this);
088    }
089
090    // to listen for status changes from JMRIClient system
091    @Override
092    public synchronized void reply(JMRIClientReply m) {
093        String message = m.toString();
094        if (!message.contains(transmitName + " ")) {
095            return; // not for us
096        }
097        if (m.toString().contains("OFF")) {
098            notifyStateChange(mState, jmri.Light.OFF);
099        } else if (m.toString().contains("ON")) {
100            notifyStateChange(mState, jmri.Light.ON);
101        } else {
102            notifyStateChange(mState, jmri.Light.UNKNOWN);
103        }
104    }
105
106    @Override
107    public void message(JMRIClientMessage m) {
108    }
109
110    private final static Logger log = LoggerFactory.getLogger(JMRIClientLight.class);
111
112}
113
114
115