001/*
002 * This file is part of McIDAS-V
003 *
004 * Copyright 2007-2015
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(new Runnable() {
092                @Override public void run() {
093                    tf.setEnabled(false);
094                }
095            });
096        }
097        return tf;
098    }
099
100    /**
101     * Returns the user's input (or the default value).
102     *
103     * @return Input or default value.
104     */
105    public String getValue() {
106//        logger.trace("returning value='{}'", value);
107        return value;
108    }
109
110    /**
111     * Stores the user's input.
112     *
113     * @param newValue User input. Should not be {@code null}; use a zero
114     * length {@code String} to specify an empty value.
115     */
116    public void setValue(final String newValue) {
117//        logger.trace("overwrite value='{}' with newValue='{}'", value, newValue);
118        value = newValue;
119    }
120
121    /**
122     * Initializes the current option using a relevant variable from the
123     * startup script.
124     *
125     * @param text Line from the startup script that represents the current
126     * option. {@code null} is not allowed.
127     *
128     * @throws IllegalArgumentException if {@code text} is not in the proper
129     * format for the current platform.
130     */
131    @Override public void fromPrefsFormat(final String text) {
132        if (!isValidPrefFormat(text)) {
133            throw new IllegalArgumentException("Incorrect syntax for this platform: " + text);
134        }
135        String copy = new String(text);
136        if (StartupManager.getInstance().getPlatform() == Platform.WINDOWS) {
137            copy = copy.replace(SET_PREFIX, EMPTY_STRING);
138        }
139        int splitAt = copy.indexOf('=');
140        if (splitAt >= 0) {
141            setValue(removeOutermostQuotes(copy.substring(splitAt + 1)));
142        } else {
143            setValue(EMPTY_STRING);
144        }
145    }
146
147    /**
148     * {@code String} representation of this {@code TextOption}.
149     *
150     * @return {@code String} that looks something like
151     * {@literal "[TextOption@7825114a: optionId=BLAH value=USER INPUT]"}.
152     */
153    public String toString() {
154        return String.format("[TextOption@%x: optionId=%s, value=%s]",
155            hashCode(), getOptionId(), getValue());
156    }
157
158    /**
159     * If the given {@code String} begins and ends with
160     * {@link OptionMaster#QUOTE_STRING}, this method will return the given
161     * {@code String} without the {@literal "outermost"} quote pair. Otherwise
162     * the {@code String} is returned without modification.
163     *
164     * @param value {@code String} from which the outermost pair of quotes
165     * should be removed. Cannot be {@code null}.
166     *
167     * @return Either {@code value} with the outermost pair of quotes removed,
168     * or {@code value}, unmodified.
169     */
170    public static String removeOutermostQuotes(final String value) {
171        String returnValue = value;
172        if (value.startsWith(QUOTE_STRING) && value.endsWith(QUOTE_STRING)) {
173            returnValue = value.substring(1, value.length() - 1);
174        }
175        return returnValue;
176    }
177}