package org.greenstone.gatherer.cdm;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.EventListener;
import javax.swing.event.EventListenerList;

import org.greenstone.gatherer.Configuration;
import org.greenstone.gatherer.Dictionary;
import org.greenstone.gatherer.Gatherer;
import org.greenstone.gatherer.gui.GLIButton;
import org.greenstone.gatherer.gui.ModalDialog;
import org.greenstone.gatherer.gui.TestingPreparation;

public class DatabaseTypeManager
{

	/** The size of this new collection dialog box. */
	static private Dimension DIALOG_SIZE = new Dimension(600, 280);

	static final public String DATABASE_TYPE_GDBM = "gdbm";
	static final public String DATABASE_TYPE_JDBM = "jdbm";
	static final public String DATABASE_TYPE_SQLITE = "sqlite";

	static final public String DATABASE_TYPE_GDBM_STR = "GDBM";
	static final public String DATABASE_TYPE_JDBM_STR = "JDBM";
	static final public String DATABASE_TYPE_SQLITE_STR = "SQLITE";

	static final public String[] DATABASE_TYPES = { DATABASE_TYPE_GDBM, DATABASE_TYPE_JDBM, DATABASE_TYPE_SQLITE };

	private EventListenerList listeners = null;
	/** the databasetype element in the config file - uses CollectionMeta */
	public CollectionMeta database_type_meta = null;
	private Control controls = null;

	protected DatabaseTypeManager manager = null;

	public DatabaseTypeManager()
	{
		database_type_meta = new CollectionMeta(CollectionDesignManager.collect_config.getDatabaseType());
		if (getDatabaseType().equals(""))
		{
			database_type_meta.setValue(DATABASE_TYPE_GDBM);
			// must have an old collection, assume MG
		}
		listeners = new EventListenerList();
		manager = this;
	}

	public void addDatabaseTypeListener(DatabaseTypeListener listener)
	{
		listeners.add(DatabaseTypeListener.class, listener);
	}

	protected void notifyListeners(String new_database_type)
	{
		Object[] concerned = listeners.getListenerList();
		for (int i = 0; i < concerned.length; i++)
		{
			if (concerned[i] == DatabaseTypeListener.class)
			{
				((DatabaseTypeListener) concerned[i + 1]).databaseTypeChanged(new_database_type);
			}
		}
		concerned = null;
	}

	public void promptForNewDatabaseType()
	{

		DatabaseTypePrompt dtp = new DatabaseTypePrompt(database_type_meta.getValue(CollectionMeta.TEXT));
	}

	public boolean isGDBM()
	{

		return getDatabaseType().equals(DATABASE_TYPE_GDBM);
	}

	public boolean isJDBM()
	{

		return getDatabaseType().equals(DATABASE_TYPE_JDBM);
	}

	public boolean isSQLITE()
	{

		return getDatabaseType().equals(DATABASE_TYPE_SQLITE);
	}

	public String getDatabaseType()
	{
		return database_type_meta.getValue(CollectionMeta.TEXT);
	}

	public Control getControls()
	{
		if (controls == null)
		{
			controls = new DatabaseTypeControl();
		}
		return controls;
	}

	public interface DatabaseTypeListener extends EventListener
	{
		public void databaseTypeChanged(String new_database_type);
	}

	private class DatabaseTypeControl extends JPanel implements Control, DatabaseTypeListener
	{

		JLabel label = null;
		JButton change_button = null;

		public DatabaseTypeControl()
		{
			super();
			this.setComponentOrientation(Dictionary.getOrientation());

			JPanel spacer_panel = new JPanel();
			spacer_panel.setComponentOrientation(Dictionary.getOrientation());

			JPanel main_panel = new JPanel();
			main_panel.setComponentOrientation(Dictionary.getOrientation());
			/*
			 * may be CDM.DatabaseTypeManager.gdbm,
			 * CDM.DatabaseTypeManager.jdbm, CDM.DatabaseTypeManager.sqlite
			 */
			label = new JLabel(Dictionary.get("CDM.DatabaseTypeManager.Current_Type", getDatabaseTypeString(getDatabaseType())));
			label.setComponentOrientation(Dictionary.getOrientation());

			change_button = new GLIButton(Dictionary.get("CDM.DatabaseTypeManager.Change"), Dictionary.get("CDM.DatabaseTypeManager.Change_Tooltip"));

			change_button.addActionListener(new ActionListener()
			{
				public void actionPerformed(ActionEvent event)
				{
					promptForNewDatabaseType();
				}
			});

			main_panel.setLayout(new BorderLayout(10, 10));
			main_panel.add(label, BorderLayout.CENTER);
			main_panel.add(change_button, BorderLayout.LINE_END);

			setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 0));
			setLayout(new BorderLayout());
			add(spacer_panel, BorderLayout.CENTER);
			add(main_panel, BorderLayout.LINE_END);

			manager.addDatabaseTypeListener(this);

			TestingPreparation.setNamesRecursivelyForControl(this);
		}

		public void loseFocus()
		{
		}

		public void gainFocus()
		{
		}

		public void destroy()
		{
		}

		private String getDatabaseTypeString(String database_type)
		{
			if (database_type.equals(DATABASE_TYPE_GDBM))
			{
				return DATABASE_TYPE_GDBM_STR;
			}
			if (database_type.equals(DATABASE_TYPE_JDBM))
			{
				return DATABASE_TYPE_JDBM_STR;
			}
			if (database_type.equals(DATABASE_TYPE_SQLITE))
			{
				return DATABASE_TYPE_SQLITE_STR;
			}
			return "";
		}

		public void databaseTypeChanged(String new_database_type)
		{
			label.setText(Dictionary.get("CDM.DatabaseTypeManager.Current_Type", getDatabaseTypeString(new_database_type)));
		}
	}

	private class DatabaseTypePrompt extends ModalDialog
	{

		private JDialog self;

		private JRadioButton gdbm_button = null;
		private JRadioButton jdbm_button = null;
		private JRadioButton sqlite_button = null;

		private JTextArea description_textarea = null;

		JButton ok_button = null;
		JButton cancel_button = null;

		public DatabaseTypePrompt(String current_database_type)
		{
			super(Gatherer.g_man, true);
			this.self = this;
			setSize(DIALOG_SIZE);
			setTitle(Dictionary.get("CDM.DatabaseTypeManager.Title"));
			this.setComponentOrientation(Dictionary.getOrientation());
			gdbm_button = new JRadioButton(DATABASE_TYPE_GDBM_STR);
			gdbm_button.setComponentOrientation(Dictionary.getOrientation());
			gdbm_button.setActionCommand(DATABASE_TYPE_GDBM);
			jdbm_button = new JRadioButton(DATABASE_TYPE_JDBM_STR);
			jdbm_button.setComponentOrientation(Dictionary.getOrientation());
			jdbm_button.setActionCommand(DATABASE_TYPE_JDBM);
			sqlite_button = new JRadioButton(DATABASE_TYPE_SQLITE_STR);
			sqlite_button.setComponentOrientation(Dictionary.getOrientation());
			sqlite_button.setActionCommand(DATABASE_TYPE_SQLITE);

			DatabaseTypeButtonListener dtbl = new DatabaseTypeButtonListener();
			gdbm_button.addActionListener(dtbl);
			jdbm_button.addActionListener(dtbl);
			sqlite_button.addActionListener(dtbl);

			ButtonGroup database_type_group = new ButtonGroup();
			database_type_group.add(gdbm_button);
			database_type_group.add(jdbm_button);
			if (!Gatherer.GS3)
			{
				database_type_group.add(sqlite_button);
			}
			if (current_database_type != null)
			{
				if (current_database_type.equals(DATABASE_TYPE_GDBM))
				{
					gdbm_button.setSelected(true);
				}
				else if (current_database_type.equals(DATABASE_TYPE_JDBM))
				{
					jdbm_button.setSelected(true);
				}
				else if (current_database_type.equals(DATABASE_TYPE_SQLITE) && !Gatherer.GS3)
				{
					sqlite_button.setSelected(true);
				}
			}

			JPanel radio_pane = new JPanel();
			radio_pane.setLayout(new GridLayout(3, 1));
			radio_pane.add(gdbm_button);
			radio_pane.add(jdbm_button);
			if (!Gatherer.GS3)
			{
				radio_pane.add(sqlite_button);
			}
			radio_pane.setComponentOrientation(Dictionary.getOrientation());

			description_textarea = new JTextArea();
			description_textarea.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
			/*
			 * may be CDM.DatabaseTypeManager.gdbm_Description,
			 * CDM.DatabaseTypeManager.jdbm_Description,
			 * CDM.DatabaseTypeManager.sqlite_Description
			 */
			description_textarea.setText(Dictionary.get("CDM.DatabaseTypeManager." + current_database_type + "_Description"));
			description_textarea.setLineWrap(true);
			description_textarea.setWrapStyleWord(true);
			description_textarea.setComponentOrientation(Dictionary.getOrientation());

			cancel_button = new GLIButton(Dictionary.get("General.Cancel"), Dictionary.get("General.Cancel_Tooltip"));

			cancel_button.addActionListener(new ActionListener()
			{
				public void actionPerformed(ActionEvent event)
				{
					self.dispose();
				}
			});

			ok_button = new GLIButton(Dictionary.get("General.OK"), Dictionary.get("General.OK_Tooltip"));

			ok_button.addActionListener(new ActionListener()
			{
				public void actionPerformed(ActionEvent event)
				{
					String new_database_type = DATABASE_TYPE_GDBM;
					if (gdbm_button.isSelected())
					{
						new_database_type = DATABASE_TYPE_GDBM;
					}
					else if (jdbm_button.isSelected())
					{
						new_database_type = DATABASE_TYPE_JDBM;
					}
					else if (sqlite_button.isSelected())
					{
						new_database_type = DATABASE_TYPE_SQLITE;
					}
					if (!database_type_meta.getValue(CollectionMeta.TEXT).equals(new_database_type))
					{
						manager.notifyListeners(new_database_type);
						database_type_meta.setValue(new_database_type);
					}
					self.dispose();
				}
			});
			// tell the CDM that we have (possibly) changed
			ok_button.addActionListener(CollectionDesignManager.databasecol_change_listener);
			JPanel button_pane = new JPanel();
			button_pane.setLayout(new GridLayout(1, 2));
			button_pane.add(ok_button);
			button_pane.add(cancel_button);
			button_pane.setComponentOrientation(Dictionary.getOrientation());

			JPanel content_pane = (JPanel) getContentPane();
			content_pane.setOpaque(true);
			content_pane.setLayout(new BorderLayout());
			content_pane.add(radio_pane, BorderLayout.NORTH);
			content_pane.add(new JScrollPane(description_textarea), BorderLayout.CENTER);
			content_pane.add(button_pane, BorderLayout.SOUTH);
			content_pane.setComponentOrientation(Dictionary.getOrientation());
			
			TestingPreparation.setIndividualSubcomponentNames(this,
							      gdbm_button, jdbm_button,
							      sqlite_button);
			
			// Center and display.
			Dimension screen_size = Configuration.screen_size;
			this.setLocation((screen_size.width - DIALOG_SIZE.width) / 2, (screen_size.height - DIALOG_SIZE.height) / 2);
			this.setVisible(true); // blocks until the dialog is killed

		}

		public void loseFocus()
		{

		}

		public void gainFocus()
		{

		}

		public void destroy()
		{

		}

		private class DatabaseTypeButtonListener implements ActionListener
		{

			public void actionPerformed(ActionEvent event)
			{
				description_textarea.setText(Dictionary.get("CDM.DatabaseTypeManager." + event.getActionCommand() + "_Description"));
			}
		}
	}
}
