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 */
028
029package edu.wisc.ssec.mcidasv.data;
030
031import static javax.swing.GroupLayout.Alignment.BASELINE;
032import static javax.swing.GroupLayout.Alignment.LEADING;
033import static javax.swing.LayoutStyle.ComponentPlacement.RELATED;
034import static javax.swing.LayoutStyle.ComponentPlacement.UNRELATED;
035
036import java.awt.Dimension;
037import java.rmi.RemoteException;
038import java.util.Calendar;
039import java.util.Date;
040
041import javax.swing.GroupLayout;
042import javax.swing.JComponent;
043import javax.swing.JLabel;
044import javax.swing.JPanel;
045import javax.swing.JTextField;
046
047import name.gano.astro.time.Time;
048
049import org.slf4j.Logger;
050import org.slf4j.LoggerFactory;
051
052import ucar.unidata.data.DataSelection;
053import ucar.unidata.data.DataSelectionComponent;
054import ucar.unidata.data.DataSourceImpl;
055
056import visad.VisADException;
057
058import edu.wisc.ssec.mcidasv.Constants;
059import edu.wisc.ssec.mcidasv.data.dateChooser.JCalendar;
060import edu.wisc.ssec.mcidasv.data.dateChooser.JDateChooser;
061import edu.wisc.ssec.mcidasv.data.dateChooser.JDayChooser;
062import edu.wisc.ssec.mcidasv.data.dateChooser.JMonthChooser;
063import edu.wisc.ssec.mcidasv.data.dateChooser.JYearChooser;
064
065public class TimeRangeSelection extends DataSelectionComponent implements Constants {
066
067      private static final Logger logger = LoggerFactory.getLogger(TimeRangeSelection.class);
068
069      private JTextField beginTimeFld;
070      private JTextField endTimeFld;
071      private String defaultBegTime = "00:00:00";
072      private String defaultEndTime = "23:59:59";
073      private Date defaultDay = null;
074
075      private JDateChooser begDay = null;
076      private JDateChooser endDay = null;
077
078      public static final String PROP_BEGTIME = "BeginTime";
079      public static final String PROP_ENDTIME = "EndTime";
080      protected static final String PROP_BTIME = "BTime";
081      protected static final String PROP_ETIME = "ETime";
082      protected static final String PROP_YEAR = "Year";
083      protected static final String PROP_MONTH = "Month";
084      protected static final String PROP_DAY = "Day";
085      protected static final String PROP_HOURS = "Hours";
086      protected static final String PROP_MINS = "Mins";
087      protected static final String PROP_SECS = "Secs";
088
089      private JPanel timeRangeComp = new JPanel();
090
091      public TimeRangeSelection(DataSourceImpl dataSource) 
092              throws VisADException, RemoteException {
093          super("Time Range");
094      }
095
096    protected JComponent doMakeContents() {
097
098        logger.debug("creating the TimeRangeSelection panel...");
099        JLabel begLab = new JLabel("  Begin");
100        JLabel endLab = new JLabel("  End");
101        JLabel begTimeLab = new JLabel("      Time:");
102        JLabel endTimeLab = new JLabel("      Time:");
103        JLabel begDateLab = new JLabel("      Date:");
104        JLabel endDateLab = new JLabel("      Date:");
105        beginTimeFld = new JTextField(defaultBegTime, 8);
106        beginTimeFld.setMaximumSize(new Dimension(80, 40));
107        endTimeFld = new JTextField(defaultEndTime, 8);
108        endTimeFld.setMaximumSize(new Dimension(80, 40));
109        Calendar cal = Calendar.getInstance();
110        defaultDay = cal.getTime();
111        begDay = new JDateChooser(defaultDay);
112        begDay.setMaximumSize(new Dimension(140, 20));
113        endDay = new JDateChooser(defaultDay);
114        endDay.setMaximumSize(new Dimension(140, 20));
115        
116        // make them listen to each other to maintain range validity (beg <= end) and vice versa
117        begDay.getJCalendar().getDayChooser().setName(JDayChooser.BEG_DAY);
118        endDay.getJCalendar().getDayChooser().setName(JDayChooser.END_DAY);
119        begDay.getJCalendar().getDayChooser().addPropertyChangeListener("day", endDay);
120        endDay.getJCalendar().getDayChooser().addPropertyChangeListener("day", begDay);
121
122        GroupLayout layout = new GroupLayout(timeRangeComp);
123        timeRangeComp.setLayout(layout);
124        layout.setHorizontalGroup(
125            layout.createParallelGroup(LEADING)
126                .addComponent(begLab)
127                .addGroup(layout.createSequentialGroup()
128                    .addComponent(begTimeLab)
129                    .addGap(GAP_RELATED)
130                    .addComponent(beginTimeFld))
131                .addGroup(layout.createSequentialGroup()
132                    .addComponent(begDateLab)
133                    .addGap(GAP_RELATED)
134                    .addComponent(begDay))
135                .addComponent(endLab)
136                .addGroup(layout.createSequentialGroup()
137                    .addComponent(endTimeLab)
138                    .addGap(GAP_RELATED)
139                    .addComponent(endTimeFld))
140                .addGroup(layout.createSequentialGroup()
141                    .addComponent(endDateLab)
142                    .addGap(GAP_RELATED)
143                    .addComponent(endDay))
144         );
145
146        layout.setVerticalGroup(
147            layout.createParallelGroup(LEADING)
148            .addGroup(layout.createSequentialGroup()
149                .addComponent(begLab)
150                .addGroup(layout.createParallelGroup(BASELINE)
151                    .addComponent(begTimeLab)
152                    .addComponent(beginTimeFld))
153                .addPreferredGap(RELATED)
154                .addGroup(layout.createParallelGroup(BASELINE)
155                    .addComponent(begDateLab)
156                    .addComponent(begDay))
157                .addPreferredGap(UNRELATED)
158                .addComponent(endLab)
159                .addGroup(layout.createParallelGroup(BASELINE)
160                    .addComponent(endTimeLab)
161                    .addComponent(endTimeFld))
162                .addPreferredGap(RELATED)
163                .addGroup(layout.createParallelGroup(BASELINE)
164                    .addComponent(endDateLab)
165                    .addComponent(endDay)))
166         );
167
168         return timeRangeComp;
169    }
170
171    protected JComponent getTimeRangeComponent() {
172        return timeRangeComp;
173    }
174
175    public boolean begTimeOk() {
176        String begTime = beginTimeFld.getText();
177        String[] timeStrings = begTime.split(":");
178        int num = timeStrings.length;
179        if (num != 3) return false;
180        int hours = -1;
181        int mins = -1;
182        int secs = -1; 
183        try {
184                hours = Integer.parseInt(timeStrings[0]);
185                mins = Integer.parseInt(timeStrings[1]);
186                secs = Integer.parseInt(timeStrings[2]);
187        } catch (NumberFormatException nfe) {
188                return false;
189        }
190        if ((hours < 0) || (hours > 23)) return false;
191        if ((mins < 0) || (mins > 59)) return false;
192        if ((secs < 0) || (secs > 59)) return false;
193        return true;
194    }
195    
196    public boolean endTimeOk() {
197        String endTime = endTimeFld.getText();
198        String[] timeStrings = endTime.split(":");
199        int num = timeStrings.length;
200        if (num != 3) return false;
201        int hours = -1;
202        int mins = -1;
203        int secs = -1;
204        try {
205                hours = Integer.parseInt(timeStrings[0]);
206                mins = Integer.parseInt(timeStrings[1]);
207                secs = Integer.parseInt(timeStrings[2]);
208        } catch (NumberFormatException nfe) {
209                return false;
210        }
211        if ((hours < 0) || (hours > 23)) return false;
212        if ((mins < 0) || (mins > 59)) return false;
213        if ((secs < 0) || (secs > 59)) return false;
214        return true;
215    }
216    
217    /**
218     * TJJ Jun 2015
219     * Return the difference in seconds between the Calendar objects only!
220     * NOTE: this will only give you the number of days difference,
221     * the HH, MM, and SS data comes from a different UI widget.
222     * 
223     * We compute seconds simply because that is easiest way to get an
224     * absolute time from Date object
225     */
226    
227    public long getTimeRangeInSeconds() {
228        
229        // make sure our widgets are set with a valid end time greater
230        // than begin time
231        if (! timeRangeOk()) {
232                return -1;
233        }
234        
235        long endTimeMs = endDay.getDate().getTime();
236        long begTimeMs = begDay.getDate().getTime();
237        return (endTimeMs - begTimeMs) / 1000;
238        
239    }
240    
241    /**
242     * Make sure the end date/time exceeds the beginning date/time.
243     * 
244     * @return true if condition met, false otherwise
245     * 
246     */
247    
248    public boolean timeRangeOk() {
249        
250        if (! begTimeOk()) return false;
251        if (! endTimeOk()) return false;
252        
253        JCalendar cal = begDay.getJCalendar();
254        JDayChooser dayChooser = cal.getDayChooser();
255        int day = dayChooser.getDay();
256        JMonthChooser monthChooser = cal.getMonthChooser();
257        int month = monthChooser.getMonth() + 1;
258        JYearChooser yearChooser = cal.getYearChooser();
259        int year = yearChooser.getYear();
260
261        int hours = 0;
262        int mins = 0;
263        double secs = 0.0;
264        String begTime = beginTimeFld.getText();
265        String[] timeStrings = begTime.split(":");
266        int num = timeStrings.length;
267        if (num > 0)
268            hours = (new Integer(timeStrings[0])).intValue();
269        if (num > 1)
270            mins = (new Integer(timeStrings[1])).intValue();
271        if (num > 2)
272            secs = (new Integer(timeStrings[2])).intValue();
273
274        Time bTime = new Time(year, month, day, hours, mins, secs);
275
276        cal = endDay.getJCalendar();
277        dayChooser = cal.getDayChooser();
278        day = dayChooser.getDay();
279        monthChooser = cal.getMonthChooser();
280        month = monthChooser.getMonth() + 1;
281        yearChooser = cal.getYearChooser();
282        year = yearChooser.getYear();
283
284        String endTime = endTimeFld.getText();
285        timeStrings = endTime.split(":");
286        num = timeStrings.length;
287        if (num > 0)
288            hours = (new Integer(timeStrings[0])).intValue();
289        if (num > 1)
290            mins = (new Integer(timeStrings[1])).intValue();
291        if (num > 2)
292            secs = (new Integer(timeStrings[2])).intValue();
293
294        Time eTime = new Time(year, month, day, hours, mins, secs);
295        
296        if (eTime.getJulianDate() < bTime.getJulianDate()) {
297                return false;
298        }
299        return true;
300    }
301    
302    @Override public void applyToDataSelection(DataSelection dataSelection) {
303        
304        if (! begTimeOk()) return;
305        if (! endTimeOk()) return;
306        
307        if (dataSelection == null) {
308            dataSelection = new DataSelection(true);
309        }
310
311        JCalendar cal = begDay.getJCalendar();
312        JDayChooser dayChooser = cal.getDayChooser();
313        int day = dayChooser.getDay();
314        JMonthChooser monthChooser = cal.getMonthChooser();
315        int month = monthChooser.getMonth() + 1;
316        JYearChooser yearChooser = cal.getYearChooser();
317        int year = yearChooser.getYear();
318
319        int hours = 0;
320        int mins = 0;
321        double secs = 0.0;
322        String begTime = beginTimeFld.getText();
323        String[] timeStrings = begTime.split(":");
324        int num = timeStrings.length;
325        if (num > 0)
326            hours = (new Integer(timeStrings[0])).intValue();
327        if (num > 1)
328            mins = (new Integer(timeStrings[1])).intValue();
329        if (num > 2)
330            secs = (new Integer(timeStrings[2])).intValue();
331        if ((hours < 0) || (hours > 23)) hours = 0;
332        if ((mins < 0) || (mins > 59)) mins = 0;
333        if ((secs < 0.0) || (secs > 59.0)) secs = 0.0;
334
335        Time bTime = new Time(year, month, day, hours, mins, secs);
336        double dVal = bTime.getJulianDate();
337        Double bigD = new Double(dVal);
338        String begTimeStr = bigD.toString();
339        dataSelection.putProperty(PROP_BEGTIME, bTime.getDateTimeStr());
340
341        Integer intVal = new Integer(year);
342        dataSelection.putProperty(PROP_YEAR, intVal.toString());
343        intVal = new Integer(month);
344        dataSelection.putProperty(PROP_MONTH, intVal.toString());
345        intVal = new Integer(day);
346        dataSelection.putProperty(PROP_DAY, intVal.toString());
347        intVal = new Integer(hours);
348        dataSelection.putProperty(PROP_HOURS, intVal.toString());
349        intVal = new Integer(mins);
350        dataSelection.putProperty(PROP_MINS, intVal.toString());
351        Double doubleVal = new Double(secs);
352        dataSelection.putProperty(PROP_SECS, doubleVal.toString());
353
354        cal = endDay.getJCalendar();
355        dayChooser = cal.getDayChooser();
356        day = dayChooser.getDay();
357        monthChooser = cal.getMonthChooser();
358        month = monthChooser.getMonth() + 1;
359        yearChooser = cal.getYearChooser();
360        year = yearChooser.getYear();
361
362        String endTime = endTimeFld.getText();
363        timeStrings = endTime.split(":");
364        num = timeStrings.length;
365        if (num > 0)
366            hours = (new Integer(timeStrings[0])).intValue();
367        if (num > 1)
368            mins = (new Integer(timeStrings[1])).intValue();
369        if (num > 2)
370            secs = (new Integer(timeStrings[2])).intValue();
371        if ((hours < 0) || (hours > 23)) hours = 0;
372        if ((mins < 0) || (mins > 59)) mins = 0;
373        if ((secs < 0.0) || (secs > 59.0)) secs = 0.0;
374
375        Time eTime = new Time(year, month, day, hours, mins, secs);
376        dVal = eTime.getJulianDate();
377        bigD = new Double(dVal);
378        String endTimeStr = bigD.toString();
379
380        dataSelection.putProperty(PROP_ENDTIME, eTime.getDateTimeStr());
381        dataSelection.putProperty(PROP_BTIME, begTimeStr);
382        dataSelection.putProperty(PROP_ETIME, endTimeStr);
383        
384    }
385    
386}