/*
 * SaveChangesDialog.java
 */
 // REMIND: add action command strings and event handlers see FileExistsDialog

package samples;

import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.util.*;
import javax.swing.*;
import javax.swing.plaf.metal.MetalLookAndFeel;

/** 
 * SaveChangesDialog: A dialog that asks if changes should be saved. 
 * The dialog is similar to those created via JOptionPane.
 */
public class SaveChangesDialog extends JDialog {

    /** 
     * Resources with default locale 
     */
    private ResourceBundle resources = null;
  
    /** 
     * Path to the image resources 
     */
    private String imagePath = null;

    // Components that we need to modify dynamically
    private JButton saveButton = null;
    private JButton dontSaveButton = null;
    private JButton cancelButton = null;

    /**
     * For some reason, the dialog comes up with no initial focus,
     * so we must do it manually when the window opens.
     */
    Component initialFocusOwner = null;

    /** 
     * Creates a new SaveChangesDialog
     */
    public SaveChangesDialog(Frame parent,boolean modal) {
        super(parent, modal);
        initResources();
        initComponents();
        pack();
    }

    /** 
     * Gets the resource bundle and other resources.
     */
    private void initResources() {
	Locale locale = Locale.getDefault();
        resources = ResourceBundle.getBundle(
	    "samples.resources.bundles.SaveChangesDialogResources", locale);
        imagePath = resources.getString("imagePath");

	// all applets, frames, and dialogs should have descriptions
	// This is good for users with disabilities
	getAccessibleContext().setAccessibleDescription(
	    resources.getString("dialog.accessibleDescription"));
    } // initResources()

    /* This method is called from within the constructor to
     * initialize the dialog.
     */
    private void initComponents() {
	Container contents = getContentPane();
        contents.setLayout(new GridBagLayout ());
        GridBagConstraints constraints;
        setTitle (resources.getString("dialog.title"));

        addWindowListener(new WindowAdapter () {
	    public void windowOpened(WindowEvent event) {
                // For some reason, the dialog comes up with no initial,
                // focus, so we must do it manually when the window opens.
	        if (initialFocusOwner != null) {
		    initialFocusOwner.requestFocus();
		    initialFocusOwner = null; // only do it once
		}
	    }
            public void windowClosing(WindowEvent event) {
                closeDialog();
            }
        });

	// the image displayed in the dialog
        JLabel imageLabel = new JLabel ();
        imageLabel.setIcon(new ImageIcon(
	    getClass().getResource(
	        imagePath+resources.getString("dialog.warning.image"))));
        constraints = new GridBagConstraints ();
        constraints.gridheight = 2;
        constraints.insets = new Insets(12, 33, 0, 0);
        constraints.anchor = GridBagConstraints.NORTHEAST;
        getContentPane ().add(imageLabel, constraints);

        // header Label
        JLabel headerLabel = new JLabel();
        headerLabel.setText(resources.getString("dialog.headingText"));
        headerLabel.setForeground(
	    new Color(MetalLookAndFeel.getBlack().getRGB()));
        constraints = new GridBagConstraints ();
        constraints.insets = new Insets(12, 12, 0, 11);
        constraints.anchor = GridBagConstraints.WEST;
        contents.add(headerLabel, constraints);

	// main text area
        JTextArea textAreaContent = new JTextArea();
        textAreaContent.setText(resources.getString("dialog.textContent"));
        textAreaContent.setEditable(false);
        textAreaContent.setBackground(
	    new Color(MetalLookAndFeel.getControl().getRGB()));
        constraints = new GridBagConstraints ();
        constraints.gridx = 1;
        constraints.gridy = 1;
        constraints.insets = new Insets(0, 12, 0, 11);
        constraints.anchor = GridBagConstraints.WEST;
        contents.add(textAreaContent, constraints);

	// save, don't save, and cancel buttons
        JPanel buttonPanel = createButtonPanel();
        constraints = new GridBagConstraints ();
        constraints.gridx = 1;
        constraints.gridy = 2;
        constraints.insets = new Insets(12, 12, 11, 11);
        constraints.anchor = GridBagConstraints.WEST;
        contents.add(buttonPanel, constraints);

	// Force the initial focus
	initialFocusOwner = saveButton;

	// Make the buttons look nice, and set up default
        equalizeButtonSizes();
        getRootPane().setDefaultButton(saveButton);

    } // initComponents()

    /**
     * Sets the instance variables:
     * 
     */
    private JPanel createButtonPanel() {
	JPanel panel = new JPanel();
        panel.setLayout(new BoxLayout(panel, 0));

        saveButton = new JButton();
        saveButton.setText(resources.getString("saveButton.label"));
	saveButton.addActionListener(new ActionListener() {
	    public void actionPerformed(ActionEvent event) {
	        closeDialog();
	    }
	});
        panel.add(saveButton);
    
        // spacing
        panel.add(Box.createRigidArea(new Dimension(5,0)));
    
	dontSaveButton = new JButton();
        dontSaveButton.setText(resources.getString("dontSaveButton.label"));
        dontSaveButton.setMnemonic(
	    resources.getString("dontSaveButton.mnemonic").charAt(0));
	dontSaveButton.addActionListener(new ActionListener() {
	    public void actionPerformed(ActionEvent event) {
	        closeDialog();
	    }
	});
        panel.add(dontSaveButton);
    
        // spacing
        panel.add(Box.createRigidArea(new Dimension(5,0)));

	cancelButton = new JButton();
        cancelButton.setText(resources.getString("cancelButton.label"));
        cancelButton.setNextFocusableComponent (saveButton);
	cancelButton.addActionListener(new ActionListener() {
	    public void actionPerformed(ActionEvent event) {
	        closeDialog();
	    }
	});
        panel.add(cancelButton);

	return panel;
    } // createButtonPanel()

    /**
     * Sets all of the buttons to be the same width. This is done
     * dynamically after the buttons are created, so that the layout
     * automatically adjusts to the locale-specific strings.
     */
    private void equalizeButtonSizes() {

        String[] labels = new String[] { 
            saveButton.getText(), 
            dontSaveButton.getText(), 
	    cancelButton.getText()
	};
      
	// Get the largest width and height
	Dimension maxSize= new Dimension(0,0);
	Rectangle2D textBounds = null;
	Dimension textSize = null;
        FontMetrics metrics = saveButton.getFontMetrics(saveButton.getFont());
	Graphics g = getGraphics();
	for (int i = 0; i < labels.length; ++i) {
	    textBounds = metrics.getStringBounds(labels[i], g);
	    maxSize.width = 
	        Math.max(maxSize.width, (int)textBounds.getWidth());
	    maxSize.height = 
	        Math.max(maxSize.height, (int)textBounds.getHeight());
	}
      
        Insets insets = saveButton.getBorder().getBorderInsets(saveButton);
        maxSize.width += insets.left + insets.right;
        maxSize.height += insets.top + insets.bottom;
      
        // reset preferred and maximum size since BoxLayout takes both 
	// into account 
        saveButton.setPreferredSize((Dimension)maxSize.clone());
        dontSaveButton.setPreferredSize((Dimension)maxSize.clone());
        cancelButton.setPreferredSize((Dimension)maxSize.clone());
        saveButton.setMaximumSize((Dimension)maxSize.clone());
        dontSaveButton.setMaximumSize((Dimension)maxSize.clone());
        cancelButton.setMaximumSize((Dimension)maxSize.clone());
    } // equalizeButtonSizes()

    /** 
     * Hides and disposes dialog 
     */
    private void closeDialog() {
        setVisible(false);
        dispose();
    } // closeDialog()

    /**
     * This main() is provided for debugging purposes, to display a 
     * sample dialog.
     */
    public static void main(String args[]) {
	JFrame frame = new JFrame() {
	    public Dimension getPreferredSize() {
	        return new Dimension(200,100);
	    }
	};
	frame.setTitle("Debugging frame");
	frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	frame.pack();
	frame.setVisible(false);

        SaveChangesDialog dialog = new SaveChangesDialog(frame, true);
	dialog.addWindowListener(new WindowAdapter() {
	    public void windowClosing(WindowEvent event) {
	        System.exit(0);
	    }
	    public void windowClosed(WindowEvent event) {
	        System.exit(0);
	    }
	});
	dialog.pack();
	dialog.setVisible(true);
    } // main()

} // class SaveChangesDialog