001package jmri.jmrit.operations.automation.actions;
002
003import java.beans.PropertyChangeEvent;
004import java.beans.PropertyChangeListener;
005
006import org.slf4j.Logger;
007import org.slf4j.LoggerFactory;
008
009import jmri.jmrit.operations.routes.RouteLocation;
010import jmri.jmrit.operations.setup.Control;
011import jmri.jmrit.operations.trains.Train;
012
013public class WaitTrainAction extends Action implements PropertyChangeListener {
014
015    private static final int _code = ActionCodes.WAIT_FOR_TRAIN;
016
017    @Override
018    public int getCode() {
019        return _code;
020    }
021
022    @Override
023    public String getName() {
024        return Bundle.getMessage("WaitForTrain");
025    }
026
027    @Override
028    public boolean isConcurrentAction() {
029        return true;
030    }
031
032    @Override
033    public void doAction() {
034        if (getAutomationItem() != null) {
035            Train train = getAutomationItem().getTrain();
036            if (train != null && train.getRoute() != null) {
037                setRunning(true);
038                train.addPropertyChangeListener(this);
039                RouteLocation rl = getAutomationItem().getRouteLocation();
040                if (!train.isBuilt() || rl != null && rl != train.getCurrentRouteLocation()) {
041                    return; // wait for property change
042                }
043                train.removePropertyChangeListener(this);
044                finishAction(true); // done
045            } else {
046                finishAction(false);
047            }
048        }
049    }
050
051    /**
052     * Wait for train to build and no location, or train to arrive at location,
053     * or train build to be deselected.
054     *
055     */
056    private void trainUpdate(PropertyChangeEvent evt) {
057        if (getAutomationItem() != null) {
058            if (evt.getPropertyName().equals(Train.TRAIN_MOVE_COMPLETE_CHANGED_PROPERTY) ||
059                    (evt.getPropertyName().equals(Train.BUILT_CHANGED_PROPERTY)
060                    && (boolean) evt.getNewValue() == true)) {
061                Train train = getAutomationItem().getTrain();
062                RouteLocation rl = getAutomationItem().getRouteLocation();
063                if (rl != null && rl != train.getCurrentRouteLocation()) {
064                    return; // haven't reached this location continue waiting
065                }
066                train.removePropertyChangeListener(this);
067                finishAction(true);
068            } else if (evt.getPropertyName().equals(Train.BUILD_CHANGED_PROPERTY)
069                    && (boolean) evt.getNewValue() == false) {
070                Train train = getAutomationItem().getTrain();
071                train.removePropertyChangeListener(this);
072                finishAction(true);
073            }
074        }
075    }
076
077    @Override
078    public void cancelAction() {
079        if (getAutomationItem() != null) {
080            setRunning(false);
081            Train train = getAutomationItem().getTrain();
082            if (train != null) {
083                train.removePropertyChangeListener(this);
084            }
085        }
086    }
087
088    @Override
089    public void propertyChange(PropertyChangeEvent evt) {
090        if (Control.SHOW_PROPERTY)
091            log.debug("Property change AutomationItem {}: ({}) old: ({}) new: ({})", getAutomationItem().getId(),
092                    evt.getPropertyName(), evt.getOldValue(), evt.getNewValue());
093        trainUpdate(evt);
094    }
095
096    private final static Logger log = LoggerFactory.getLogger(WaitTrainAction.class);
097
098}