001package jmri.implementation;
002
003import java.util.*;
004
005import jmri.SignalSystem;
006import org.slf4j.Logger;
007import org.slf4j.LoggerFactory;
008
009/**
010 * Default implementation of a basic signal system definition.
011 * <p>
012 * The default contents are taken from the NamedBeanBundle properties file. This
013 * makes creation a little more heavy-weight, but speeds operation.
014 *
015 *
016 * @author Bob Jacobsen Copyright (C) 2009
017 */
018public class DefaultSignalSystem extends AbstractNamedBean implements SignalSystem {
019
020    public DefaultSignalSystem(String systemName, String userName) {
021        super(systemName, userName);
022    }
023
024    public DefaultSignalSystem(String systemName) {
025        super(systemName);
026    }
027
028    @Override
029    public void setProperty(String aspect, String key, Object value) {
030        getTable(aspect).put(key, value);
031        if (!keys.contains(key)) {
032            keys.add(key);
033        }
034    }
035
036    @Override
037    public Object getProperty(String aspect, String key) {
038        if (aspect == null) {
039            return null;
040        }
041        return getTable(aspect).get(key);
042    }
043
044    @Override
045    public void setImageType(String type) {
046        if (!imageTypes.contains(type)) {
047            imageTypes.add(type);
048        }
049    }
050
051    @Override
052    public Enumeration<String> getImageTypeList() {
053        return imageTypes.elements();
054    }
055
056    @Override
057    public String getAspect(Object obj, String key) {
058        if (obj == null) {
059            return null;
060        }
061        Set<String> aspectKeys = aspects.keySet();
062        for (String aspect : aspectKeys) {
063            if (getTable(aspect).containsKey(key)) {
064                if (getTable(aspect).get(key).equals(obj)) {
065                    return aspect;
066                }
067            }
068        }
069        return null;
070    }
071
072    protected Hashtable<String, Object> getTable(String aspect) {
073        Hashtable<String, Object> t = aspects.get(aspect);
074        if (t == null) {
075            t = new Hashtable<>();
076            aspects.put(aspect, t);
077        }
078        return t;
079    }
080
081    @Override
082    public Enumeration<String> getAspects() {
083        return new Vector<>(aspects.keySet()).elements();  // this will be greatly simplified when we can just return keySet
084    }
085
086    @Override
087    public Enumeration<String> getKeys() {
088        return keys.elements();
089    }
090
091    @Override
092    public boolean checkAspect(String aspect) {
093        return aspects.get(aspect) != null;
094    }
095
096    public void loadDefaults() {
097
098        log.debug("start loadDefaults");
099
100        String aspect;
101        String key = Bundle.getMessage("SignalAspectKey");
102        String value;
103
104        aspect = Bundle.getMessage("SignalAspectDefaultRed");
105        value = Bundle.getMessage("SignalAspect_" + key + "_" + aspect);
106        setProperty(aspect, key, value);
107
108        aspect = Bundle.getMessage("SignalAspectDefaultYellow");
109        value = Bundle.getMessage("SignalAspect_" + key + "_" + aspect);
110        setProperty(aspect, key, value);
111
112        aspect = Bundle.getMessage("SignalAspectDefaultGreen");
113        value = Bundle.getMessage("SignalAspect_" + key + "_" + aspect);
114        setProperty(aspect, key, value);
115
116    }
117
118    /**
119     * {@inheritDoc}
120     *
121     * This method returns a constant result on the DefaultSignalSystem.
122     *
123     * @return {@link jmri.NamedBean#INCONSISTENT}
124     */
125    @Override
126    public int getState() {
127        return INCONSISTENT;
128    }
129
130    /**
131     * {@inheritDoc}
132     *
133     * This method has no effect on the DefaultSignalSystem.
134     */
135    @Override
136    public void setState(int s) {
137        // do nothing
138    }
139
140    float maximumLineSpeed = 0.0f;
141
142    @Override
143    public float getMaximumLineSpeed() {
144        if (maximumLineSpeed == 0.0f) {
145            for (String as : aspects.keySet()) {
146                String speed = (String) getProperty(as, "speed");
147                if (speed != null) {
148                    float aspectSpeed = 0.0f;
149                    try {
150                        aspectSpeed = Float.parseFloat(speed);
151                    } catch (NumberFormatException nx) {
152                        try {
153                            aspectSpeed = jmri.InstanceManager.getDefault(SignalSpeedMap.class).getSpeed(speed);
154                        } catch (IllegalArgumentException ex) {
155                            //Considered Normal if the speed does not appear in the map
156                            log.debug("Speed {} not found in map", speed);
157                        }
158                    }
159                    if (aspectSpeed > maximumLineSpeed) {
160                        maximumLineSpeed = aspectSpeed;
161                    }
162                }
163
164            }
165        }
166        if (maximumLineSpeed == 0.0f) {
167            //no speeds configured so will use the default.
168            maximumLineSpeed = jmri.InstanceManager.getDefault(SignalSpeedMap.class).getSpeed("Maximum");
169        }
170        return maximumLineSpeed;
171    }
172
173    protected java.util.HashMap<String, Hashtable<String, Object>> aspects
174            = new java.util.LinkedHashMap<>();
175
176    protected java.util.Vector<String> keys = new java.util.Vector<>();
177
178    protected java.util.Vector<String> imageTypes = new java.util.Vector<>();
179
180    @Override
181    public String getBeanType() {
182        return Bundle.getMessage("BeanNameSignalSystem");
183    }
184    
185    @Override
186    /**
187     * {@inheritDoc}
188     */
189    public String summary() {
190        StringBuilder retval = new StringBuilder();
191        retval.append(toString());
192        retval.append("\n  BeanType: ").append(getBeanType());
193        
194        retval.append("\n  keys:");
195        for (String key : keys) retval.append("\n    ").append(key);
196        
197        retval.append("\n  aspects:");
198        Set<String> values = aspects.keySet();
199        for (String value : values) 
200            retval.append("\n    ").append(value);
201        
202        retval.append("\n  maximumLineSpeed = ").append(getMaximumLineSpeed());
203        
204        return new String(retval);
205    }
206
207    private final static Logger log = LoggerFactory.getLogger(DefaultSignalSystem.class);
208}
209