/*
 * @(#)DatePickerDemo.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.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.Window;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.Serializable;
import java.awt.event.KeyEvent;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.Locale;
import java.util.Vector;

import javax.swing.ActionMap;
import javax.swing.DefaultCellEditor;
import javax.swing.DefaultListCellRenderer;
import javax.swing.InputMap;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JColorChooser;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.KeyStroke;
import javax.swing.border.TitledBorder;
import javax.swing.colorchooser.ColorSelectionModel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.plaf.ColorUIResource;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
import javax.swing.table.TableModel;
import javax.swing.table.*;

import com.standbysoft.component.date.DateSelectionModel;
import com.standbysoft.component.date.DateSelectionModel.SelectionMode;
import com.standbysoft.component.date.swing.JDateComponent;
import com.standbysoft.component.date.swing.JDatePicker;
import com.standbysoft.component.date.swing.JMonthView;
import com.standbysoft.component.date.swing.JDateComponent.DateAction;

/**
 * Shows specific <code>JDatePicker</code> operations.
 */
public class DatePickerDemo extends JPanel {
    /**
     * Actual date picker used to show its features.
     */
    private JDatePicker datePicker;

    public DatePickerDemo() {
        datePicker = createDatePicker();
        
        setLayout(new GridBagLayout());
        
        add(datePicker, new GridBagConstraints(00114.00.0, GridBagConstraints.NORTH, GridBagConstraints.HORIZONTAL, new Insets(8555)00));
        add(createGeneralPanel()new GridBagConstraints(10111.00.0, GridBagConstraints.NORTH, GridBagConstraints.HORIZONTAL, new Insets(0555)00));
        add(createDateFormattingPanel()new GridBagConstraints(11111.00.0, GridBagConstraints.NORTH, GridBagConstraints.HORIZONTAL, new Insets(0555)00));
        add(createColorsPanel()new GridBagConstraints(20120.00.0, GridBagConstraints.NORTH, GridBagConstraints.HORIZONTAL, new Insets(0555)00));        
        add(createTablePanel()new GridBagConstraints(12213.01.0, GridBagConstraints.NORTH, GridBagConstraints.BOTH, new Insets(0555)00));
    }

    /**
     * Creates the date picker component that is used by this demo. It has two 
     * keyboard actions associated with its calendar to select the today date 
     * and the Christmas date. 
     
     @return date picker component that is used by this demo.
     */
    private JDatePicker createDatePicker() {
        JDatePicker datePicker = new JDatePicker(true);
        
        JMonthView monthView = datePicker.getPopup().getMonthView();
        InputMap im = monthView.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
        ActionMap am = monthView.getActionMap();

        //register select today action when the T key is pressed
        KeyStroke keyToday= KeyStroke.getKeyStroke(KeyEvent.VK_T, 0);
        im.put(keyToday, JDateComponent.selectTodayAction);
        am.put(JDateComponent.selectTodayAction, new JDateComponent.SelectTodayAction());
        
        //register select Christmas action when the X key is pressed
        KeyStroke keyChristmas = KeyStroke.getKeyStroke(KeyEvent.VK_X, 0);
        im.put(keyChristmas, "select-christmas");
        am.put("select-christmas"new SelectChristmasAction());
        
        return datePicker;
    }

    /**
     * This action is used to select the Christmas date for the current year. 
     */
    public static class SelectChristmasAction extends DateAction {
        public void actionPerformed(ActionEvent e) {
            //get the date component for which the selection is made
            JDateComponent dateComponent = getDateComponent(e);
            if (dateComponent == null) {
                return;
            }

            //create the date
            Calendar cal = Calendar.getInstance();
            cal.setTime(dateComponent.getSelectedDate());
            
            cal.set(Calendar.MONTH, Calendar.DECEMBER);
            cal.set(Calendar.DATE, 25);
            
            Date date = cal.getTime();
            
            //select the date
            DateSelectionModel dsm = dateComponent.getDateSelectionModel();

            if (date != null) {
                if (dsm.isDateSelectable(date)) {
                    dsm.setDateSelectionIterval(date, date);
                else {
                    Toolkit.getDefaultToolkit().beep();
                }
            }
        }
    }
    
    /**
     * Creates a panel that controls specific JDatePicker features.
     
     @return actual panel
     */
    private JComponent createGeneralPanel() {
        JPanel generalPanel = new JPanel();
        generalPanel.setBorder(new TitledBorder("General"));
        generalPanel.setLayout(new GridBagLayout());

//        datePicker.putClientProperty("JDatePicker.backgroundOnEditable", Boolean.TRUE);
        
        final JCheckBox editableCheckBox = new JCheckBox("Editable", datePicker.isEditable());
        editableCheckBox.setFont(editableCheckBox.getFont().deriveFont(Font.BOLD));
        editableCheckBox.setMnemonic('d');
        editableCheckBox.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                datePicker.setEditable(editableCheckBox.isSelected());
                DatePickerDemo.this.invalidate();
            }
        });
        
        final JCheckBox enabledCheckBox = new JCheckBox("Enabled", datePicker.isEnabled());
        enabledCheckBox.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                datePicker.setEnabled(enabledCheckBox.isSelected());
            }
        });
        
        final JCheckBox multipleCheckBox = new JCheckBox("Multiple Selection"(datePicker.getDateSelectionModel().getSelectionMode() == SelectionMode.MULTIPLE_INTERVAL));
        multipleCheckBox.setToolTipText("CTRL click or drag the mouse to select multiple dates in the drop-down calendar");
        multipleCheckBox.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                if (multipleCheckBox.isSelected()) {
                    datePicker.getDateSelectionModel().setSelectionMode(SelectionMode.MULTIPLE_INTERVAL);
                else {
                    datePicker.getDateSelectionModel().setSelectionMode(SelectionMode.SINGLE);
                }
            }
        });
        
        Color color = null;
        
        JLabel foregroundLabel = new JLabel("Foreground:");
        foregroundLabel.setDisplayedMnemonic('o');
        final JButton foregroundButton = new JButton(" ");
        foregroundLabel.setLabelFor(foregroundButton);
        foregroundButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                Color color = JColorChooser.showDialog(DatePickerDemo.this, "Choose Foreground", datePicker.getForeground());
                if (color != null) {
                    datePicker.setForeground(color);
                    foregroundButton.setBackground(datePicker.getForeground());
                }
            }
        });
        
        color = datePicker.getForeground();
        if (color != null && color instanceof ColorUIResource) {
            color = new Color(color.getRGB());
        }
        foregroundButton.setBackground(color);
        
        JLabel backgroundLabel = new JLabel("Background:");
        final JButton backgroundButton = new JButton(" ");
        backgroundLabel.setDisplayedMnemonic('b');
        backgroundLabel.setLabelFor(backgroundButton);
        backgroundButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                Color color = JColorChooser.showDialog(DatePickerDemo.this, "Choose Background", datePicker.getBackground());
                if (color != null) {
                    datePicker.setBackground(color);
                    backgroundButton.setBackground(datePicker.getBackground());
                }
            }
        });
        
        color = datePicker.getBackground();
        if (color != null && color instanceof ColorUIResource) {
            color = new Color(color.getRGB());
        }
        backgroundButton.setBackground(color);

        generalPanel.add(editableCheckBox, new GridBagConstraints(00110.00.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(0555)00));
        generalPanel.add(enabledCheckBox, new GridBagConstraints(10110.00.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(0555)00));
        generalPanel.add(multipleCheckBox, new GridBagConstraints(20110.00.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(0555)00));
//        generalPanel.add(backgroundLabel, new GridBagConstraints(1, 1, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(0, 5, 5, 5), 0, 0));
//        generalPanel.add(backgroundButton, new GridBagConstraints(2, 1, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(0, 5, 5, 5), 0, 0));
        generalPanel.add(new JLabel()new GridBagConstraints(30111.00.0, GridBagConstraints.NORTH, GridBagConstraints.HORIZONTAL, new Insets(0505)00));
        
        return generalPanel;
    }
    /**
     * Creates a panel that controls JDatePicker date formatting.
     
     @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(datePicker.getLocale());
        localeComboBox.addItemListener(new ItemListener() {
            public void itemStateChanged(ItemEvent evt) {
                if (evt.getStateChange() == ItemEvent.SELECTED) {
                    Locale locale = (LocalelocaleComboBox.getSelectedItem();
                    datePicker.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 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();
                    datePicker.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) {
                datePicker.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()) {
                    datePicker.setDateFormat((String)customDateFormatComboBox.getSelectedItem());
                    formatComboBox.setEnabled(false);
                    formatLabel.setEnabled(false);
                    customDateFormatComboBox.setEnabled(true);
                else {
                    datePicker.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(new JLabel()new GridBagConstraints(30111.00.0, GridBagConstraints.NORTH, GridBagConstraints.HORIZONTAL, new Insets(0555)00));

        return formattingPanel;
    }
    
    /**
     * Creates a panel that controls the colors of the JDatePicker drop down calendar.
     
     @return actual panel
     */
    private JComponent createColorsPanel() {
        final JMonthView popupMonthView = datePicker.getPopup().getMonthView();
        
        JPanel colorsPanel = new JPanel();
        colorsPanel.setBorder(new TitledBorder("Calendar Colors"));
        colorsPanel.setLayout(new GridBagLayout());
        
        Color color = null;
        
        JLabel foregroundLabel = new JLabel("Foreground:");
        foregroundLabel.setDisplayedMnemonic('o');
        final JButton foregroundButton = new JButton(" ");
        foregroundLabel.setLabelFor(foregroundButton);
        foregroundButton.addActionListener(new CalendarColorSelectionHandler(datePicker, popupMonthView.getForeground()"Choose Foreground", foregroundButton) {
            public void setColor(Color color) {
                popupMonthView.setForeground(color);
            }
        });
        
        color = popupMonthView.getForeground();
        if (color != null && color instanceof ColorUIResource) {
            color = new Color(color.getRGB());
        }
        foregroundButton.setBackground(color);
        
        JLabel titleBackgroundLabel = new JLabel("Title Background:");
        final JButton titleBackgroundButton = new JButton(" ");
        titleBackgroundLabel.setDisplayedMnemonic('b');
        titleBackgroundLabel.setLabelFor(titleBackgroundButton);
        titleBackgroundButton.addActionListener(new CalendarColorSelectionHandler(datePicker, popupMonthView.getTitleBackground()"Choose Title Background", titleBackgroundButton) {
            public void setColor(Color color) {
                popupMonthView.setTitleBackground(color);
            }
        });
        
        color = popupMonthView.getTitleBackground();
        if (color != null && color instanceof ColorUIResource) {
            color = new Color(color.getRGB());
        }
        titleBackgroundButton.setBackground(color);
        
        JLabel titleForegroundLabel = new JLabel("Title Foreground:");
        final JButton titleForegroundButton = new JButton(" ");
        titleForegroundLabel.setDisplayedMnemonic('r');
        titleForegroundLabel.setLabelFor(titleForegroundButton);
        titleForegroundButton.addActionListener(new CalendarColorSelectionHandler(datePicker, popupMonthView.getTitleForeground()"Choose Title Foreground", titleForegroundButton) {
            public void setColor(Color color) {
                popupMonthView.setTitleForeground(color);
            }
        });
        
        color = popupMonthView.getTitleForeground();
        if (color != null && color instanceof ColorUIResource) {
            color = new Color(color.getRGB());
        }
        titleForegroundButton.setBackground(color);
        
        JLabel trailingForegroundLabel = new JLabel("Trailing Foreground:");
        final JButton trailingForegroundButton = new JButton(" ");
        trailingForegroundLabel.setDisplayedMnemonic('t');
        trailingForegroundLabel.setLabelFor(trailingForegroundButton);
        trailingForegroundButton.addActionListener(new CalendarColorSelectionHandler(datePicker, popupMonthView.getTrailingForeground()"Choose Trailing Foreground", trailingForegroundButton) {
            public void setColor(Color color) {
                popupMonthView.setTrailingForeground(color);
            }
        });
        
        color = popupMonthView.getTrailingForeground();
        if (color != null && color instanceof ColorUIResource) {
            color = new Color(color.getRGB());
        }
        trailingForegroundButton.setBackground(color);
        
        JLabel monthBackgroundLabel = new JLabel("Month Background:");
        monthBackgroundLabel.setDisplayedMnemonic('m');
        final JButton monthBackgroundButton = new JButton(" ");
        monthBackgroundLabel.setLabelFor(monthBackgroundButton);
        monthBackgroundButton.addActionListener(new CalendarColorSelectionHandler(datePicker, popupMonthView.getMonthBackground()"Choose Month Background", monthBackgroundButton) {
            public void setColor(Color color) {
                popupMonthView.setMonthBackground(color);
            }
        });
        
        color = popupMonthView.getMonthBackground();
        if (color != null && color instanceof ColorUIResource) {
            color = new Color(color.getRGB());
        }
        monthBackgroundButton.setBackground(color);
        
        colorsPanel.add(foregroundLabel, new GridBagConstraints(00111.00.0, GridBagConstraints.NORTH, GridBagConstraints.HORIZONTAL, new Insets(0555)00));
        colorsPanel.add(foregroundButton, new GridBagConstraints(10110.00.0, GridBagConstraints.NORTH, GridBagConstraints.NONE, new Insets(0555)00));
        colorsPanel.add(titleBackgroundLabel, new GridBagConstraints(01111.00.0, GridBagConstraints.NORTH, GridBagConstraints.HORIZONTAL, new Insets(0555)00));
        colorsPanel.add(titleBackgroundButton, new GridBagConstraints(11110.00.0, GridBagConstraints.NORTH, GridBagConstraints.NONE, new Insets(0555)00));
        colorsPanel.add(titleForegroundLabel, new GridBagConstraints(0</