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     * @param powerOption true if track power at startup is ON
146     */
147    public void configureCommandStation(boolean powerOption) {
148        if(classObjectMap.containsKey(CommandStation.class)) {
149            return;
150        }
151        log.debug("start command station queuing thread");
152        SprogCommandStation commandStation = new jmri.jmrix.sprog.SprogCommandStation(st);
153        commandStation.setSystemConnectionMemo(this);
154        commandStation.setPowerState(powerOption);
155        jmri.InstanceManager.store(commandStation, jmri.CommandStation.class);
156        store(commandStation, jmri.CommandStation.class);
157        switch (sprogMode) {
158            case OPS:
159                slotThread = jmri.util.ThreadingUtil.newThread(commandStation);
160                slotThread.setName("SPROG slot thread");
161                slotThread.setPriority(Thread.MAX_PRIORITY-2);
162                slotThread.start();
163                break;
164            case SERVICE:
165                break;
166            default:
167                log.error("Unhandled sprogMode: {}", sprogMode);
168                break;
169        }
170    }
171
172    public void configureCommandStation() {
173        this.configureCommandStation(false);
174    }
175    
176    /**
177     * Configure the programming manager and "command station" objects.
178     * 
179     * @param slots number of command station slots
180     */
181    public void configureCommandStation(int slots) {
182        numSlots = slots;
183        this.configureCommandStation(false);
184    }
185
186    /**
187     * Configure the programming manager and "command station" objects.
188     * 
189     * @param slots number of command station slots
190     * @param powerOption true if track power at startup is ON
191     */
192    public void configureCommandStation(int slots, String powerOption) {
193        numSlots = slots;
194        if (powerOption != null && powerOption.equals(Bundle.getMessage("PowerStateOn"))) {
195            this.configureCommandStation(true);
196        } else {
197            this.configureCommandStation(false);
198        }
199    }
200
201    /**
202     * Get the command station object associated with this connection.
203     *
204     * @return the command station
205     */
206    public SprogCommandStation getCommandStation() {
207        return (SprogCommandStation)get(CommandStation.class);
208    }
209
210    @Override
211    public boolean provides(Class<?> type) {
212        if (getDisabled()) {
213            return false;
214        }
215        if ((type.equals(jmri.CommandStation.class))) {
216            if (sprogMode == null) {
217                return false;
218            }
219            switch (sprogMode) {
220                case OPS:
221                    return true;
222                case SERVICE:
223                    return false;
224                default:
225                    log.error("Unhandled sprogMode: {}", sprogMode);
226                    break;
227            }
228        }
229        return super.provides(type);
230    }
231
232    /**
233     * Configure the common managers for Sprog connections.
234     */
235    @Override
236    public void configureManagers() {
237
238        configureCommandStation();
239
240        if (getProgrammerManager().isAddressedModePossible()) {
241            jmri.InstanceManager.store(getProgrammerManager(), AddressedProgrammerManager.class);
242            store(getProgrammerManager(), AddressedProgrammerManager.class);
243        }
244        if (getProgrammerManager().isGlobalProgrammerAvailable()) {
245            InstanceManager.store(getProgrammerManager(), GlobalProgrammerManager.class);
246            store(getProgrammerManager(), GlobalProgrammerManager.class);
247        }
248
249        PowerManager powerManager = new jmri.jmrix.sprog.SprogPowerManager(this);
250        jmri.InstanceManager.store(powerManager, PowerManager.class);
251        store(powerManager, PowerManager.class);
252
253        TurnoutManager sprogTurnoutManager = new SprogTurnoutManager(this);
254        jmri.InstanceManager.setTurnoutManager(sprogTurnoutManager);
255        store(sprogTurnoutManager,TurnoutManager.class);
256
257        switch (sprogMode) {
258            case OPS:
259                ThrottleManager sprogCSThrottleManager = new jmri.jmrix.sprog.SprogCSThrottleManager(this);
260                jmri.InstanceManager.setThrottleManager(sprogCSThrottleManager);
261                store(sprogCSThrottleManager,ThrottleManager.class);
262                break;
263            case SERVICE:
264                ThrottleManager sprogThrottleManager = new jmri.jmrix.sprog.SprogThrottleManager(this);
265                jmri.InstanceManager.setThrottleManager(sprogThrottleManager);
266                store(sprogThrottleManager,ThrottleManager.class);
267                break;
268            default:
269                log.warn("Unhandled programming mode: {}", sprogMode);
270                break;
271        }
272        register();
273    }
274
275    public SprogProgrammerManager getProgrammerManager() {
276
277        return (SprogProgrammerManager) classObjectMap.computeIfAbsent(SprogProgrammerManager.class, (Class<?> c) -> new SprogProgrammerManager(new SprogProgrammer(this), sprogMode, this));
278    }
279
280    public void setProgrammerManager(SprogProgrammerManager p) {
281        store(p,SprogProgrammerManager.class);
282    }
283
284    public SprogPowerManager getPowerManager() {
285        return (SprogPowerManager)get(PowerManager.class);
286    }
287
288    public ThrottleManager getThrottleManager() {
289        return get(ThrottleManager.class);
290    }
291
292    public TurnoutManager getTurnoutManager() {
293        return get(TurnoutManager.class);
294    }
295
296    @Override
297    protected ResourceBundle getActionModelResourceBundle() {
298        return ResourceBundle.getBundle("jmri.jmrix.sprog.SprogActionListBundle");
299    }
300
301    @Override
302    public <B extends NamedBean> Comparator<B> getNamedBeanComparator(Class<B> type) {
303        return new NamedBeanComparator<>();
304    }
305
306    @Override
307    public void dispose() {
308        if (st != null) {
309            st.dispose();
310        }
311        st = null;
312        InstanceManager.deregister(this, SprogSystemConnectionMemo.class);
313        if (cf != null) {
314            InstanceManager.deregister(cf, jmri.jmrix.swing.ComponentFactory.class);
315        }
316        super.dispose();
317    }
318
319    private SprogVersionQuery svq = null;
320
321    /**
322     * @return a SprogVersionQuery object for this connection
323     */
324    public SprogVersionQuery getSprogVersionQuery() {
325        if (svq == null) {
326            svq = new SprogVersionQuery(this);
327        }
328        return svq;
329    }
330
331    private static final Logger log = LoggerFactory.getLogger(SprogSystemConnectionMemo.class);
332
333}