/*
 * FileExistsDialog.java
 */
 
package samples;

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

/** 
 * FileExistsDialog: A JOptionPane-like dialog that displays the message
 * that a file exists.
 */
public class FileExistsDialog extends JDialog {

    /** 
     * Resource resource with localized strings and images
     */
    private ResourceBundle resources = null;
  
    /** 
     * Path to the image resources 
     */
    private String imagePath = null;

    /**
     * The component that gets the focus when the window is first opened
     */
    private Component initialFocusOwner = null;

    /**
     * Command string for replace action (e.g., a button). 
     * This string is never presented to the user and should 
     * not be internationalized.
     */
    private String CMD_REPLACE = "cmd.replace"/*NOI18N*/;

    /**
     * Command string for a cancel action (e.g., a button). 
     * This string is never presented to the user and should 
     * not be internationalized.
     */
    private String CMD_CANCEL = "cmd.cancel"/*NOI18N*/;

    // Components we need to access after initialization
    private JButton replaceButton = null;
    private JButton cancelButton = null;
  
    /** 
     * Creates a new FileExistsDialog
     *
     * @param parent parent frame
     * @param modal modal flag
     */
    public FileExistsDialog(Frame parent,boolean modal) {
        super(parent, modal);
	initResources();
        initComponents();
        pack();
    }

    /**
     * Determines the locale, loads resources
     */
    public void initResources() {

	Locale locale = Locale.getDefault();
        resources = ResourceBundle.getBundle(
		"samples.resources.bundles.FileExistsDialogResources", locale);
        imagePath = resources.getString("images.path");

    } // initResources()

    /**
     * Sets all of the buttons to be the same size. 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[] { 
            replaceButton.getText(), 
	    cancelButton.getText()
	};
      
	// Get the largest width and height
	Dimension maxSize= new Dimension(0,0);
	Rectangle2D textBounds = null;
	Dimension textSize = null;
        FontMetrics metrics = 
		replaceButton.getFontMetrics(replaceButton.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 = 
	    replaceButton.getBorder().getBorderInsets(replaceButton);
        maxSize.width += insets.left + insets.right;
        maxSize.height += insets.top + insets.bottom;
      
        // reset preferred and maximum size since BoxLayout takes both 
	// into account 
        replaceButton.setPreferredSize((Dimension)maxSize.clone());
        cancelButton.setPreferredSize((Dimension)maxSize.clone());
        replaceButton.setMaximumSize((Dimension)maxSize.clone());
        cancelButton.setMaximumSize((Dimension)maxSize.clone());
    } // equalizeButtonSizes()
  
    /** 
     * This method is called from within the constructor to
     * initialize the dialog.
     */
    private void initComponents() {

	// Configure the window, itself
        Container contents = getContentPane();
        contents.setLayout(new GridBagLayout ());
        GridBagConstraints constraints = null;
        setTitle(resources.getString("window.title"));
	// accessibility - all applets, frames, and dialogs should
	// have descriptions
	this.getAccessibleContext().setAccessibleDescription(
	    resources.getString("window.description"));
	addWindowListener(new WindowAdapter() {
	    public void windowOpened(WindowEvent event) {
		// For some reason the window opens with no focus owner,
		// so we need to force the issue
	        if (initialFocusOwner != null) {
		    initialFocusOwner.requestFocus();
		    // Only do this the 1st time the window is opened
		    initialFocusOwner = null; 
		}
	    }
	    public void windowClosing(WindowEvent event) {
	        // Treat it like a cancel
		windowAction(CMD_CANCEL);
	    }
	});
  
	// image
        JLabel imageLabel = new JLabel();
	String contentImagePath = 
			imagePath + resources.getString("content.image");
        imageLabel.setIcon(
            new ImageIcon(
	        getClass().getResource(contentImagePath)));
        // accessibility - set name so that low vision users get a description
        imageLabel.getAccessibleContext().setAccessibleName(
	    resources.getString("content.image.name"));
        constraints = new GridBagConstraints ();
        constraints.gridheight = 2;
        constraints.insets = new Insets(12, 33, 0, 0);
        constraints.anchor = GridBagConstraints.NORTHEAST;
        contents.add(imageLabel, constraints);
  
        // header
        JLabel headerLabel = new JLabel ();
        headerLabel.setText(resources.getString("header.text"));
        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);
    
	// Actual text of the message
	JTextArea contentTextArea = new JTextArea();
        contentTextArea.setEditable(false);
        contentTextArea.setText(resources.getString("content.text"));
        contentTextArea.setBackground(
		new Color(MetalLookAndFeel.getControl().getRGB()));

        // accessibility -- every component that can have the
	// keyboard focus must have a name. This text area has no
	// label, so the name must be set explicitly (if it had a
	// label, the name would be pulled from the label).
        contentTextArea.getAccessibleContext().setAccessibleName(
		resources.getString("content.name"));
  
        constraints = new GridBagConstraints ();
        constraints.gridx = 1;
        constraints.gridy = 1;
        constraints.insets = new Insets(0, 12, 0, 11);
        constraints.anchor = GridBagConstraints.WEST;
        contents.add(contentTextArea, constraints);
  
	// Buttons
	JPanel buttonPanel = new JPanel();
        buttonPanel.setLayout (new BoxLayout(buttonPanel, 0));
	replaceButton = new JButton();
	replaceButton.setActionCommand(CMD_REPLACE);
        replaceButton.setText(resources.getString("replaceButton.label"));
        replaceButton.setMnemonic(
	    resources.getString("replaceButton.mnemonic").charAt(0));
        replaceButton.setToolTipText(
	    resources.getString("replaceButton.tooltip"));
	replaceButton.addActionListener(new ActionListener() {
	    public void actionPerformed(ActionEvent event) {
	        windowAction(event);
	    }
	});
        buttonPanel.add(replaceButton);
    
        // spacing
        buttonPanel.add(Box.createRigidArea(new Dimension(5,0)));

	cancelButton = new JButton();
	cancelButton.setActionCommand(CMD_CANCEL);
        cancelButton.setText(resources.getString("cancelButton.label"));
        cancelButton.setNextFocusableComponent(replaceButton);
	cancelButton.setToolTipText(
	    resources.getString("cancelButton.tooltip"));
	cancelButton.addActionListener(new ActionListener() {
	    public void actionPerformed(ActionEvent event) {
	        windowAction(event);
	    }
	});
        buttonPanel.add(cancelButton);
  
        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);

	// Equalize the sizes of all the buttons
	equalizeButtonSizes();

	// For some reason, the dialog appears with no input focus.
	// We added a window listener above to force the issue
	initialFocusOwner = replaceButton;

    } // initComponents()

    /**
     * The user has selected an option. Here we close and dispose the dialog.
     * If actionCommand is an ActionEvent, getCommandString() is called,
     * otherwise toString() is used to get the action command.
     *
     * @param actionCommand may be null
     */
    private void windowAction(Object actionCommand) {
	String cmd = null;
        if (actionCommand != null) {
	    if (actionCommand instanceof ActionEvent) {
	        cmd = ((ActionEvent)actionCommand).getActionCommand();
	    } else {
	        cmd = actionCommand.toString();
	    }
	}
	if (cmd == null) {
	    // do nothing
	} else if (cmd.equals(CMD_REPLACE)) {
	    System.out.println("your replace code here...");
	} else if (cmd.equals(CMD_CANCEL)) {
	    System.out.println("your cancel code here...");
	}
	setVisible(false);
	dispose();
    } // windowAction()
  
    /**
     * 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);

        FileExistsDialog dialog = new FileExistsDialog(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 FileExistsDialog