001/*
002 * This file is part of McIDAS-V
003 *
004 * Copyright 2007-2023
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 */
028
029package edu.wisc.ssec.mcidasv.chooser.adde;
030
031import static javax.swing.GroupLayout.DEFAULT_SIZE;
032import static javax.swing.GroupLayout.PREFERRED_SIZE;
033import static javax.swing.GroupLayout.Alignment.BASELINE;
034import static javax.swing.GroupLayout.Alignment.LEADING;
035import static javax.swing.LayoutStyle.ComponentPlacement.RELATED;
036
037import java.awt.event.ItemEvent;
038import java.awt.event.ItemListener;
039import java.util.Hashtable;
040import java.util.List;
041
042import javax.swing.GroupLayout;
043import javax.swing.JCheckBox;
044import javax.swing.JComponent;
045import javax.swing.JLabel;
046import javax.swing.JPanel;
047
048import org.w3c.dom.Element;
049
050import edu.wisc.ssec.mcidas.AreaDirectory;
051
052import ucar.unidata.data.imagery.BandInfo;
053import ucar.unidata.idv.chooser.IdvChooserManager;
054import ucar.unidata.util.TwoFacedObject;
055import ucar.unidata.xml.XmlObjectStore;
056
057import edu.wisc.ssec.mcidasv.Constants;
058import edu.wisc.ssec.mcidasv.util.McVGuiUtils;
059
060
061/**
062 * Widget to select images from a remote ADDE server
063 * Displays a list of the descriptors (names) of the image datasets
064 * available for a particular ADDE group on the remote server.
065 *
066 * @author Don Murray
067 */
068public class AddeImageParameterChooser extends AddeImageChooser implements Constants {
069
070    /**
071     * Public keys for server, group, dataset, user, project.
072     */
073    public final static String SIZE_KEY = "size";
074    public final static String BAND_KEY = "band";
075    public final static String PLACE_KEY = "place";
076    public final static String LATLON_KEY = "latlon";
077    public final static String LINELE_KEY = "linele";
078    public final static String MAG_KEY = "mag";
079    public final static String UNIT_KEY = "unit";
080    public final static String PREVIEW_KEY = "preview";
081    public final static String NAVIGATION_KEY = "navigation";
082
083    /** Property for image default value unit */
084    protected static final String PROP_NAV = "NAV";
085
086    /** Property for image default value unit */
087    protected static final String PROP_UNIT = "UNIT";
088
089    /** Property for image default value band */
090    protected static final String PROP_BAND = "BAND";
091
092    /** Xml attr name for the defaults */
093    private static final String ATTR_NAV = "NAV";
094    private static final String ATTR_UNIT = "UNIT";
095    private static final String ATTR_BAND = "BAND";
096    private static final String ATTR_PLACE = "PLACE";
097    private static final String ATTR_SIZE = "SIZE";
098    private static final String ATTR_MAG = "MAG";
099    private static final String ATTR_LATLON = "LATLON";
100    private static final String ATTR_LINELE = "LINELE";
101
102    /** string for ALL */
103    private static final String ALL = "ALL";
104
105    private static JCheckBox previewBox = null;
106
107    /**
108     * Construct an Adde image selection widget
109     *
110     *
111     * @param mgr The chooser manager
112     * @param root The chooser.xml node
113     */
114    public AddeImageParameterChooser(IdvChooserManager mgr, Element root) {
115        super(mgr, root);
116        //DAVEP: Hiding parameter set picker for now... revisit after 1.0
117//        showParameterButton();
118    }
119    
120    /**
121     * Return the parameter type associated with this chooser.  Override!
122     */
123    @Override protected String getParameterSetType() {
124        return "addeimagery";
125    }
126    
127    /**
128     * Return the data source ID.  Used by extending classes.
129     */
130    @Override protected String getDataSourceId() {
131        return "ADDE.IMAGE.V";
132    }
133
134    /**
135     * Restore the selected parameter set using element attributes.
136     *
137     * @param restoreElement {@code Element} with the desired attributes.
138     * {@code null} values are permitted.
139     *
140     * @return {@code true} if the parameter set was restored, {@code false}
141     * otherwise.
142     */
143    @Override protected boolean restoreParameterSet(Element restoreElement) {
144        boolean okay = super.restoreParameterSet(restoreElement);
145        if (!okay) return okay;
146        
147        // Imagery specific restore
148        
149        // Restore nav
150        if (restoreElement.hasAttribute(ATTR_NAV)) {
151            String nav = restoreElement.getAttribute(ATTR_NAV);
152            TwoFacedObject tfo = new TwoFacedObject("Default", "X");
153            navComboBox.setSelectedItem((Object)tfo);
154            if (nav.toUpperCase().equals("LALO")) {
155                tfo = new TwoFacedObject("Lat/Lon", "LALO");
156            }
157            navComboBox.setSelectedItem((Object)tfo);
158        }
159        return true;
160    }
161    
162    /**
163     * Get the list of BandInfos for the current selected images
164     * @return list of BandInfos
165     */
166    public List<BandInfo> getSelectedBandInfos() {
167        return super.getBandInfos();
168    }
169
170    /**
171     * Get the value for the given property. This can either be the value
172     * supplied by the end user through the advanced GUI or is the default
173     *
174     * @param prop The property
175     * @param ad The AreaDirectory
176     *
177     * @return The value of the property to use in the request string
178     */
179    @Override protected String getPropValue(String prop, AreaDirectory ad) {
180        String propValue = super.getPropValue(prop, ad);
181        if (prop.equals(PROP_NAV)) {
182            propValue = TwoFacedObject.getIdString(navComboBox.getSelectedItem());
183        }
184        return propValue;
185    }
186
187    /**
188     * Get the default value for a key
189     *
190     * @param property property (key type)
191     * @param dflt default value
192     *
193     * @return Value for key or dflt if not found.
194     */
195    @Override protected String getDefault(String property, String dflt) {
196        String paramDefault = super.getDefault(property, dflt);
197        if (property.equals(PROP_NAV)) {
198            if (restoreElement != null) {
199                paramDefault = restoreElement.getAttribute(ATTR_NAV);
200            }
201        } else if (property.equals(PROP_UNIT)) {
202            paramDefault = "";
203        } else if (property.equals(PROP_BAND)) {
204            paramDefault = ALL;
205        } else if (property.equals(PROP_PLACE)) {
206            paramDefault = "";
207        }
208        return paramDefault;
209    }
210    
211    /**
212     * Get the DataSource properties
213     * 
214     * @param ht
215     *            Hashtable of properties
216     */
217    @Override
218    protected void getDataSourceProperties(Hashtable ht) {
219        super.getDataSourceProperties(ht);
220        if (restoreElement != null) {
221            if (restoreElement.hasAttribute(ATTR_BAND)) {
222                ht.put(BAND_KEY, (Object)(restoreElement.getAttribute(ATTR_BAND)));
223            }
224            if (restoreElement.hasAttribute(ATTR_LATLON)) {
225                ht.put(LATLON_KEY, (Object)(restoreElement.getAttribute(ATTR_LATLON)));
226            }
227            if (restoreElement.hasAttribute(ATTR_LINELE)) {
228                ht.put(LINELE_KEY, (Object)(restoreElement.getAttribute(ATTR_LINELE)));
229            }
230            if (restoreElement.hasAttribute(ATTR_MAG)) {
231                ht.put(MAG_KEY, (Object)(restoreElement.getAttribute(ATTR_MAG)));
232            }
233            if (restoreElement.hasAttribute(ATTR_PLACE)) {
234                ht.put(PLACE_KEY, (Object)(restoreElement.getAttribute(ATTR_PLACE)));
235            }
236            if (restoreElement.hasAttribute(ATTR_SIZE)) {
237                ht.put(SIZE_KEY, (Object)(restoreElement.getAttribute(ATTR_SIZE)));
238            }
239            if (restoreElement.hasAttribute(ATTR_UNIT)) {
240                ht.put(UNIT_KEY, (Object)(restoreElement.getAttribute(ATTR_UNIT)));
241            }
242        } else {
243            ht.put(NAVIGATION_KEY, (Object)getPropValue(PROP_NAV, null));
244        }
245        ht.put(PREVIEW_KEY, (Object)previewBox.isSelected());
246    }
247    
248    /**
249     * Should we use the user supplied property
250     * 
251     * @param propId
252     *            The property
253     * 
254     * @return Should use the value from the advanced widget
255     */
256    protected boolean usePropFromUser(String propId) {
257        boolean fromSuper = super.usePropFromUser(propId);
258        if (propId.equals(PROP_UNIT)) fromSuper = false;
259        else if (propId.equals(PROP_BAND)) fromSuper = false;
260        return fromSuper;
261    }
262    
263    /**
264     * Make the UI for this selector.
265     *
266     * @return The gui
267     */
268    @Override
269    public JComponent doMakeContents() {
270        JPanel myPanel = new JPanel();
271
272        JLabel timesLabel = McVGuiUtils.makeLabelRight("Times:");
273        addDescComp(timesLabel);
274
275        JPanel timesPanel = makeTimesPanel();
276        timesPanel.setBorder(javax.swing.BorderFactory.createEtchedBorder());
277        addDescComp(timesPanel);
278
279        JLabel navigationLabel = McVGuiUtils.makeLabelRight("Navigation:");
280        addDescComp(navigationLabel);
281
282        // Use processPropertyComponents to build combo boxes that we rely on
283        processPropertyComponents();
284        addDescComp(navComboBox);
285        McVGuiUtils.setComponentWidth(navComboBox, McVGuiUtils.Width.DOUBLE);
286
287        // Preview checkbox
288        JLabel previewLabel = McVGuiUtils.makeLabelRight("Preview:");
289        addDescComp(previewLabel);
290        XmlObjectStore store = getIdv().getStore();
291        previewBox = new JCheckBox("Create preview image", store.get(Constants.PREF_IMAGE_PREVIEW, true));
292        previewBox.setToolTipText("Creating preview images takes extra time and network bandwidth");
293        previewBox.addItemListener(new ItemListener() {
294            public void itemStateChanged(ItemEvent e) {
295                XmlObjectStore store = getIdv().getStore();
296                store.put(Constants.PREF_IMAGE_PREVIEW, previewBox.isSelected());
297                store.save();
298            }
299        });
300        addDescComp(previewBox);
301
302        GroupLayout layout = new GroupLayout(myPanel);
303        myPanel.setLayout(layout);
304        layout.setHorizontalGroup(
305                layout.createParallelGroup(LEADING)
306                .addGroup(layout.createSequentialGroup()
307                        .addGroup(layout.createParallelGroup(LEADING)
308                                .addGroup(layout.createSequentialGroup()
309                                        .addComponent(descriptorLabel)
310                                        .addGap(GAP_RELATED)
311                                        .addComponent(descriptorComboBox))
312                                        .addGroup(layout.createSequentialGroup()
313                                                .addComponent(timesLabel)
314                                                .addGap(GAP_RELATED)
315                                                .addComponent(timesPanel, PREFERRED_SIZE, DEFAULT_SIZE, Short.MAX_VALUE))
316                                                .addGroup(layout.createSequentialGroup()
317                                                        .addComponent(navigationLabel)
318                                                        .addGap(GAP_RELATED)
319                                                        .addComponent(navComboBox))
320                                                        .addGroup(layout.createSequentialGroup()
321                                                                .addComponent(previewLabel)
322                                                                .addGap(GAP_RELATED)
323                                                                .addComponent(previewBox))))
324        );
325        layout.setVerticalGroup(
326                layout.createParallelGroup(LEADING)
327                .addGroup(layout.createSequentialGroup()
328                        .addGroup(layout.createParallelGroup(BASELINE)
329                                .addComponent(descriptorLabel)
330                                .addComponent(descriptorComboBox))
331                                .addPreferredGap(RELATED)
332                                .addGroup(layout.createParallelGroup(LEADING)
333                                        .addComponent(timesLabel)
334                                        .addComponent(timesPanel, PREFERRED_SIZE, DEFAULT_SIZE, Short.MAX_VALUE))
335                                        .addPreferredGap(RELATED)
336                                        .addGroup(layout.createParallelGroup(LEADING)
337                                                .addComponent(navigationLabel)
338                                                .addComponent(navComboBox))
339                                                .addGroup(layout.createParallelGroup(LEADING)
340                                                        .addComponent(previewLabel)
341                                                        .addComponent(previewBox)))
342        );
343        
344        setInnerPanel(myPanel);
345        return super.doMakeContents(true);
346    }
347
348}