/*
 * @(#)DateEditComponentDemo.java
 *
 * Copyright (c) 2003-2004 Stand By Soft, Ltd. All rights reserved.
 *
 * This software is the proprietary information of Stand By Soft, Ltd.  
 * Use is subject to license terms.
 */
package com.standbysoft.demo.date;

import java.awt.Component;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.text.DateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;

import javax.swing.DefaultListCellRenderer;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.border.TitledBorder;

import com.standbysoft.component.date.DateParserException;
import com.standbysoft.component.date.DateSelectionModel;
import com.standbysoft.component.date.DefaultDateParser;
import com.standbysoft.component.date.DefaultDateSelectionModel;
import com.standbysoft.component.date.event.DateEvent;
import com.standbysoft.component.date.event.DateListener;
import com.standbysoft.component.date.event.DateSelectionEvent;
import com.standbysoft.component.date.event.DateSelectionListener;
import com.standbysoft.component.date.swing.JDateEditComponent;
import com.standbysoft.component.date.swing.JDateField;

/**
 * Shows the basic operations that can be performed on a <code>JDateEditComponent</code>.
 */
public class DateEditComponentDemo extends JPanel {
    /**
     * Date edit component for which this demo was created. It could be 
     * JDatePicker or JDateField.
     */
    private JDateEditComponent editComponent;
    
    public DateEditComponentDemo() {
        editComponent = new JDateField()//we have decided to use JDateField.
        editComponent.setEmptySelectionText(" / / ");
        editComponent.setDateFormat(DateFormat.SHORT);

        setLayout(new GridBagLayout());
        
        add(editComponent, new GridBagConstraints(00114.00.0, GridBagConstraints.NORTH, GridBagConstraints.HORIZONTAL, new Insets(8555)00));
        add(createDateValidationPanel()new GridBagConstraints(10210.00.0, GridBagConstraints.NORTH, GridBagConstraints.HORIZONTAL, new Insets(0555)00));
        add(createDateEditingPanel()new GridBagConstraints(11210.00.0, GridBagConstraints.NORTH, GridBagConstraints.HORIZONTAL, new Insets(0555)00));
        add(createDateSelectionPanel()new GridBagConstraints(12110.00.0, GridBagConstraints.NORTH, GridBagConstraints.BOTH, new Insets(0555)00));
        add(createDateFormattingPanel()new GridBagConstraints(22110.00.0, GridBagConstraints.NORTH, GridBagConstraints.HORIZONTAL, new Insets(0555)00));
        add(createMessagesPanel()new GridBagConstraints(13213.01.0, GridBagConstraints.NORTH, GridBagConstraints.BOTH, new Insets(0555)00));
    }

    /**
     * Creates a panel that controls validation behavior for the date edit component.
     
     @return actual panel
     */
    private JPanel createDateValidationPanel() {
        editComponent.setDateParser(new MyDateParser());
        
        JPanel validationPanel = new JPanel();
        validationPanel.setBorder(new TitledBorder("Date Validation"));
        validationPanel.setLayout(new GridBagLayout());
        
        final JCheckBox autoValidateCheckBox = new JCheckBox("Auto Validate", editComponent.isAutoValidate());
        autoValidateCheckBox.setToolTipText("Dates are validated when the component loses focus");
        autoValidateCheckBox.setMnemonic('v');
        autoValidateCheckBox.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                editComponent.setAutoValidate(autoValidateCheckBox.isSelected());
            }
        });
        
        final JCheckBox autoRestoreCheckBox = new JCheckBox("Auto Restore", editComponent.isAutoRestore());
        autoRestoreCheckBox.setToolTipText("Invalid dates are automatically restored to the last valid date");
        autoRestoreCheckBox.setMnemonic('r');
        autoRestoreCheckBox.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                editComponent.setAutoRestore(autoRestoreCheckBox.isSelected());
            }
        });
        
        final JCheckBox autoCenturyCheckBox = new JCheckBox("Auto Century", editComponent.isAutoCentury());
        autoCenturyCheckBox.setToolTipText("Century is automatically added to the year field if its value is less than 100");
        autoCenturyCheckBox.setMnemonic('c');
        autoCenturyCheckBox.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                editComponent.setAutoCentury(autoCenturyCheckBox.isSelected());
            }
        });
        
        final JCheckBox beepOnErrorCheckBox = new JCheckBox("Beep On Error", editComponent.isBeepOnError());
        beepOnErrorCheckBox.setToolTipText("Beep if the typed date is not valid");
        beepOnErrorCheckBox.setMnemonic('b');
        beepOnErrorCheckBox.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                editComponent.setBeepOnError(beepOnErrorCheckBox.isSelected());
            }
        });
        
        validationPanel.add(autoValidateCheckBox, new GridBagConstraints(00110.00.0, GridBagConstraints.NORTH, GridBagConstraints.HORIZONTAL, new Insets(0555)00));
        validationPanel.add(autoRestoreCheckBox, new GridBagConstraints(10110.00.0, GridBagConstraints.NORTH, GridBagConstraints.HORIZONTAL, new Insets(0555)00));
        validationPanel.add(autoCenturyCheckBox, new GridBagConstraints(20110.00.0, GridBagConstraints.NORTH, GridBagConstraints.HORIZONTAL, new Insets(0555)00));
        validationPanel.add(beepOnErrorCheckBox, new GridBagConstraints(30110.00.0, GridBagConstraints.NORTH, GridBagConstraints.HORIZONTAL, new Insets(0555)00));
        validationPanel.add(new JLabel()new GridBagConstraints(00511.00.0, GridBagConstraints.NORTH, GridBagConstraints.HORIZONTAL, new Insets(0555)00));
        
        return validationPanel;
    }

    /**
     * Creates a panel that controls editing features for the date edit component.
     
     @return actual panel
     */
    private JPanel createDateEditingPanel() {
        JPanel editingPanel = new JPanel();
        editingPanel.setBorder(new TitledBorder("Date Editing"));
        editingPanel.setLayout(new GridBagLayout());
        
        Boolean clear = (Boolean)editComponent.getClientProperty("JDateEditComponent.clearDateOnEdit");
        final JCheckBox clearDateOnEditCheckBox = new JCheckBox("Clear Date On Edit", clear != null && clear.booleanValue());
        clearDateOnEditCheckBox.setToolTipText("Delete date when editing is started after a keyboard focus (not mouse)");
        clearDateOnEditCheckBox.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                editComponent.putClientProperty("JDateEditComponent.clearDateOnEdit", Boolean.valueOf(clearDateOnEditCheckBox.isSelected()));
            }
        });

        final JLabel freeTextHintLabel = new JLabel("Hint: Type \"today\" to select the today date or \"none\" for a null date");
        freeTextHintLabel.setVisible(editComponent.isFreeText());
        freeTextHintLabel.setFont(freeTextHintLabel.getFont().deriveFont(10.0f));
        
        final JCheckBox customParserAllowedCheckBox = new JCheckBox("Free Text Editing", editComponent.isFreeText());
        customParserAllowedCheckBox.setToolTipText("Any text can be a date as long as it is recognized by the custom date parser");
        customParserAllowedCheckBox.setMnemonic('f');
        customParserAllowedCheckBox.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                editComponent.setFreeText(customParserAllowedCheckBox.isSelected());
                freeTextHintLabel.setVisible(customParserAllowedCheckBox.isSelected());
            }
        });
        
        editingPanel.add(clearDateOnEditCheckBox, new GridBagConstraints(00110.00.0, GridBagConstraints.NORTH, GridBagConstraints.HORIZONTAL, new Insets(0555)00));
        editingPanel.add(customParserAllowedCheckBox, new GridBagConstraints(10110.00.0, GridBagConstraints.NORTH, GridBagConstraints.HORIZONTAL, new Insets(0555)00));
        editingPanel.add(freeTextHintLabel, new GridBagConstraints(20110.00.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(0555)00));
        editingPanel.add(new JLabel()new GridBagConstraints(30511.00.0, GridBagConstraints.NORTH, GridBagConstraints.HORIZONTAL, new Insets(0555)00));
        
        return editingPanel;
    }
    
    /**
     * Creates a panel that controls date formatting for the date edit component.
     
     @return actual panel
     */
    private JPanel createDateFormattingPanel() {
        JPanel formattingPanel = new JPanel();
        formattingPanel.setBorder(new TitledBorder("Date Formatting"));
        formattingPanel.setLayout(new GridBagLayout());        
        
        JLabel localeLabel = new JLabel("Locale:");
        localeLabel.setDisplayedMnemonic('l');
        final JComboBox localeComboBox = new JComboBox(Locale.getAvailableLocales());
        localeLabel.setLabelFor(localeComboBox);

        localeComboBox.setSelectedItem(editComponent.getLocale());
        localeComboBox.addItemListener(new ItemListener() {
            public void itemStateChanged(ItemEvent evt) {
                if (evt.getStateChange() == ItemEvent.SELECTED) {
                    Locale locale = (LocalelocaleComboBox.getSelectedItem();
                    editComponent.setLocale(locale);
                }
            }
        });
        localeComboBox.setRenderer(new DefaultListCellRenderer() {
            public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
                JLabel l = (JLabelsuper.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
                Locale locale = (Localevalue;
                l.setText(locale.getDisplayName());

                return l;
            }
        });
        
        
        final JLabel alignLabel = new JLabel("Alignment:");
        
        final JComboBox alignComboBox = new JComboBox(new Integer[] {new Integer(JDateEditComponent.LEFT)new Integer(JDateEditComponent.RIGHT)new Integer(JDateEditComponent.CENTER)new Integer(JDateEditComponent.TRAILING)new Integer(JDateEditComponent.LEADING)});
        alignLabel.setLabelFor(alignComboBox);
        alignComboBox.setSelectedItem(new Integer(editComponent.getHorizontalAlignment()));
        alignComboBox.addItemListener(new ItemListener() {
            public void itemStateChanged(ItemEvent evt) {
                if (evt.getStateChange() == ItemEvent.SELECTED) {
                    Integer integer = (IntegeralignComboBox.getSelectedItem();
                    editComponent.setHorizontalAlignment(integer.intValue());
                }
            }
        });
        
        alignComboBox.setRenderer(new DefaultListCellRenderer() {
            public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
                JLabel l = (JLabelsuper.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
                switch (((Integer)value).intValue()) {
                    case JDateEditComponent.LEADING: l.setText("Leading")break;
                    case JDateEditComponent.TRAILING: l.setText("Trailing")break;
                    case JDateEditComponent.LEFT: l.setText("Left")break;
                    case JDateEditComponent.CENTER: l.setText("Center")break;
                    case JDateEditComponent.RIGHT: l.setText("Right")break;
                    default: l.setText("Unavailable");
                }

                return l;
            }
        });
        
        final JLabel formatLabel = new JLabel("Date Format:");
        formatLabel.setDisplayedMnemonic('d');
        
        final JComboBox formatComboBox = new JComboBox(new Integer[] {new Integer(DateFormat.SHORT)new Integer(DateFormat.MEDIUM)new Integer(DateFormat.LONG)new Integer(DateFormat.FULL)});
        formatLabel.setLabelFor(formatComboBox);
        formatComboBox.addItemListener(new ItemListener() {
            public void itemStateChanged(ItemEvent evt) {
                if (evt.getStateChange() == ItemEvent.SELECTED) {
                    Integer integer = (IntegerformatComboBox.getSelectedItem();
                    editComponent.setDateFormat(integer.intValue());
                }
            }
        });
        formatComboBox.setSelectedItem(new Integer(DateFormat.DEFAULT));
        
        formatComboBox.setRenderer(new DefaultListCellRenderer() {
            public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
                JLabel l = (JLabelsuper.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
                switch (((Integer)value).intValue()) {
                    case DateFormat.SHORT: l.setText("Short")break;
                    case DateFormat.MEDIUM: l.setText("Medium")break;
                    case DateFormat.LONG: l.setText("Long")break;
                    case DateFormat.FULL: l.setText("Full")break;
                    default: l.setText("Unavailable");
                }

                return l;
            }
        });

        String[] patternExamples = {
                 "MMM d, yyyy hh:mm a",
                 "dd MMMMM yyyy",
                 "dd.MM.yy",
                 "MM/dd/yy",
                 "yyyy.MM.dd G 'at' hh:mm:ss z",
                 "EEE, MMM d, ''yy",
                 "h:mm a",
                 "H:mm:ss:SSS",
                 "K:mm a,z",
                 "yyyy.MMMMM.dd GGG hh:mm aaa"
        };
        
        final JComboBox customDateFormatComboBox = new JComboBox(patternExamples);
        customDateFormatComboBox.setEditable(true);
        customDateFormatComboBox.addActionListener(new ActionListener() {            
            public void actionPerformed(ActionEvent e) {
                editComponent.setDateFormat((String)customDateFormatComboBox.getSelectedItem());
            }
        });

        final JCheckBox customDateFormatCheckBox = new JCheckBox("Custom Format:");
        customDateFormatCheckBox.setMnemonic('u');
        customDateFormatCheckBox.addItemListener(new ItemListener() {
            public void itemStateChanged(ItemEvent evt) {
                JCheckBox cb = (JCheckBox)evt.getSource();
                
                if (cb.isSelected()) {
                    editComponent.setDateFormat((String)customDateFormatComboBox.getSelectedItem());
                    formatComboBox.setEnabled(false);
                    formatLabel.setEnabled(false);
                    customDateFormatComboBox.setEnabled(true);
                else {
                    editComponent.setDateFormat(((Integer)formatComboBox.getSelectedItem()).intValue());
                    formatComboBox.setEnabled(true);
                    formatLabel.setEnabled(true);
                    customDateFormatComboBox.setEnabled(false);
                }
            }
        });
        customDateFormatCheckBox.setSelected(!customDateFormatCheckBox.isSelected());
        customDateFormatCheckBox.setSelected(!customDateFormatCheckBox.isSelected());

        formattingPanel.add(customDateFormatCheckBox, new GridBagConstraints(10110.00.0, GridBagConstraints.NORTH, GridBagConstraints.HORIZONTAL, new Insets(0555)00));
        formattingPanel.add(customDateFormatComboBox, new GridBagConstraints(20110.00.0, GridBagConstraints.NORTH, GridBagConstraints.HORIZONTAL, new Insets(0555)00));
        formattingPanel.add(formatLabel, new GridBagConstraints(11110.00.0, GridBagConstraints.NORTH, GridBagConstraints.HORIZONTAL, new Insets(0555)00));
        formattingPanel.add(formatComboBox, new GridBagConstraints(21110.00.0, GridBagConstraints.NORTH, GridBagConstraints.HORIZONTAL, new Insets(0555)00));
        formattingPanel.add(localeLabel, new GridBagConstraints(12110.00.0, GridBagConstraints.NORTH, GridBagConstraints.HORIZONTAL, new Insets(0555)00));
        formattingPanel.add(localeComboBox, new GridBagConstraints(22110.00.0, GridBagConstraints.NORTH, GridBagConstraints.HORIZONTAL, new Insets(0555)00));
        formattingPanel.add(alignLabel, new GridBagConstraints(13110.00.0, GridBagConstraints.NORTH, GridBagConstraints.HORIZONTAL, new Insets(0555)00));
        formattingPanel.add(alignComboBox, new GridBagConstraints(23110.00.0, GridBagConstraints.NORTH, GridBagConstraints.HORIZONTAL, new Insets(0555)00));
        formattingPanel.add(new JLabel()new GridBagConstraints(04211.00.0, GridBagConstraints.NORTH, GridBagConstraints.HORIZONTAL, new Insets(0555)00));

        return formattingPanel;
    }

    /**
     * Creates a panel that controls date selection for the date edit component.
     
     @return actual panel
     */
    private JPanel createDateSelectionPanel() {
        JPanel dateSelectionPanel = new JPanel();
        dateSelectionPanel.setBorder(new TitledBorder("Date Selection"));
        dateSelectionPanel.setLayout(new GridBagLayout());
        
        JLabel nullDateLabel = new JLabel("Null Date Text: ");
        final JCheckBox nullDateCheckBox = new JCheckBox("Allow Null Date");
        nullDateCheckBox.setMnemonic('n');
        final JTextField nullDateTextField = new JTextField(editComponent.getEmptySelectionText()10);
        final JButton nullDateTextButton = new JButton("Apply");
        nullDateTextButton.setMargin(new Insets(2222));
        nullDateTextButton.setToolTipText("Set the text that represents a null date for the date picker");
        nullDateTextButton.setMnemonic('t');

        nullDateTextButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                editComponent.setEmptySelectionText(nullDateTextField.getText());
            }
        });
        
        nullDateCheckBox.addItemListener(new ItemListener() {
            public void itemStateChanged(ItemEvent evt) {
                try {
                    editComponent.setEmptySelectionAllowed(nullDateCheckBox.isSelected());
                    nullDateTextField.setEnabled(nullDateCheckBox.isSelected());
                    nullDateTextButton.setEnabled(nullDateCheckBox.isSelected());
                catch (Exception e) {
                    nullDateCheckBox.setSelected(editComponent.isEmptySelectionAllowed());
                    JOptionPane.showOptionDialog(JOptionPane.getFrameForComponent(DateEditComponentDemo.this)"The following error occurred:\n" + e.getMessage()"Null Date Error", JOptionPane.OK_OPTION, JOptionPane.INFORMATION_MESSAGE, null, new String[] { "Dismiss" }null);
                }
            }
        });
        nullDateCheckBox.setSelected(editComponent.isEmptySelectionAllowed());
        nullDateTextField.setEnabled(nullDateCheckBox.isSelected());
        nullDateTextButton.setEnabled(nullDateCheckBox.isSelected());

        JLabel dateSelectionModelLabel = new JLabel("Selection Model:");
        final JComboBox dateSelectionModelComboBox = new JComboBox(new Object[] {new DefaultDateSelectionModel()new NoWeekendDateSelectionModel()});
        dateSelectionModelComboBox.addItemListener(new ItemListener() {
            public void itemStateChanged(ItemEvent evt) {
                if (evt.getStateChange() == ItemEvent.SELECTED) {
                    DateSelectionModel dsm = (DateSelectionModel)dateSelectionModelComboBox.getSelectedItem();
                    editComponent.setDateSelectionModel(dsm);
                }
            }
        });
        dateSelectionModelComboBox.setRenderer(new DefaultListCellRenderer() {
            public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
                JLabel l = (JLabelsuper.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
                String className = value.getClass().getName();
                
                if (className.indexOf("Default"!= -1) {
                    l.setText("Default");
                else if (className.indexOf("NoWeekend"!= -1) {
                    l.setText("No Weekends");
                else {
                    l.setText("Custom");
                }

                return l;
            }
        });

        dateSelectionPanel.add(nullDateCheckBox, new GridBagConstraints(00310.00.0, GridBagConstraints.NORTH, GridBagConstraints.HORIZONTAL, new Insets(0555)00));
        dateSelectionPanel.add(nullDateLabel, new GridBagConstraints(01110.00.0, GridBagConstraints.NORTH, GridBagConstraints.HORIZONTAL, new Insets(0555)00));
        dateSelectionPanel.add(nullDateTextField, new GridBagConstraints(11211.00.0, GridBagConstraints.NORTH, GridBagConstraints.HORIZONTAL, new Insets(0555)