001/*
002 * This file is part of McIDAS-V
003 *
004 * Copyright 2007-2016
005 * Space Science and Engineering Center (SSEC)
006 * University of Wisconsin - Madison
007 * 1225 W. Dayton Street, Madison, WI 53706, USA
008 * https://www.ssec.wisc.edu/mcidas
009 * 
010 * All Rights Reserved
011 * 
012 * McIDAS-V is built on Unidata's IDV and SSEC's VisAD libraries, and
013 * some McIDAS-V source code is based on IDV and VisAD source code.  
014 * 
015 * McIDAS-V is free software; you can redistribute it and/or modify
016 * it under the terms of the GNU Lesser Public License as published by
017 * the Free Software Foundation; either version 3 of the License, or
018 * (at your option) any later version.
019 * 
020 * McIDAS-V is distributed in the hope that it will be useful,
021 * but WITHOUT ANY WARRANTY; without even the implied warranty of
022 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
023 * GNU Lesser Public License for more details.
024 * 
025 * You should have received a copy of the GNU Lesser Public License
026 * along with this program.  If not, see http://www.gnu.org/licenses.
027 */
028package edu.wisc.ssec.mcidasv.startupmanager.options;
029
030import static edu.wisc.ssec.mcidasv.startupmanager.options.OptionMaster.EMPTY_STRING;
031import static edu.wisc.ssec.mcidasv.startupmanager.options.OptionMaster.QUOTE_STRING;
032import static edu.wisc.ssec.mcidasv.startupmanager.options.OptionMaster.SET_PREFIX;
033
034import java.awt.event.KeyAdapter;
035import java.awt.event.KeyEvent;
036
037import javax.swing.JTextField;
038import javax.swing.SwingUtilities;
039
040import edu.wisc.ssec.mcidasv.startupmanager.Platform;
041import edu.wisc.ssec.mcidasv.startupmanager.StartupManager;
042import edu.wisc.ssec.mcidasv.startupmanager.options.OptionMaster.OptionPlatform;
043import edu.wisc.ssec.mcidasv.startupmanager.options.OptionMaster.Type;
044import edu.wisc.ssec.mcidasv.startupmanager.options.OptionMaster.Visibility;
045
046//import org.slf4j.Logger;
047//import org.slf4j.LoggerFactory;
048
049public class TextOption extends AbstractOption {
050
051    /** Logging object. */
052//    private static final Logger logger = LoggerFactory.getLogger(TextOption.class);
053
054    /** Text field value. */
055    private String value;
056
057    /**
058     * Create a startup option that allows the user to supply arbitrary text.
059     *
060     * <p><b>NOTE:</b> {@code null} is not a permitted value for any of this
061     * constructor's parameters.</p>
062     *
063     * @param id Identifier for this startup option.
064     * @param label Brief description suitable for a GUI label.
065     * @param defaultValue Default value for this startup option.
066     * @param optionPlatform Platforms where this option may be applied.
067     * @param optionVisibility Whether or not the option is presented via the GUI.
068     */
069    public TextOption(final String id, final String label, 
070        final String defaultValue, final OptionPlatform optionPlatform,
071        final Visibility optionVisibility) 
072    {
073        super(id, label, Type.TEXT, optionPlatform, optionVisibility);
074        value = defaultValue;
075    }
076
077    /**
078     * Builds a {@link JTextField} containing the text value specified in the
079     * constructor.
080     *
081     * @return {@code JTextField} to present to the user.
082     */
083    public JTextField getComponent() {
084        final JTextField tf = new JTextField(value, 10);
085        tf.addKeyListener(new KeyAdapter() {
086            @Override public void keyReleased(final KeyEvent e) {
087                setValue(tf.getText());
088            }
089        });
090        if (!onValidPlatform()) {
091            SwingUtilities.invokeLater(() -> tf.setEnabled(false));
092        }
093        return tf;
094    }
095
096    /**
097     * Returns the user's input (or the default value).
098     *
099     * @return Input or default value.
100     */
101    public String getValue() {
102//        logger.trace("returning value='{}'", value);
103        return value;
104    }
105
106    /**
107     * Stores the user's input.
108     *
109     * @param newValue User input. Should not be {@code null}; use a zero
110     * length {@code String} to specify an empty value.
111     */
112    public void setValue(final String newValue) {
113//        logger.trace("overwrite value='{}' with newValue='{}'", value, newValue);
114        value = newValue;
115    }
116
117    /**
118     * Initializes the current option using a relevant variable from the
119     * startup script.
120     *
121     * @param text Line from the startup script that represents the current
122     * option. {@code null} is not allowed.
123     *
124     * @throws IllegalArgumentException if {@code text} is not in the proper
125     * format for the current platform.
126     */
127    @Override public void fromPrefsFormat(final String text) {
128        if (!isValidPrefFormat(text)) {
129            throw new IllegalArgumentException("Incorrect syntax for this platform: " + text);
130        }
131        String copy = new String(text);
132        if (StartupManager.getInstance().getPlatform() == Platform.WINDOWS) {
133            copy = copy.replace(SET_PREFIX, EMPTY_STRING);
134        }
135        int splitAt = copy.indexOf('=');
136        if (splitAt >= 0) {
137            setValue(removeOutermostQuotes(copy.substring(splitAt + 1)));
138        } else {
139            setValue(EMPTY_STRING);
140        }
141    }
142
143    /**
144     * {@code String} representation of this {@code TextOption}.
145     *
146     * @return {@code String} that looks something like
147     * {@literal "[TextOption@7825114a: optionId=BLAH value=USER INPUT]"}.
148     */
149    public String toString() {
150        return String.format("[TextOption@%x: optionId=%s, value=%s]",
151            hashCode(), getOptionId(), getValue());
152    }
153
154    /**
155     * If the given {@code String} begins and ends with
156     * {@link OptionMaster#QUOTE_STRING}, this method will return the given
157     * {@code String} without the {@literal "outermost"} quote pair. Otherwise
158     * the {@code String} is returned without modification.
159     *
160     * @param value {@code String} from which the outermost pair of quotes
161     * should be removed. Cannot be {@code null}.
162     *
163     * @return Either {@code value} with the outermost pair of quotes removed,
164     * or {@code value}, unmodified.
165     */
166    public static String removeOutermostQuotes(final String value) {
167        String returnValue = value;
168        if (value.startsWith(QUOTE_STRING) && value.endsWith(QUOTE_STRING)) {
169            returnValue = value.substring(1, value.length() - 1);
170        }
171        return returnValue;
172    }
173}