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 final HashMap<String, Scale> _scaleMap = new HashMap<>();
019
020    /**
021     * Prevent public Construction, class only supplies static methods.
022     */
023    private ScaleManager(){}
024
025    /**
026     * Load the hash map from ScaleData.xml.  The XML load process will load
027     * the customized local copy if available, otherwise the program file will be used.
028     */
029    private static void fillMap() {
030        if (!jmri.configurexml.ScaleConfigXML.doLoad()) {
031            // Create backup HO and N scales
032            addScale("HO", "HO", 87.1);
033            addScale("N", "N", 160.0);
034        }
035        log.debug("ScaleManager initialized");
036    }
037
038    private static void fillScaleMapIfEmpty(){
039        if (_scaleMap.isEmpty()) {
040            fillMap();
041        }
042    }
043
044    /**
045     * Create a scale instance and add it to the map.
046     * @param scaleName The scale name, such as HO.
047     * @param userName The user name.  By default the same as the scale name.
048     * @param scaleRatio The ratio for the scale, such as 87.1.
049     */
050    public static void addScale(String scaleName, String userName, double scaleRatio) {
051        _scaleMap.put(scaleName, new Scale(scaleName, scaleRatio, userName));
052    }
053
054    /**
055     * Get the scale that corresponds to the supplied scale name, otherwise null.
056     * @param name The scale name.
057     * @return The selected scale or null.
058     */
059    public static Scale getScale(@Nonnull String name) {
060        fillScaleMapIfEmpty();
061        return _scaleMap.get(name);
062    }
063
064    /**
065     * Get a list of all scale entries sorted by user name.
066     * @return The sorted scale list.
067     */
068    public static ArrayList<Scale> getScales() {
069        fillScaleMapIfEmpty();
070        ArrayList<Scale> list = new ArrayList<>();
071        for (Scale scale : _scaleMap.values()) {
072            list.add(scale);
073        }
074        Collections.sort(list, (o1, o2) -> o1.getUserName().compareTo(o2.getUserName()));
075        return list;
076    }
077
078    /**
079     * Get the scale that matches the user name, the scale name, or null.
080     * The user names are searched first.  If not found then the scale name is used.
081     * @param name The user name or scale name.
082     * @return The selected scale or null.
083     */
084    public static Scale getScaleByName(@Nonnull String name) {
085        fillScaleMapIfEmpty();
086        for (Scale scale : _scaleMap.values()) {
087            if (scale.getUserName().equals(name)) {
088                return scale;
089            }
090        }
091        return _scaleMap.get(name);
092    }
093
094    private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(ScaleManager.class);
095
096}