001package jmri;
002
003import java.util.ArrayList;
004import java.util.Collections;
005import java.util.HashMap;
006import javax.annotation.Nonnull;
007
008/**
009 * Create a list of layout scale objects and provide retrieval methods.
010 * <p>
011 * See {@link jmri.Scale Scale} for details of each scale object.
012 *
013 * @author Dave Sand Copyright (C) 2018
014 * @since 4.13.6
015 */
016public class ScaleManager {
017
018    private static HashMap<String, Scale> _scaleMap = new HashMap<>();
019
020    /**
021     * Load the hash map from ScaleData.xml.  The XML load process will load
022     * the customized local copy if available, otherwise the program file will be used.
023     */
024    private static void fillMap() {
025        if (!jmri.configurexml.ScaleConfigXML.doLoad()) {
026            // Create backup HO and N scales
027            addScale("HO", "HO", 87.1);
028            addScale("N", "N", 160.0);
029        }
030        log.debug("ScaleManager initialized");
031    }
032
033    /**
034     * Create a scale instance and add it to the map.
035     * @param scaleName The scale name, such as HO.
036     * @param userName The user name.  By default the same as the scale name.
037     * @param scaleRatio The ratio for the scale, such as 87.1.
038     */
039    public static void addScale(String scaleName, String userName, double scaleRatio) {
040        _scaleMap.put(scaleName, new Scale(scaleName, scaleRatio, userName));
041    }
042
043    /**
044     * Get the scale that corresponds to the supplied scale name, otherwise null.
045     * @param name The scale name.
046     * @return The selected scale or null.
047     */
048    public static Scale getScale(@Nonnull String name) {
049        if (_scaleMap.isEmpty()) fillMap();
050        return _scaleMap.get(name);
051    }
052
053    /**
054     * Get a list of all scale entries sorted by user name.
055     * @return The sorted scale list.
056     */
057    public static ArrayList<Scale> getScales() {
058        if (_scaleMap.isEmpty()) fillMap();
059        ArrayList<Scale> list = new ArrayList<>();
060        for (Scale scale : _scaleMap.values()) {
061            list.add(scale);
062        }
063        Collections.sort(list, (o1, o2) -> o1.getUserName().compareTo(o2.getUserName()));
064        return list;
065    }
066
067    /**
068     * Get the scale that matches the user name, the scale name, or null.
069     * The user names are searched first.  If not found then the scale name is used.
070     * @param name The user name or scale name.
071     * @return The selected scale or null.
072     */
073    public static Scale getScaleByName(@Nonnull String name) {
074        if (_scaleMap.isEmpty()) fillMap();
075        for (Scale scale : _scaleMap.values()) {
076            if (scale.getUserName().equals(name)) {
077                return scale;
078            }
079        }
080        return _scaleMap.get(name);
081    }
082
083    private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(ScaleManager.class);
084}