001/*
002 * $Id: PolarOrbitTrackChooser.java,v 1.3 2011/03/24 16:06:31 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.chooser;
032
033import static javax.swing.GroupLayout.DEFAULT_SIZE;
034import static javax.swing.GroupLayout.Alignment.BASELINE;
035import static javax.swing.GroupLayout.Alignment.LEADING;
036import static javax.swing.GroupLayout.Alignment.TRAILING;
037import static javax.swing.LayoutStyle.ComponentPlacement.RELATED;
038import static javax.swing.LayoutStyle.ComponentPlacement.UNRELATED;
039
040import java.awt.Dimension;
041import java.awt.Graphics;
042import java.awt.event.ActionEvent;
043import java.awt.event.ActionListener;
044import java.awt.event.ItemEvent;
045import java.awt.event.ItemListener;
046import java.awt.event.KeyEvent;
047import java.awt.event.KeyListener;
048import java.text.SimpleDateFormat;
049import java.util.ArrayList;
050import java.util.Arrays;
051import java.util.Collections;
052import java.util.Enumeration;
053import java.util.Hashtable;
054import java.util.List;
055import java.util.Map;
056import java.util.Vector;
057
058import javax.swing.GroupLayout;
059import javax.swing.JButton;
060import javax.swing.JCheckBox;
061import javax.swing.JComboBox;
062import javax.swing.JComponent;
063import javax.swing.JLabel;
064import javax.swing.JPanel;
065import javax.swing.JRadioButton;
066import javax.swing.JTabbedPane;
067import javax.swing.JTextField;
068
069import org.w3c.dom.Element;
070
071import ucar.unidata.data.imagery.AddeImageDescriptor;
072import ucar.unidata.data.imagery.AddeImageInfo;
073import ucar.unidata.data.imagery.BandInfo;
074import ucar.unidata.data.imagery.ImageDataSource;
075import ucar.unidata.data.imagery.ImageDataset;
076import ucar.unidata.idv.IdvResourceManager;
077import ucar.unidata.idv.chooser.adde.AddeServer;
078import ucar.unidata.idv.chooser.adde.AddeServer.Group;
079import ucar.unidata.idv.chooser.IdvChooserManager;
080import ucar.unidata.ui.ChooserList;
081import ucar.unidata.util.GuiUtils;
082import ucar.unidata.util.Misc;
083import ucar.unidata.util.PreferenceList;
084import ucar.unidata.util.StringUtil;
085import ucar.unidata.util.TwoFacedObject;
086import ucar.unidata.xml.XmlNodeList;
087import ucar.unidata.xml.XmlObjectStore;
088import ucar.unidata.xml.XmlResourceCollection;
089import ucar.unidata.xml.XmlUtil;
090import ucar.visad.UtcDate;
091import visad.DateTime;
092import visad.Gridded1DSet;
093import visad.VisADException;
094import edu.wisc.ssec.mcidas.AreaDirectory;
095import edu.wisc.ssec.mcidas.AreaDirectoryList;
096import edu.wisc.ssec.mcidas.McIDASException;
097import edu.wisc.ssec.mcidas.adde.AddeSatBands;
098import edu.wisc.ssec.mcidas.adde.AddeURL;
099import edu.wisc.ssec.mcidas.adde.DataSetInfo;
100import edu.wisc.ssec.mcidasv.Constants;
101import edu.wisc.ssec.mcidasv.McIDASV;
102import edu.wisc.ssec.mcidasv.chooser.adde.AddeChooser;
103import edu.wisc.ssec.mcidasv.servermanager.EntryTransforms;
104import edu.wisc.ssec.mcidasv.servermanager.AddeEntry.EntryType;
105import edu.wisc.ssec.mcidasv.servermanager.EntryStore;
106import edu.wisc.ssec.mcidasv.util.CollectionHelpers;
107import edu.wisc.ssec.mcidasv.util.McVGuiUtils;
108import edu.wisc.ssec.mcidasv.util.McVGuiUtils.Position;
109import edu.wisc.ssec.mcidasv.util.McVGuiUtils.TextColor;
110import edu.wisc.ssec.mcidasv.util.McVGuiUtils.Width;
111import static edu.wisc.ssec.mcidasv.util.CollectionHelpers.arrList;
112
113
114/**
115 * Widget to select images from a remote ADDE server
116 * Displays a list of the descriptors (names) of the image datasets
117 * available for a particular ADDE group on the remote server.
118 *
119 * @author Don Murray
120 */
121public class PolarOrbitTrackChooser extends AddeChooser implements Constants {
122
123    /** Connect button--we need to be able to disable this */
124    JButton connectButton = McVGuiUtils.makeImageTextButton(ICON_CONNECT_SMALL, "Connect");
125
126    /** Manage button */
127    JButton manageButton =
128        McVGuiUtils.makeImageButton("/edu/wisc/ssec/mcidasv/resources/icons/toolbar/preferences-system22.png",
129            this, "doManager", null, "Manage servers");
130
131    /** Public button--we need to draw a menu from this */
132    JButton publicButton =
133        McVGuiUtils.makeImageButton("/edu/wisc/ssec/mcidasv/resources/icons/toolbar/show-layer-controls22.png",
134            this, "showGroups", null, "List public datasets");
135
136    private JComboBox serverSelector;
137    private JRadioButton addeBtn;
138    private JRadioButton urlBtn;
139    List addeList = new ArrayList();
140    List urlList = new ArrayList();
141
142    /** Manages the pull down list of urls */
143    private PreferenceList prefList;
144
145    /** The list of urls */
146    private JComboBox box;
147    private JTextField boxEditor;
148
149    /** text type */
150    private static final String TLE_TYPE = "text";
151
152    /** Property name to get the list or urls */
153    public static final String PREF_URLLIST = "idv.urllist";
154
155    /**
156     * Property for the tle server name key.
157     * @see #getServer()
158     */
159    public static String TLE_SERVER_NAME_KEY = "tle_server";
160    public static String URL_NAME_KEY = "url_name";
161
162    /**
163     * Property for the tle group name key.
164     * @see #getGroup()
165     */
166    public static String TLE_GROUP_NAME_KEY = "tle_group";
167
168    /**
169     * Property for the tle user id
170     */
171    public static String TLE_USER_ID_KEY = "tle_user";
172
173    /**
174     * Property for the tle project number
175     */
176    public static String TLE_PROJECT_NUMBER_KEY = "tle_proj";
177
178    /**
179     * Construct an Adde image selection widget
180     *
181     *
182     * @param mgr The chooser manager
183     * @param root The chooser.xml node
184     */
185    public PolarOrbitTrackChooser(IdvChooserManager mgr, Element root) {
186        super(mgr, root);
187        serverSelector = getServerSelector();
188        showServers();
189    }
190    
191        /**
192         * Return the data source ID.  Used by extending classes.
193         */
194    @Override
195        protected String getDataSourceId() {
196                return "ADDE.TLE.V";
197        }
198    
199    /**
200     * Make the UI for this selector.
201     *
202     * @return The gui
203     */
204    @Override
205    public JComponent doMakeContents() {
206        JPanel outerPanel = new JPanel();
207        JPanel addePanel = new JPanel();
208        JPanel urlPanel = new JPanel();
209
210        addeBtn = new JRadioButton("ADDE", true);
211        urlBtn = new JRadioButton("URL", false);
212        GuiUtils.buttonGroup(addeBtn, urlBtn);
213        addeBtn.addActionListener(new ActionListener() {
214            public void actionPerformed(ActionEvent e) {
215                for (int i=0; i<7; i++) {
216                    JComponent comp = (JComponent)(addeList.get(i));
217                    comp.setEnabled(true);
218                }
219                for (int i=0; i<2; i++) {
220                    JComponent comp = (JComponent)(urlList.get(i));
221                    comp.setEnabled(false);
222                }
223            }
224        });
225        urlBtn.addActionListener(new ActionListener() {
226            public void actionPerformed(ActionEvent e) {
227                for (int i=0; i<2; i++) {
228                    JComponent comp = (JComponent)(urlList.get(i));
229                    comp.setEnabled(true);
230                }
231                loadButton.setEnabled(true);
232                for (int i=0; i<7; i++) {
233                    JComponent comp = (JComponent)(addeList.get(i));
234                    comp.setEnabled(false);
235                }
236            }
237        });
238
239        addePanel =  (JPanel)makeAddePanel();
240        urlPanel =  (JPanel)makeUrlPanel();
241
242        JButton helpButton = McVGuiUtils.makeImageButton(ICON_HELP, "Show help");
243        helpButton.setActionCommand(GuiUtils.CMD_HELP);
244        helpButton.addActionListener(this);
245
246        JButton refreshButton = McVGuiUtils.makeImageButton(ICON_REFRESH, "Refresh");
247        refreshButton.setActionCommand(GuiUtils.CMD_UPDATE);
248        refreshButton.addActionListener(this);
249
250        McVGuiUtils.setComponentWidth(loadButton, Width.DOUBLE);
251
252        GroupLayout layout = new GroupLayout(outerPanel);
253        outerPanel.setLayout(layout);
254        layout.setHorizontalGroup(
255            layout.createParallelGroup(LEADING)
256            .addGroup(TRAILING, layout.createSequentialGroup()
257                .addGroup(layout.createParallelGroup(TRAILING)
258                    .addGroup(layout.createSequentialGroup()
259                        .addContainerGap()
260                        .addComponent(helpButton)
261                        .addGap(GAP_RELATED)
262                        .addComponent(refreshButton)
263                        .addGap(GAP_RELATED)
264                        .addComponent(cancelButton)
265                        .addPreferredGap(RELATED)
266                        .addComponent(loadButton))
267                        .addGroup(LEADING, layout.createSequentialGroup()
268                        .addContainerGap()
269                        .addGroup(layout.createParallelGroup(LEADING)
270                            .addComponent(addeBtn)
271                            .addComponent(addePanel, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE)
272                            .addComponent(urlBtn)
273                            .addComponent(urlPanel, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE))
274                        .addGroup(layout.createSequentialGroup()))) 
275                .addContainerGap())
276        );
277        layout.setVerticalGroup(
278            layout.createParallelGroup(LEADING)
279            .addGroup(layout.createSequentialGroup()
280                .addContainerGap()
281                .addComponent(addeBtn)
282                .addComponent(addePanel, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE)
283                .addPreferredGap(UNRELATED)
284                .addComponent(urlBtn)
285                .addComponent(urlPanel, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE)
286                .addPreferredGap(UNRELATED)
287                .addPreferredGap(UNRELATED)
288                .addGroup(layout.createParallelGroup(BASELINE)
289                    .addComponent(loadButton)
290                    .addComponent(cancelButton)
291                    .addComponent(refreshButton)
292                    .addComponent(helpButton))
293                .addContainerGap())
294        );
295
296        return outerPanel;
297    }
298
299    private JComponent makeAddePanel() {
300        JPanel outerPanel = new JPanel();
301
302        JLabel serverLabel = new JLabel("Server:");
303
304        clearOnChange(serverSelector);
305        McVGuiUtils.setComponentWidth(serverSelector, Width.DOUBLE);
306
307        JLabel groupLabel = McVGuiUtils.makeLabelRight("Dataset:");
308
309        groupSelector.setEditable(isGroupEditable());
310        clearOnChange(groupSelector);
311        McVGuiUtils.setComponentWidth(groupSelector, Width.DOUBLE);
312
313        McVGuiUtils.setComponentWidth(connectButton, Width.DOUBLE);
314        connectButton.setActionCommand(CMD_CONNECT);
315        connectButton.addActionListener(this);
316
317        GroupLayout layout = new GroupLayout(outerPanel);
318        outerPanel.setLayout(layout);
319        layout.setHorizontalGroup(
320            layout.createParallelGroup(LEADING)
321            .addGroup(TRAILING, layout.createSequentialGroup()
322                .addGroup(layout.createParallelGroup(TRAILING)
323                        .addGroup(LEADING, layout.createSequentialGroup()
324                        .addContainerGap()
325                        .addGroup(layout.createParallelGroup(LEADING)
326                        .addGroup(layout.createSequentialGroup()
327                            .addComponent(serverLabel)
328                            .addGap(GAP_RELATED)
329                            .addComponent(serverSelector)
330                            .addGap(GAP_RELATED)
331                            .addComponent(manageButton)
332                            .addGap(GAP_RELATED)
333                            .addComponent(groupLabel)
334                            .addGap(GAP_RELATED)
335                            .addComponent(groupSelector)
336                            .addGap(GAP_RELATED)
337                            .addComponent(publicButton)
338                            .addPreferredGap(RELATED, DEFAULT_SIZE, Short.MAX_VALUE)
339                            .addComponent(connectButton))
340                        .addGroup(layout.createSequentialGroup()
341                            .addComponent(descriptorLabel)
342                            .addGap(GAP_RELATED)
343                            .addComponent(descriptorComboBox)))))
344                    .addContainerGap())
345        );
346
347        layout.setVerticalGroup(
348            layout.createParallelGroup(LEADING)
349            .addGroup(layout.createSequentialGroup()
350                .addContainerGap()
351                .addGroup(layout.createParallelGroup(BASELINE)
352                    .addComponent(serverLabel)
353                    .addComponent(serverSelector)
354                    .addComponent(manageButton)
355                    .addComponent(groupLabel)
356                    .addComponent(groupSelector)
357                    .addComponent(publicButton)
358                    .addComponent(connectButton))
359                .addPreferredGap(UNRELATED)
360                .addGroup(layout.createParallelGroup(BASELINE)
361                    .addComponent(descriptorLabel)
362                    .addComponent(descriptorComboBox))
363                .addContainerGap())
364        );
365
366        addeList.add(serverLabel);
367        addeList.add(serverSelector);
368        addeList.add(groupLabel);
369        addeList.add(groupSelector);
370        addeList.add(connectButton);
371        addeList.add(descriptorLabel);
372        McVGuiUtils.setComponentWidth(descriptorComboBox, Width.DOUBLEDOUBLE);
373        addeList.add(descriptorComboBox);
374
375        return outerPanel;
376    }
377
378    private JComponent makeUrlPanel() {
379        JPanel urlPanel = new JPanel();
380        JLabel urlLabel = new JLabel("URL:");
381        McVGuiUtils.setLabelPosition(urlLabel, Position.RIGHT);
382
383        prefList = getPreferenceList(PREF_URLLIST);
384        box = prefList.createComboBox(CMD_LOAD, this);
385        boxEditor = (JTextField)box.getEditor().getEditorComponent();
386        boxEditor.addKeyListener(new KeyListener() {
387            public void keyPressed(KeyEvent e) {}
388            public void keyReleased(KeyEvent e) {
389            }
390            public void keyTyped(KeyEvent e) {}
391        });
392        urlLabel.setEnabled(false);
393        box.setEnabled(false);
394        urlList.add(urlLabel);
395        urlList.add(box);
396        urlPanel = GuiUtils.top(box);
397        JPanel retPanel = McVGuiUtils.makeLabeledComponent(urlLabel, urlPanel);
398
399        return retPanel;
400    }
401
402
403    /**
404     * Update labels, enable widgets, etc.
405     */
406    protected void updateStatus() {
407        super.updateStatus();
408        enableWidgets();
409    }
410
411    /**
412     * Get the data type ID
413     *
414     * @return  the data type
415     */
416
417    public String getDataType() {
418        return "TEXT";
419    }
420
421    /**
422      * get the adde server grup type to use
423      *
424      * @return group type
425      */
426    @Override
427    protected String getGroupType() {
428            return TLE_TYPE;
429    }
430
431    /**
432     * User said go, we go. 
433     * Create the ADDE.TLE.V DataSource
434     * 
435     */
436    public void doLoadInThread() {
437        String obj = "TLE";
438        prefList.saveState(box);
439        Hashtable ht = new Hashtable();
440        getDataSourceProperties(ht);
441        makeDataSource(obj, getDataSourceId(), ht);
442        saveServerState();
443    }
444
445    /**
446     * Get the DataSource properties
447     * 
448     * @param ht
449     *            Hashtable of properties
450     */
451    protected void getDataSourceProperties(Hashtable ht) {
452        if (addeBtn.isSelected()) {
453            super.getDataSourceProperties(ht);
454            ht.put(DATASET_NAME_KEY, getDatasetName());
455            String server = getServer();
456            ht.put(TLE_SERVER_NAME_KEY, server);
457            String group = getGroup();
458            ht.put(TLE_GROUP_NAME_KEY, group);
459            Map<String, String> acct = getAccounting(server, group);
460            String user = acct.get("user");
461            String proj = acct.get("proj");
462            ht.put(TLE_USER_ID_KEY, user);
463            ht.put(TLE_PROJECT_NUMBER_KEY, proj);
464        } else {
465            ht.put(URL_NAME_KEY, box.getSelectedItem());
466        }
467    }
468
469    private String getDatasetName() {
470        return "TLE";
471    }
472}