//*****************************************************************************
/*
** FILE:   da_DatabaseDriverDialog.java
**
** Copyright 1998 Steve Withall.
**
** HISTORY:
**    26Apr98  stevew  Created.
*/
package da;

import eh.eh_Debug;

import com.sun.java.swing.Box;
import com.sun.java.swing.DefaultListModel;
import com.sun.java.swing.JButton;
import com.sun.java.swing.JDialog;
import com.sun.java.swing.JLabel;
import com.sun.java.swing.JList;
import com.sun.java.swing.JOptionPane;
import com.sun.java.swing.JPanel;
import com.sun.java.swing.JScrollPane;
import com.sun.java.swing.JTextField;

import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.DriverPropertyInfo;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import java.awt.BorderLayout;
import java.awt.Frame;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.Point;

import java.util.Enumeration;

import java.lang.Class;
import java.lang.StringBuffer;

//*****************************************************************************
/**
 * A dialog to list the database drivers currently loaded, and to load new ones.
 */
public class da_DatabaseDriverDialog extends JDialog
{
    DefaultListModel  DriverListModel = new DefaultListModel();

    Frame             ParentFrame     = null;

    /** List box in which all debug output is displayed. */
    JList        DriverList;

    JScrollPane  DriverListScrollPane;

    // Attributes relating to the name of a new driver class file to load.
    JLabel       ClassNameLabel     = new JLabel("Driver class name");
    JTextField   ClassNameTextField = new JTextField(30);

    // Buttons.
    JButton      LoadButton  = new JButton("Load");
    JButton      CloseButton = new JButton("Close");

    //*****************************************************************************
    /**
     * Constructor.
     */
    public da_DatabaseDriverDialog(Frame  InputParentFrame)
    {
	    super(InputParentFrame, "Database drivers", true);
	    ParentFrame = InputParentFrame;

	    // Load icon image.
//	    Image  IconImage   = Toolkit.getDefaultToolkit().getImage("df/images/da_DatabaseDriverIcon.gif");
//	    InputParentFrame.setIconImage(IconImage);

	    getContentPane().setLayout(new BorderLayout() );

	    DriverList = new JList(DriverListModel);
        loadDriverList();

	    DriverListScrollPane = new JScrollPane(DriverList);
        getContentPane().add("Center", DriverListScrollPane);

        initBottomPanel();

        Point  ParentLocation = InputParentFrame.getLocation();
        setBounds(ParentLocation.x + 40, ParentLocation.y + 110, 660, 180);
        show();
    }

    //*****************************************************************************
    /**
     * Initialise the input/control panel at the bottom of the dialog.
     */
    private void initBottomPanel()
    {
        eh_Debug.add(7, "da_DatabaseDriverDialog.InitBottomPanel");
        JPanel  BottomPanel = new JPanel();

        GridBagLayout      BottomPanelLayout      = new GridBagLayout();
        GridBagConstraints BottomPanelConstraints = new GridBagConstraints();
        BottomPanel.setLayout(BottomPanelLayout);
        BottomPanelConstraints.gridwidth = 1;

        // Class name for new driver.
        BottomPanelConstraints.insets    = new Insets(4, 4, 4, 4);
        BottomPanelConstraints.anchor    = GridBagConstraints.WEST;
        BottomPanel.add(ClassNameLabel);

        BottomPanelLayout.setConstraints(ClassNameTextField, BottomPanelConstraints);
        BottomPanel.add(ClassNameTextField);

        BottomPanelConstraints.gridwidth = GridBagConstraints.REMAINDER;
        BottomPanelLayout.setConstraints(LoadButton, BottomPanelConstraints);
        BottomPanel.add(LoadButton);

        // The bottom buttons.
        Box  ButtonBox = Box.createHorizontalBox();
        ButtonBox.add(CloseButton);

        BottomPanelConstraints.anchor    = GridBagConstraints.SOUTH;
        BottomPanelConstraints.fill      = GridBagConstraints.HORIZONTAL;
        BottomPanelConstraints.gridwidth = 3;  // The number of horizontal cells
        BottomPanelLayout.setConstraints(ButtonBox, BottomPanelConstraints);
        BottomPanel.add(ButtonBox);

    	LoadButton.addActionListener(new LoadButtonListener() );
    	CloseButton.addActionListener(new CloseButtonListener() );

	    getContentPane().add("South", BottomPanel);
	    return;
    }

    //*****************************************************************************
    /**
     * Load the list of details about the loaded drivers.
     */
    private void loadDriverList()
    {
        DriverListModel.removeAllElements();

        Enumeration  DriverEnumeration   = DriverManager.getDrivers();
        Object       CurrentDriverObject = null;
        while (DriverEnumeration.hasMoreElements() )
        {
            CurrentDriverObject = DriverEnumeration.nextElement();
            addDriverToList(CurrentDriverObject);
        }
    }

    //*****************************************************************************
    /**
     * Add driver to the list displayed on the screen.
     */
    private void addDriverToList(Object  InputDriverObject)
    {
        eh_Debug.add(7, "da_DatabaseDriverDialog.addDriverToList: Driver '"
                              + InputDriverObject.toString() + "'");
        Driver        CurrentDriver = (Driver)InputDriverObject;
        StringBuffer  ListEntry     = new StringBuffer(InputDriverObject.toString());

        try
        {
            String                DriverUrl    = new String();
            DriverPropertyInfo[]  PropertyInfo = CurrentDriver.getPropertyInfo(DriverUrl, null);

            if (PropertyInfo.length > 0)
                ListEntry.append("; properties: ");

            for (int  PropertyIndex = 0;
                 PropertyIndex < PropertyInfo.length;
                 PropertyIndex++)
            {
                ListEntry.append(" " + PropertyInfo[PropertyIndex].name
                                     + " = " + PropertyInfo[PropertyIndex].value);
                if (PropertyInfo[PropertyIndex].description != null)
                    ListEntry.append(" (" + PropertyInfo[PropertyIndex].description + ")");
            }
        }
        catch (Exception InputException)
        {
	        eh_Debug.add(5, "Cannot get property info for '"
	                          + InputDriverObject.toString() + "': "
	                          + InputException);
        }

        ListEntry.append("; version " + CurrentDriver.getMajorVersion()
                                 + "." + CurrentDriver.getMinorVersion() );
        if (CurrentDriver.jdbcCompliant() )
            ListEntry.append("; JDBC compliant");
        else
            ListEntry.append("; NOT fully JDBC compliant");

        DriverListModel.addElement(ListEntry.toString() );
    }

    //*****************************************************************************
    // Button listener inner classes.
    //*****************************************************************************
    /**
     * Handle pressing of the "Load" button. Load the named driver class and then
     * display its details in the list.
     */
    class LoadButtonListener implements ActionListener
    {
        public void actionPerformed(ActionEvent  InputEvent)
        {
            String  NewDriverClassName = ClassNameTextField.getText();

            try
            {
                // Load the named driver class.
                Class  DriverClass = Class.forName(NewDriverClassName);
                loadDriverList();
            }
            catch (Exception InputException)
            {
		        Object[]  MessageArray = new Object[2];
		        MessageArray[0] = "Error loading driver class '" + NewDriverClassName + "':";
		        MessageArray[1] = InputException.toString();

		        String[]  OptionButtonLabel = { "OK" };
		        JOptionPane.showOptionDialog(ParentFrame,
		                                     MessageArray,
		                                     "Database driver error",
		                                     JOptionPane.DEFAULT_OPTION,
		                                     JOptionPane.ERROR_MESSAGE,
		                                     null,
		                                     OptionButtonLabel,
		                                     OptionButtonLabel[0]);
	            eh_Debug.add(2, (String)MessageArray[0]);
                return;
            }
        }
    }

    //*****************************************************************************
    /**
     * Handle pressing of the "Close" button. Close this dialog, and do nothing
     * else.
     */
    class CloseButtonListener implements ActionListener
    {
        public void actionPerformed(ActionEvent  InputEvent)
        {
            dispose();
        }
    }
}
//*****************************************************************************
