001package jmri.jmrix.sprog;
002
003import jmri.JmriException;
004import jmri.PowerManager;
005import jmri.jmrix.AbstractMessage;
006import jmri.managers.AbstractPowerManager;
007import org.slf4j.Logger;
008import org.slf4j.LoggerFactory;
009
010/**
011 * PowerManager implementation for controlling SPROG layout power.
012 *
013 * @author Bob Jacobsen Copyright (C) 2001
014 */
015public class SprogPowerManager extends AbstractPowerManager<SprogSystemConnectionMemo>
016        implements SprogListener {
017
018    boolean waiting = false;
019    int onReply = UNKNOWN;
020    SprogTrafficController trafficController = null;
021
022    public SprogPowerManager(SprogSystemConnectionMemo memo) {
023        super(memo);
024        // connect to the TrafficManager
025        trafficController = memo.getSprogTrafficController();
026        trafficController.addSprogListener(this);
027    }
028
029    @Override
030    public void setPower(int v) throws JmriException {
031        int old = power;
032        power = UNKNOWN; // while waiting for reply
033        checkTC();
034        if (v == ON) {
035            // configure to wait for reply
036            log.debug("setPower ON");
037            waiting = true;
038            onReply = PowerManager.ON;
039            // send "Enable main track"
040            SprogMessage l = SprogMessage.getEnableMain();
041            trafficController.sendSprogMessage(l, this);
042        } else if (v == OFF) {
043            // configure to wait for reply
044            log.debug("setPower OFF");
045            waiting = true;
046            onReply = PowerManager.OFF;
047            // send "Kill main track"
048            SprogMessage l = SprogMessage.getKillMain();
049            for (int i = 0; i < 3; i++) {
050                trafficController.sendSprogMessage(l, this);
051            }
052        }
053        firePowerPropertyChange(old, power);
054    }
055
056    /**
057     * Update power state after service mode programming operation
058     * without sending a message to the SPROG.
059     * @param v new power state.
060     */
061    public void notePowerState(int v) {
062        int old = power;
063        power = v;
064        firePowerPropertyChange(old, power);
065    }
066
067    /**
068     * Free resources when no longer used.
069     */
070    @Override
071    public void dispose() throws JmriException {
072        trafficController.removeSprogListener(this);
073        trafficController = null;
074    }
075
076    private void checkTC() throws JmriException {
077        if (trafficController == null) {
078            throw new JmriException("attempt to use SprogPowerManager after dispose");
079        }
080    }
081
082    /**
083     * Listen for status changes from Sprog system.
084     */
085    @Override
086    public void notifyReply(SprogReply m) {
087        if (waiting) {
088            log.debug("Reply while waiting");
089            int old = power;
090            power = onReply;
091            firePowerPropertyChange(old, power);
092        }
093        waiting = false;
094    }
095
096    @Override
097    public void notifyMessage(SprogMessage m) {
098        if (m.isKillMain()) {
099            // configure to wait for reply
100            log.debug("Seen Kill Main");
101            waiting = true;
102            onReply = PowerManager.OFF;
103        } else if (m.isEnableMain()) {
104            // configure to wait for reply
105            log.debug("Seen Enable Main");
106            waiting = true;
107            onReply = PowerManager.ON;
108        }
109    }
110
111    public void notify(AbstractMessage m) {
112        if (m instanceof SprogMessage) {
113            this.notifyMessage((SprogMessage) m);
114        } else if (m instanceof SprogReply){
115            this.notifyReply((SprogReply) m);
116        }
117    }
118
119    // initialize logging
120    private final static Logger log = LoggerFactory.getLogger(SprogPowerManager.class);
121}