1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License").  You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22/*
23 * ident	"%Z%%M%	%I%	%E% SMI"
24 *
25 * Copyright (c) 1999-2000 by Sun Microsystems, Inc.
26 * All rights reserved.
27 */
28
29    import java.awt.*;
30    import java.awt.event.*;
31    import java.text.NumberFormat;
32    import java.util.ResourceBundle;
33    import java.util.MissingResourceException;
34
35    /**
36     * This creates a modal dialog box that lets the user enter a duration of
37     * time in seconds/minutes/hours/days/weeks/months/years.
38     */
39    public class DurationHelper extends Dialog {
40
41	private boolean save;
42
43	private Frame parent;
44
45	private Choice unit;
46	private TextField value;
47	private Label  total;
48
49	private Button ok;
50	private Button cancel;
51	private Button help;
52	private Button compute;
53
54        private HelpDialog hd = null;
55
56	// For I18N
57	    private static ResourceBundle rb =
58	    ResourceBundle.getBundle("GuiResource" /* NOI18N */);
59            private static ResourceBundle hrb =
60	    ResourceBundle.getBundle("HelpData" /* NOI18N */);
61
62	private static String[] units = { getString("Seconds"),
63	            			getString("Minutes"),
64		    			getString("Hours"),
65		    			getString("Days"),
66		    			getString("Weeks"),
67		    			getString("Months"),
68		    			getString("Years")	};
69	private static int[] unitMultipliers = {1, 60, 60*60, 60*60*24,
70                                                60*60*24*7, 60*60*24*30,
71                                                60*60*24*365	};
72        private static NumberFormat nf = NumberFormat.getInstance();
73	private static Toolkit toolkit = Toolkit.getDefaultToolkit();
74
75        /**
76         * Constructor for DurationHelper.
77         * @param parent the parent Frame to whom input will be blocked
78         * while this dialog box is begin shown(modal behaviour).
79         */
80    public DurationHelper(Frame parent,  Color background, Color foreground) {
81		super(parent, getString("SEAM Duration Helper"), true);
82
83		this.parent = parent;
84
85		setLayout(new GridBagLayout());
86		addLabels();
87		addFields(background, foreground);
88		addButtons();
89		setSize(350, 150);
90		setResizable(false);
91		addWindowListener(new DHWindowListener());
92    }
93
94    /**
95     * Adds all the labels.
96     */
97    private void addLabels() {
98        GridBagConstraints gbc = new GridBagConstraints();
99	gbc.weightx = gbc.weighty = 1;
100	add(new Label(getString("Unit")), gbc);
101	add(new Label(getString("Value")), gbc);
102
103	gbc.gridx = 3;
104	gbc.gridy = 0;
105	add(new Label(getString("Seconds")), gbc);
106    }
107
108    /**
109     * Initializes the strings for the units.
110     */
111    private void initUnits() {
112        unit = new Choice();
113	for (int i = 0; i < units.length; i++)
114	    unit.add(units[i]);
115	unit.select(getString("Hours"));
116	unit.addItemListener(new ItemListener() {
117		public void itemStateChanged(ItemEvent e) {
118			DurationHelper.this.checkErrorAndSetTotal();
119		}
120	});
121    }
122
123    /**
124     * Adds all the fields
125     */
126    private void addFields(Color background, Color foreground) {
127        GridBagConstraints gbc = new GridBagConstraints();
128	gbc.weightx =  gbc.weighty = 1;
129	initUnits();
130	value = new TextField();
131	value.setBackground(background);
132	value.setForeground(foreground);
133	value.setColumns(10);
134
135        // TBD: make total large enough to hold the largest int
136        total = new Label("             " /* NO18N */,
137                            Label.RIGHT);
138	gbc.gridx = 0;
139	gbc.gridy = 1;
140	add(unit, gbc);
141	gbc.gridx = 1;
142	add(value, gbc);
143	gbc.gridx = 3;
144	add(total, gbc);
145
146	value.addActionListener(new ActionListener() {
147		public void actionPerformed(ActionEvent e) {
148			DurationHelper.this.durationHelperClose(true);
149		}
150	});
151    }
152
153    /**
154     * Adds all the buttons.
155     */
156    private void addButtons() {
157
158        GridBagConstraints gbc = new GridBagConstraints();
159	gbc.weightx =  gbc.weighty = 1;
160
161	gbc.gridwidth = GridBagConstraints.REMAINDER;
162	gbc.fill = GridBagConstraints.BOTH;
163	gbc.gridx = 0;
164	gbc.gridy = 2;
165	gbc.insets = new Insets(0, 10, 0, 10);
166	add(new LineSeparator(), gbc);
167	gbc.insets = new Insets(0, 0, 0, 0);
168
169	Panel p = new Panel();
170	p.setLayout(new GridBagLayout());
171	ok = new Button(getString("OK"));
172	cancel =  new Button(getString("Cancel"));
173	help = new Button(getString("Help"));
174	gbc = new GridBagConstraints();
175        gbc.weightx =  gbc.weighty = 1;
176	p.add(ok, gbc);
177	p.add(cancel, gbc);
178	p.add(help, gbc);
179
180	ActionListener bl = new ButtonListener();
181	ok.addActionListener(bl);
182	cancel.addActionListener(bl);
183	help.addActionListener(bl);
184
185	gbc.gridy = 3;
186	gbc.gridwidth = GridBagConstraints.REMAINDER;
187	gbc.fill = GridBagConstraints.HORIZONTAL;
188	add(p, gbc);
189
190	gbc = new GridBagConstraints();
191	gbc.gridx = 2;
192	gbc.gridy = 1;
193	compute = new Button(getString("="));
194	add(compute, gbc);
195	compute.addActionListener(bl);
196
197    }
198
199    /**
200     * Updates the label called total.
201     * @return false if the text entry in the value
202     * field is not parseable, true otherwise.
203     */
204    private boolean checkErrorAndSetTotal() {
205        try {
206            String noSpaces = value.getText().trim();
207	    value.setText(noSpaces);
208	    Long l = Long.valueOf(noSpaces);
209	    total.setText(nf.format(l.longValue() *
210                unitMultipliers[unit.getSelectedIndex()]));
211        } catch (NumberFormatException e) {
212          value.requestFocus();
213          value.selectAll();
214          toolkit.beep();
215	  return false;
216        }
217
218	return true;
219    }
220
221    /**
222     * Hides the duration helper.
223     * @param save true if the user wants to save the current value in
224     * the dialog box, false if it is to be discarded. This is decided
225     * based on whether the user clicked on the "Ok" button or the
226     * "Cancel" button. Choosing the window close menu is equivalent to
227     *  clicking on "Cancel."
228     */
229    private void durationHelperClose(boolean save) {
230        if (save == true) {
231	    if (!checkErrorAndSetTotal())
232		return;
233	}
234	this.save = save;
235	setVisible(false);
236    }
237
238    /**
239     * Determine whether or not the user wanted to save the value in
240     * this Dialog box. The user indicates this by clicking on the Ok
241     * button to save it and on the Cancel button to discard it. Using the
242     * window close menu responds the same way as cancel.
243     * @return true if the user wanted to use this value,
244     * false if it is to be discarded.
245     */
246    public boolean isSaved() {
247	return save;
248    }
249
250    /**
251     * The string representation of the contents of this dialog box.
252     * @return a String with the total number of seconds entered.
253     */
254    public String toString() {
255	return total.getText();
256    }
257
258    // * **********************************************
259    // 	 I N N E R    C L A S S E S   F O L L O W
260    // * **********************************************
261
262    /**
263     * Listener for closing the dialog box through the window close
264     * menu.
265     */
266    private class DHWindowListener extends WindowAdapter {
267	public  void windowClosing(WindowEvent e) {
268		durationHelperClose(false);
269	}
270    }
271
272    /**
273     * Listener for all the buttons.
274     * The listener is shared for the sake
275     * of reducing the number of overall listeners.
276     */
277    private class ButtonListener implements ActionListener {
278        public void actionPerformed(ActionEvent e) {
279            if (e.getSource() == ok) {
280                DurationHelper.this.durationHelperClose(true);
281	    } else if (e.getSource() == cancel) {
282                DurationHelper.this.durationHelperClose(false);
283	    } else if (e.getSource() == help) {
284                if (hd != null)
285                    hd.show();
286                else {
287                    hd = new HelpDialog(DurationHelper. this.parent,
288                        getString("Help for entering time duration"),
289                                    false, 5, 45);
290                    hd.setVisible(true);
291                    hd.setText(getString(hrb, "DurationHelperHelp"));
292                }
293            } else if (e.getSource() == compute) {
294                checkErrorAndSetTotal();
295            }
296        }
297    }
298
299    /**
300     * Call rb.getString(), but catch exception
301     * and return English
302     * key so that small spelling errors don't cripple the GUI
303     *
304     */
305    private static final String getString(String key) {
306	return (getString(rb, key));
307    }
308
309    private static final String getString(ResourceBundle rb, String key) {
310        try {
311	    String res = rb.getString(key);
312            return res;
313	} catch (MissingResourceException e) {
314		System.out.println("Missing resource "+key+", using English.");
315		return key;
316	}
317    }
318
319    /*
320     * A main method to test this class.
321     */
322    /*
323    public static void main(String args[]) {
324        Frame f = new Frame("Test DurationHelper");
325        f.setVisible(true); // for help dialog to use this as parent
326        DurationHelper dh = new DurationHelper(f, Color.white, Color.black);
327        dh.setVisible(true);
328        System.out.println("Save is " + dh.save);
329    }
330	  */
331}
332