001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.gui.tagging.ac;
003
004/**
005 * Describes the priority of an item in an autocompletion list.
006 * The selected flag is currently only used in plugins.
007 *
008 * Instances of this class are not modifiable.
009 */
010public class AutoCompletionItemPriority implements Comparable<AutoCompletionItemPriority> {
011
012    /**
013     * Indicates, that the value is standard and it is found in the data.
014     * This has higher priority than some arbitrary standard value that is
015     * usually not used by the user.
016     */
017    public static final AutoCompletionItemPriority IS_IN_STANDARD_AND_IN_DATASET = new AutoCompletionItemPriority(true, true, false);
018
019    /**
020     * Indicates that this is an arbitrary value from the data set, i.e.
021     * the value of a tag name=*.
022     */
023    public static final AutoCompletionItemPriority IS_IN_DATASET = new AutoCompletionItemPriority(true, false, false);
024
025    /**
026     * Indicates that this is a standard value, i.e. a standard tag name
027     * or a standard value for a given tag name (from the presets).
028     */
029    public static final AutoCompletionItemPriority IS_IN_STANDARD = new AutoCompletionItemPriority(false, true, false);
030
031    /**
032     * Indicates that this is a value from a selected object.
033     */
034    public static final AutoCompletionItemPriority  IS_IN_SELECTION  = new AutoCompletionItemPriority(false, false, true);
035
036    /** Unknown priority. This is the lowest priority. */
037    public static final AutoCompletionItemPriority UNKNOWN = new AutoCompletionItemPriority(false, false, false);
038
039    private static final int NO_USER_INPUT = Integer.MAX_VALUE;
040
041    private final int userInput;
042    private final boolean inDataSet;
043    private final boolean inStandard;
044    private final boolean selected;
045
046
047    /**
048     * Create new AutoCompletionItemPriority object.
049     *
050     * @param inDataSet true, if the item is found in the currently active data layer
051     * @param inStandard true, if the item is a standard tag, e.g. from the presets.
052     * @param selected true, if it is found on an object that is currently selected
053     * @param userInput null, if the user hasn't entered this tag so far. A number when
054     * the tag key / value has been entered by the user before. A lower number means
055     * this happened more recently and beats a higher number in priority.
056     */
057    public AutoCompletionItemPriority(boolean inDataSet, boolean inStandard, boolean selected, Integer userInput) {
058        this.inDataSet = inDataSet;
059        this.inStandard = inStandard;
060        this.selected = selected;
061        this.userInput = userInput == null ? NO_USER_INPUT : userInput;
062    }
063
064    public AutoCompletionItemPriority(boolean inDataSet, boolean inStandard, boolean selected) {
065        this(inDataSet, inStandard, selected, NO_USER_INPUT);
066    }
067
068    public boolean isInDataSet() {
069        return inDataSet;
070    }
071
072    public boolean isInStandard() {
073        return inStandard;
074    }
075
076    public boolean isSelected() {
077        return selected;
078    }
079
080    public Integer getUserInput() {
081        return userInput == NO_USER_INPUT ? null : userInput;
082    }
083
084    /**
085     * Imposes an ordering on the priorities.
086     * Currently, being in the current DataSet is worth more than being in the Presets.
087     */
088    @Override
089    public int compareTo(AutoCompletionItemPriority other) {
090        int ui = Integer.compare(other.userInput, userInput);
091        if (ui != 0) return ui;
092
093        int sel = Boolean.valueOf(selected).compareTo(other.selected);
094        if (sel != 0) return sel;
095
096        int ds = Boolean.valueOf(inDataSet).compareTo(other.inDataSet);
097        if (ds != 0) return ds;
098
099        int std = Boolean.valueOf(inStandard).compareTo(other.inStandard);
100        if (std != 0) return std;
101
102        return 0;
103    }
104
105    /**
106     * Merges two priorities.
107     * The resulting priority is always &gt;= the original ones.
108     * @return the merged priority
109     */
110    public AutoCompletionItemPriority mergeWith(AutoCompletionItemPriority other) {
111        return new AutoCompletionItemPriority(
112                inDataSet || other.inDataSet,
113                inStandard || other.inStandard,
114                selected || other.selected,
115                Math.min(userInput, other.userInput));
116    }
117
118    @Override
119    public String toString() {
120        return String.format("<Priority; userInput: %s, inDataSet: %b, inStandard: %b, selected: %b>",
121                userInput == NO_USER_INPUT ? "no" : Integer.toString(userInput), inDataSet, inStandard, selected);
122    }
123}