001package jmri.jmrix.sprog;
002
003import java.util.Comparator;
004import java.util.ResourceBundle;
005
006import jmri.*;
007import jmri.jmrix.ConfiguringSystemConnectionMemo;
008import jmri.jmrix.DefaultSystemConnectionMemo;
009import jmri.jmrix.sprog.SprogConstants.SprogMode;
010import jmri.jmrix.sprog.update.SprogType;
011import jmri.jmrix.sprog.update.SprogVersion;
012import jmri.jmrix.sprog.update.SprogVersionQuery;
013import jmri.jmrix.swing.ComponentFactory;
014import jmri.util.NamedBeanComparator;
015
016import org.slf4j.Logger;
017import org.slf4j.LoggerFactory;
018
019/**
020 * Lightweight class to denote that a system is active, and provide general
021 * information.
022 * <p>
023 * Objects of specific subtypes are registered in the instance manager to
024 * activate their particular system.
025 *
026 * @author Bob Jacobsen Copyright (C) 2010
027 */
028public class SprogSystemConnectionMemo extends DefaultSystemConnectionMemo implements ConfiguringSystemConnectionMemo {
029
030    public SprogSystemConnectionMemo(SprogTrafficController st, SprogMode sm) {
031        super(st.getController().getSystemConnectionMemo().getSystemPrefix(), SprogConnectionTypeList.SPROG);
032        if (log.isDebugEnabled()) {
033            log.debug("SprogSystemConnectionMemo, prefix='{}'", st.getController().getSystemConnectionMemo().getSystemPrefix());
034        }
035        this.st = st;
036        init(sm, new SprogType(SprogType.UNKNOWN));
037    }
038
039    public SprogSystemConnectionMemo(SprogMode sm) {
040        this(sm, new SprogType(SprogType.UNKNOWN));
041    }
042
043    public SprogSystemConnectionMemo(SprogMode sm, SprogType type) {
044        super("S", SprogConnectionTypeList.SPROG); // default to S
045        init(sm, type);
046    }
047    
048    private void init(SprogMode sm, SprogType type) {
049        sprogMode = sm;  // static
050        sprogVersion = new SprogVersion(type);
051        cf = new jmri.jmrix.sprog.swing.SprogComponentFactory(this);
052        InstanceManager.store(this, SprogSystemConnectionMemo.class);
053        InstanceManager.store(cf, ComponentFactory.class);
054    }
055
056    public SprogSystemConnectionMemo() {
057        this(SprogMode.OPS);
058    }
059
060    /**
061     * Set the SPROG mode for this connection.
062     *
063     * @param mode selected mode
064     */
065    public void setSprogMode(SprogMode mode) {
066        sprogMode = mode;
067    }
068
069    /**
070     * Return the SPROG mode for this connection.
071     *
072     * @return SprogMode
073     */
074    public SprogMode getSprogMode() {
075        return sprogMode;
076    }
077    private SprogMode sprogMode;
078
079    /**
080     * Return the SPROG version object for this connection.
081     *
082     * @return SprogVersion
083     */
084    public SprogVersion getSprogVersion() {
085        return sprogVersion;
086    }
087
088    /**
089     * Set the SPROG version object for this connection.
090     *
091     * @param version type and version class
092     */
093    public void setSprogVersion(SprogVersion version) {
094        sprogVersion = version;
095    }
096
097    private SprogVersion sprogVersion;
098
099    /**
100     * Return the type of SPROG connected.
101     *
102     * @return SprogType set
103     */
104    public SprogType getSprogType() {
105        return sprogVersion.sprogType;
106    }
107
108    ComponentFactory cf = null;
109
110    /**
111     * Provide access to the TrafficController for this particular connection.
112     *
113     * @return current tc for this connection
114     */
115    public SprogTrafficController getSprogTrafficController() {
116        return st;
117    }
118
119    public void setSprogTrafficController(SprogTrafficController st) {
120        this.st = st;
121    }
122
123    private SprogTrafficController st;
124
125    private Thread slotThread;
126
127    public Thread getSlotThread() {
128        return slotThread;
129    }
130    
131    private int numSlots = SprogConstants.DEFAULT_MAX_SLOTS;
132    
133    /**
134     * Get the number of command station slots
135     * 
136     * @return The number fo slots
137     */
138    public int getNumSlots() {
139        return numSlots;
140    }
141
142    /**
143     * Configure the programming manager and "command station" objects.
144     */
145    public void configureCommandStation() {
146        if(classObjectMap.containsKey(CommandStation.class)) {
147            return;
148        }
149        log.debug("start command station queuing thread");
150        SprogCommandStation commandStation = new jmri.jmrix.sprog.SprogCommandStation(st);
151        commandStation.setSystemConnectionMemo(this);
152        jmri.InstanceManager.store(commandStation, jmri.CommandStation.class);
153        store(commandStation, jmri.CommandStation.class);
154        switch (sprogMode) {
155            case OPS:
156                slotThread = jmri.util.ThreadingUtil.newThread(commandStation);
157                slotThread.setName("SPROG slot thread");
158                slotThread.setPriority(Thread.MAX_PRIORITY-2);
159                slotThread.start();
160                break;
161            case SERVICE:
162                break;
163            default:
164                log.error("Unhandled sprogMode: {}", sprogMode);
165                break;
166        }
167    }
168
169    public void configureCommandStation(int slots) {
170        numSlots = slots;
171        this.configureCommandStation();
172    }
173    
174    /**
175     * Get the command station object associated with this connection.
176     * 
177     * @return the command station
178     */
179    public SprogCommandStation getCommandStation() {
180        return get(CommandStation.class);
181    }
182
183    @Override
184    public boolean provides(Class<?> type) {
185        if (getDisabled()) {
186            return false;
187        }
188        if ((type.equals(jmri.CommandStation.class))) {
189            if (sprogMode == null) {
190                return false;
191            }
192            switch (sprogMode) {
193                case OPS:
194                    return true;
195                case SERVICE:
196                    return false;
197                default:
198                    log.error("Unhandled sprogMode: {}", sprogMode);
199                    break;
200            }
201        }
202        return super.provides(type);
203    }
204
205    /**
206     * Configure the common managers for Sprog connections.
207     */
208    public void configureManagers() {
209
210        configureCommandStation();
211
212        if (getProgrammerManager().isAddressedModePossible()) {
213            jmri.InstanceManager.store(getProgrammerManager(), AddressedProgrammerManager.class);
214            store(getProgrammerManager(), AddressedProgrammerManager.class);
215        }
216        if (getProgrammerManager().isGlobalProgrammerAvailable()) {
217            InstanceManager.store(getProgrammerManager(), GlobalProgrammerManager.class);
218            store(getProgrammerManager(), GlobalProgrammerManager.class);
219        }
220
221        PowerManager powerManager = new jmri.jmrix.sprog.SprogPowerManager(this);
222        jmri.InstanceManager.store(powerManager, PowerManager.class);
223        store(powerManager, PowerManager.class);
224
225        TurnoutManager sprogTurnoutManager = new SprogTurnoutManager(this);
226        jmri.InstanceManager.setTurnoutManager(sprogTurnoutManager);
227        store(sprogTurnoutManager,TurnoutManager.class);
228
229        switch (sprogMode) {
230            case OPS:
231                ThrottleManager sprogCSThrottleManager = new jmri.jmrix.sprog.SprogCSThrottleManager(this);
232                jmri.InstanceManager.setThrottleManager(sprogCSThrottleManager);
233                store(sprogCSThrottleManager,ThrottleManager.class);
234                break;
235            case SERVICE:
236                ThrottleManager sprogThrottleManager = new jmri.jmrix.sprog.SprogThrottleManager(this);
237                jmri.InstanceManager.setThrottleManager(sprogThrottleManager);
238                store(sprogThrottleManager,ThrottleManager.class);
239                break;
240            default:
241                log.warn("Unhandled programming mode: {}", sprogMode);
242                break;
243        }
244        register();
245    }
246
247    public SprogProgrammerManager getProgrammerManager() {
248
249        return (SprogProgrammerManager) classObjectMap.computeIfAbsent(SprogProgrammerManager.class, (Class c) -> new SprogProgrammerManager(new SprogProgrammer(this), sprogMode, this));
250    }
251
252    public void setProgrammerManager(SprogProgrammerManager p) {
253        store(p,SprogProgrammerManager.class);
254    }
255
256    public SprogPowerManager getPowerManager() {
257        return get(PowerManager.class);
258    }
259
260    public ThrottleManager getThrottleManager() {
261        return get(ThrottleManager.class);
262    }
263
264    public TurnoutManager getTurnoutManager() {
265        return get(TurnoutManager.class);
266    }
267
268    @Override
269    protected ResourceBundle getActionModelResourceBundle() {
270        return ResourceBundle.getBundle("jmri.jmrix.sprog.SprogActionListBundle");
271    }
272
273    @Override
274    public <B extends NamedBean> Comparator<B> getNamedBeanComparator(Class<B> type) {
275        return new NamedBeanComparator<>();
276    }
277
278    @Override
279    public void dispose() {
280        st = null;
281        InstanceManager.deregister(this, SprogSystemConnectionMemo.class);
282        if (cf != null) {
283            InstanceManager.deregister(cf, jmri.jmrix.swing.ComponentFactory.class);
284        }
285        super.dispose();
286    }
287
288    private SprogVersionQuery svq = null;
289
290    /**
291     * @return a SprogVersionQuery object for this connection
292     */
293    public SprogVersionQuery getSprogVersionQuery() {
294        if (svq == null) {
295            svq = new SprogVersionQuery(this);
296        }
297        return svq;
298    }
299
300    private static final Logger log = LoggerFactory.getLogger(SprogSystemConnectionMemo.class);
301
302}