001package jmri.implementation;
002
003import java.util.ArrayList;
004import java.util.HashMap;
005import jmri.Consist;
006import jmri.ConsistListListener;
007import jmri.ConsistListener;
008import jmri.ConsistManager;
009import jmri.LocoAddress;
010
011/**
012 * An Abstract Consist Manager on top of which system specific consist managers
013 * can be built.
014 *
015 * @author Paul Bender Copyright (C) 2004
016 * @author Randall Wood Copyright (C) 2013
017 */
018public abstract class AbstractConsistManager implements ConsistManager {
019
020    protected HashMap<LocoAddress, Consist> consistTable = null;
021    private ArrayList<ConsistListListener> changeListeners = null;
022
023    public AbstractConsistManager() {
024        consistTable = new HashMap<>();
025        changeListeners = new ArrayList<>();
026    }
027
028    /**
029     * Find a Consist with this consist address, and return it.
030     */
031    @Override
032    public Consist getConsist(LocoAddress address) {
033        if (consistTable.containsKey(address)) {
034            return (consistTable.get(address));
035        } else {
036            return (addConsist(address));
037        }
038    }
039
040    /**
041     * Add a new Consist with the given address.
042     *
043     * @param address consist address
044     * @return a consist at address; this will be the existing consist if a
045     *         consist is already known to exist at address
046     */
047    protected abstract  Consist addConsist(LocoAddress address);
048
049    // remove the old Consist
050    @Override
051    public void delConsist(LocoAddress address) {
052        consistTable.get(address).dispose();
053        consistTable.remove(address);
054    }
055
056    /**
057     * Return the list of consists we know about.
058     */
059    @Override
060    public ArrayList<LocoAddress> getConsistList() {
061        return new ArrayList<>(consistTable.keySet());
062    }
063
064    @Override
065    public String decodeErrorCode(int errorCode) {
066        StringBuilder buffer = new StringBuilder("");
067        if ((errorCode & ConsistListener.NotImplemented) != 0) {
068            buffer.append("Not Implemented ");
069        }
070        if ((errorCode & ConsistListener.OPERATION_SUCCESS) != 0) {
071            buffer.append("Operation Completed Successfully ");
072        }
073        if ((errorCode & ConsistListener.CONSIST_ERROR) != 0) {
074            buffer.append("Consist Error ");
075        }
076        if ((errorCode & ConsistListener.LOCO_NOT_OPERATED) != 0) {
077            buffer.append("Address not controled by this device.");
078        }
079        if ((errorCode & ConsistListener.ALREADY_CONSISTED) != 0) {
080            buffer.append("Locomotive already consisted");
081        }
082        if ((errorCode & ConsistListener.NOT_CONSISTED) != 0) {
083            buffer.append("Locomotive Not Consisted ");
084        }
085        if ((errorCode & ConsistListener.NONZERO_SPEED) != 0) {
086            buffer.append("Speed Not Zero ");
087        }
088        if ((errorCode & ConsistListener.NOT_CONSIST_ADDR) != 0) {
089            buffer.append("Address Not Conist Address ");
090        }
091        if ((errorCode & ConsistListener.DELETE_ERROR) != 0) {
092            buffer.append("Delete Error ");
093        }
094        if ((errorCode & ConsistListener.STACK_FULL) != 0) {
095            buffer.append("Stack Full ");
096        }
097
098        String retval = buffer.toString();
099        if (retval.equals("")) {
100            return "Unknown Status Code: " + errorCode;
101        } else {
102            return retval;
103        }
104    }
105
106    @Override
107    public void requestUpdateFromLayout() {
108    }
109
110    /**
111     * Allow a request for consist updates from the layout.
112     *
113     * If not overridden by a concrete subclass, this method always returns
114     * true.
115     *
116     * @return true if the request can be made, false if not
117     */
118    protected boolean shouldRequestUpdateFromLayout() {
119        return true;
120    }
121
122    /*
123     * register a ConsistListListener object with this Consist
124     * Manager
125     * @param listener a Consist List Listener object.
126     */
127    @Override
128    public void addConsistListListener(ConsistListListener l) {
129        changeListeners.add(l);
130    }
131
132    /*
133     * remove a ConsistListListener object with this Consist
134     * Manager
135     * @param listener a Consist List Listener object.
136     */
137    @Override
138    public void removeConsistListListener(ConsistListListener l) {
139        changeListeners.remove(l);
140    }
141
142    /*
143     * Notify the registered Consist List Listener objects that the
144     * Consist List has changed.
145     */
146    @Override
147    public void notifyConsistListChanged() {
148        for (ConsistListListener l : changeListeners) {
149            l.notifyConsistListChanged();
150        }
151    }
152
153}