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 final static 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(userInput, other.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     */
109    public AutoCompletionItemPriority mergeWith(AutoCompletionItemPriority other) {
110        return new AutoCompletionItemPriority(
111                inDataSet || other.inDataSet,
112                inStandard || other.inStandard,
113                selected || other.selected,
114                Math.min(userInput, other.userInput));
115    }
116
117    @Override public String toString() {
118        return String.format("<Priority; userInput: %s, inDataSet: %b, inStandard: %b, selected: %b>", 
119                userInput == NO_USER_INPUT ? "no" : Integer.toString(userInput), inDataSet, inStandard, selected);
120    }
121}