001/*
002 * $Id: AbstractOption.java,v 1.7 2011/03/24 16:06:34 davep Exp $
003 *
004 * This file is part of McIDAS-V
005 *
006 * Copyright 2007-2011
007 * Space Science and Engineering Center (SSEC)
008 * University of Wisconsin - Madison
009 * 1225 W. Dayton Street, Madison, WI 53706, USA
010 * https://www.ssec.wisc.edu/mcidas
011 * 
012 * All Rights Reserved
013 * 
014 * McIDAS-V is built on Unidata's IDV and SSEC's VisAD libraries, and
015 * some McIDAS-V source code is based on IDV and VisAD source code.  
016 * 
017 * McIDAS-V is free software; you can redistribute it and/or modify
018 * it under the terms of the GNU Lesser Public License as published by
019 * the Free Software Foundation; either version 3 of the License, or
020 * (at your option) any later version.
021 * 
022 * McIDAS-V is distributed in the hope that it will be useful,
023 * but WITHOUT ANY WARRANTY; without even the implied warranty of
024 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
025 * GNU Lesser Public License for more details.
026 * 
027 * You should have received a copy of the GNU Lesser Public License
028 * along with this program.  If not, see http://www.gnu.org/licenses.
029 */
030
031package edu.wisc.ssec.mcidasv.startupmanager.options;
032
033import javax.swing.JCheckBox;
034import javax.swing.JComponent;
035import javax.swing.JTextField;
036
037import edu.wisc.ssec.mcidasv.startupmanager.StartupManager;
038import edu.wisc.ssec.mcidasv.startupmanager.options.OptionMaster.OptionPlatform;
039import edu.wisc.ssec.mcidasv.startupmanager.options.OptionMaster.Type;
040import edu.wisc.ssec.mcidasv.startupmanager.options.OptionMaster.Visibility;
041
042public abstract class AbstractOption implements Option {
043
044    /**
045     * A unique identifier for an option. Should be the same as the 
046     * startup variable name found in the startup preference file.
047     */
048    private final String optionId;
049
050    /** 
051     * Brief description of the option. It will appear as the option's 
052     * label in the GUI.
053     */
054    private final String label;
055
056    /** @see Type */
057    private final Type optionType;
058
059    /** @see OptionPlatform */
060    private final OptionPlatform optionPlatform;
061
062    /** @see Visibility */
063    private final Visibility optionVisibility;
064
065    /**
066     * Creates an option that can hold a specified sort of data and that
067     * applies to a given platform.
068     * 
069     * @param id ID used to refer to this option.
070     * @param label Text that'll be used as the GUI label for this option
071     * @param optionType Type of data this option will represent.
072     * @param optionPlatform Platform(s) where this option is applicable.
073     * @param optionVisibility Visibility behavior of this option.
074     */
075    public AbstractOption(final String id, final String label, 
076        final Type optionType, final OptionPlatform optionPlatform, 
077        final Visibility optionVisibility) 
078    {
079        this.optionId = id;
080        this.label = label;
081        this.optionType = optionType;
082        this.optionPlatform = optionPlatform;
083        this.optionVisibility = optionVisibility;
084    }
085
086    /**
087     * Determines if the option applies to the current platform.
088     * 
089     * @return {@code true} if this option is applicable, {@code false} 
090     * otherwise.
091     */
092    protected boolean onValidPlatform() {
093        OptionPlatform platform = getOptionPlatform();
094        if (platform == OptionPlatform.ALL)
095            return true;
096        if (platform == OptionMaster.INSTANCE.convertToOptionPlatform())
097            return true;
098        return false;
099    }
100
101    /**
102     * Tests the specified string to see if it's valid for the current 
103     * platform. Currently strings that contain {@literal "SET "} 
104     * <b>[ note the space ]</b> are considered to be Windows-only, while 
105     * strings lacking {@literal "SET "} are considered Unix-like.
106     * 
107     * @param text The string to test.
108     * 
109     * @return Whether or not the string is valid.
110     */
111    private boolean isValidPrefFormat(final String text) {
112        assert text != null;
113        boolean hasSet = text.contains("SET ");
114        boolean isWin = (StartupManager.INSTANCE.getPlatform() == StartupManager.Platform.WINDOWS);
115        return (isWin == hasSet);
116    }
117
118    /**
119     * Returns this option's type.
120     * 
121     * @return The option's type.
122     * 
123     * @see Type
124     */
125    public Type getOptionType() {
126        return optionType;
127    }
128
129    /**
130     * Returns the platform(s) to which this option applies.
131     * 
132     * @return The option's platform.
133     * 
134     * @see OptionPlatform
135     */
136    public OptionPlatform getOptionPlatform() {
137        return optionPlatform;
138    }
139
140    /**
141     * Returns whether or not this option represents a visible UI element.
142     * 
143     * @return The option's visibility.
144     * 
145     * @see Visibility
146     */
147    public Visibility getOptionVisibility() {
148        return optionVisibility;
149    }
150
151    /**
152     * Returns the ID used when referring to this option.
153     * 
154     * @return The option's ID.
155     */
156    public String getOptionId() {
157        return optionId;
158    }
159
160    /**
161     * Returns a brief description of this option. Mostly useful for 
162     * providing a GUI label.
163     * 
164     * @return The option's label.
165     */
166    public String getLabel() {
167        return label;
168    }
169
170    /**
171     * Initializes the current option using a relevant variable from the 
172     * startup script.
173     * 
174     * @param text Line from the startup script that represents the current
175     * option.
176     * 
177     * @throws IllegalArgumentException if {@code text} is not in the proper
178     * format for the current platform.
179     */
180    public void fromPrefsFormat(final String text) {
181        if (!isValidPrefFormat(text))
182            throw new IllegalArgumentException("Incorrect syntax for this platform: " + text);
183
184        String copy = new String(text);
185        if (StartupManager.INSTANCE.getPlatform() == StartupManager.Platform.WINDOWS)
186            copy = copy.replace("SET ", "");
187
188        String[] chunks = copy.split("=");
189        if (chunks.length == 2 && chunks[0].equals(optionId))
190            setValue(chunks[1]);
191        else
192            setValue("");
193    }
194
195    /**
196     * Returns a string representation of the current option that is suitable 
197     * for use in the startup script.
198     * 
199     * @return Current value of this option as a startup script variable. The 
200     * formatting changes slightly between {@literal "Unix-like"} platforms 
201     * and Windows.
202     * 
203     * @see #isValidPrefFormat(String)
204     */
205    public String toPrefsFormat() {
206        StringBuilder str = new StringBuilder(optionId);
207        String value = getValue();
208        if (StartupManager.INSTANCE.getPlatform() == 
209            StartupManager.Platform.WINDOWS) 
210        {
211            str.insert(0, "SET ");
212        }
213
214        return str.append("=").append(value).toString();
215    }
216
217    /**
218     * Returns the GUI component that represents the option. 
219     * {@link BooleanOption}s are represented by a {@link JCheckBox}, while
220     * {@link TextOption}s appear as a {@link JTextField}.
221     * 
222     * @return The GUI representation of this option.
223     */
224    public abstract JComponent getComponent();
225
226    /**
227     * Returns the value of the option. Note that {@link BooleanOption}s
228     * return either "0" or "1".
229     * 
230     * @return The current value of the option.
231     */
232    public abstract String getValue();
233
234    /**
235     * Forces the value of the option to the data specified. Note that 
236     * {@link BooleanOption}s accept either "0", or "1".
237     * 
238     * @param value New value to use.
239     */
240    public abstract void setValue(final String value);
241
242    /**
243     * Friendly string representation of the option.
244     * 
245     * @return String containing relevant info about the option.
246     * 
247     * @see TextOption#toString()
248     * @see BooleanOption#toString()
249     */
250    public abstract String toString();
251}