//------------------------------------------------------------------------------
// Copyright (c) 2005, 2006 IBM Corporation and others.
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// which accompanies this distribution, and is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// Contributors:
// IBM Corporation - initial implementation
//------------------------------------------------------------------------------
package org.eclipse.epf.library.ui.actions;

import java.util.Collection;
import java.util.Iterator;

import org.eclipse.epf.library.LibraryPlugin;
import org.eclipse.epf.library.events.ILibraryChangeListener;
import org.eclipse.epf.library.prefs.LibraryPreferenceConstants;
import org.eclipse.epf.library.services.LibraryProcessor;
import org.eclipse.epf.library.services.SafeUpdateController;
import org.eclipse.epf.library.ui.LibraryUIResources;
import org.eclipse.jface.action.ContributionItem;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.FocusListener;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.CoolBar;
import org.eclipse.swt.widgets.CoolItem;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.swt.widgets.ToolItem;

import com.ibm.uma.MethodConfiguration;

/**
 * Adds the Configuration comboxbox to the system toolbar.
 * 
 * @author Bingxue Xu
 * @author Kelvin Low
 * @since 1.0
 */
public class ConfigurationContributionItem extends ContributionItem implements
		SelectionListener, FocusListener {

	protected Combo addressBox;

	protected ToolItem item;

	protected CoolItem coolItem;

	public static final String CONTRIBUTION_ID = ConfigurationContributionItem.class
			.getName();

	private static final String SELECT_CONFIGURATION = LibraryUIResources
			.getString("LibraryUI.selectConfigLabel.text"); //$NON-NLS-1$

	private static Combo configCombo;

	private static boolean needUpdate = false;

	private static boolean needCleanList = false;

	private static boolean needSpecialUpdare = false;

	private static String currentSelectconfig;

	private ILibraryChangeListener libListener;

	/**
	 * Creates a new instance.
	 */
	public ConfigurationContributionItem(IAction action) {
	}

	public void fill(ToolBar parent, int index) {
		item = new ToolItem(parent, SWT.SEPARATOR);
		Control box = createControl(parent);
		item.setControl(box);
		item.setWidth(240);
	}

	public void fill(CoolBar coolBar, int index) {
		Control box = createControl(coolBar);

		int flags = SWT.DROP_DOWN;
		if (index >= 0) {
			coolItem = new CoolItem(coolBar, flags, index);
		} else {
			coolItem = new CoolItem(coolBar, flags);
		}
		// Set the back reference.
		coolItem.setData(this);

		// Add the toolbar to the CoolItem widget.
		coolItem.setControl(box);

		// If the toolbar item exists then adjust the size of the cool item.
		Point toolBarSize = box.computeSize(SWT.DEFAULT, SWT.DEFAULT);

		// Set the preffered size to the size of the toolbar plus trim.
		coolItem.setMinimumSize(toolBarSize);
		coolItem.setPreferredSize(toolBarSize);
		coolItem.setSize(toolBarSize);
	}

	public void fill(Composite parent) {
		createControl(parent);
	}

	private Control createControl(Composite parent) {
		configCombo = new Combo(parent, SWT.DROP_DOWN | SWT.READ_ONLY);
		configCombo.setVisibleItemCount(10);
		configCombo.addSelectionListener(this);
		configCombo.addFocusListener(this);

		// Listen to the Library changes and automatically update the
		// configuration list in
		// the combo box.
		libListener = new ILibraryChangeListener() {
			public void libraryChanged(int option, Collection changedItems) {
				if (option == ILibraryChangeListener.OPTION_CONFIGURATION_SELECTED) {
					String currentConfig = LibraryProcessor.getInstance()
							.getCurrentConfiguration();
					selectConfiguration(currentConfig);
				} else {
					if (option == ILibraryChangeListener.OPTION_CREATED
							|| option == ILibraryChangeListener.OPTION_LOADED) {
						needCleanList = true;
						needUpdate = true;
						updateComboListSpecial();
					} else if (option == ILibraryChangeListener.OPTION_CHANGED
							|| option == ILibraryChangeListener.OPTION_DELETED) {
						if (changedItems != null) {
							for (Iterator it = changedItems.iterator(); it
									.hasNext();) {
								Object element = it.next();
								if (element instanceof MethodConfiguration) {
									needUpdate = true;
									updateComboList(true);
									if ((option == ILibraryChangeListener.OPTION_DELETED)
											&& ((MethodConfiguration) element)
													.getName()
													.equals(currentSelectconfig)) {
										needSpecialUpdare = true;
									}
									break;
								}
							}
						}
					}

					if (needSpecialUpdare) {
						updateComboListSpecial();
						needSpecialUpdare = false;
					}
				}
			}
		};

		LibraryProcessor.getInstance().addListener(libListener);

		LibraryProcessor lp = LibraryProcessor.getInstance();
		String[] configNames = lp.getConfigurationNames();

		// Check if the config remembered from last session is one of them.
		int lastSessionConfigIdx = chooseSelectedIdex(configNames);
		if (configNames != null && configNames.length > 0) {
			if (lastSessionConfigIdx < 0)
				configCombo.add(SELECT_CONFIGURATION);
			for (int i = 0; i < configNames.length; i++) {
				String configName = configNames[i];
				if (configName != null) {
					configCombo.add(configName);
				}
			}
		} else {
			configCombo.add(SELECT_CONFIGURATION);
		}

		if (lastSessionConfigIdx < 0)
			configCombo.select(0);
		else {
			configCombo.select(lastSessionConfigIdx);
			currentSelectconfig = getSavedLastConfig();
			performSelectionChanged();
		}

		configCombo.setEnabled(true);

		return configCombo;
	}

	public void focusGained(FocusEvent e) {
		if (needUpdate) {
			updateComboList(true);
			needUpdate = false;
		}
	}

	public void focusLost(FocusEvent e) {
	}

	public void widgetSelected(SelectionEvent e) {
		int selectedIndex = configCombo.getSelectionIndex();
		if (selectedIndex > 0) {
			if (configCombo.getItem(0).equals(SELECT_CONFIGURATION)) {
				configCombo.remove(0);
				configCombo.select(selectedIndex - 1);
			}
		}

		int currentIdx = configCombo.getSelectionIndex();
		currentSelectconfig = configCombo.getItem(currentIdx);

		performSelectionChanged();
	}

	public void widgetDefaultSelected(SelectionEvent e) {
	}

	public static void refresh() {
		needCleanList = true;
		updateComboList(true);
	}
	
	/**
	 * Updates the Configuration combobox content.
	 */
	private static void updateComboList(final boolean setCurrentConfig) {
		SafeUpdateController.syncExec(new Runnable() {
			public void run() {
				try {
					if (configCombo.isDisposed() || configCombo == null) {
						return;
					}
					
					int index = configCombo.getSelectionIndex();
					String currentSelection = ""; //$NON-NLS-1$
					if (index >= 0) {
						currentSelection = configCombo.getItem(index);
					}
					
					if (needCleanList) {
						configCombo.removeAll();
						needCleanList = false;
					}

					index = -1;
					configCombo.setEnabled(true);
					LibraryProcessor lp = LibraryProcessor.getInstance();
					String[] configNames = lp.getConfigurationNames();
					configCombo.removeAll();

					if (configNames != null && configNames.length > 0) {
						for (int i = 0; i < configNames.length; i++) {
							String configName = configNames[i];
							if (configName != null) {
								configCombo.add(configName);
								if (configName.equals(currentSelection)) {
									index = i;
								}
							}
						}
					} else {
						index = 0;
						configCombo.add(SELECT_CONFIGURATION);
						configCombo.select(0);
					}

					if (index >= 0) {
						configCombo.select(index);
					}

					if (index == -1) {
						configCombo.add(SELECT_CONFIGURATION, 0);
						configCombo.select(0);
					}

					int currentIdx = configCombo.getSelectionIndex();
					currentSelectconfig = configCombo.getItem(currentIdx);

					configCombo.setVisibleItemCount(10);
					if(setCurrentConfig) {
					performSelectionChanged();
					}
					else {
						saveSelectedConfigIntoPersistence();
					}
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	private static void updateComboListSpecial() {
		SafeUpdateController.syncExec(new Runnable() {
			public void run() {
				if (needCleanList) {
					configCombo.removeAll();
					currentSelectconfig = null;
				}

				try {
					if (currentSelectconfig != null) {
						configCombo.remove(currentSelectconfig);
					}
					configCombo.add(SELECT_CONFIGURATION, 0);
					configCombo.select(0);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * Selects the given Configuration.
	 * 
	 * @param cfgName
	 *            The name of the Configuration.
	 */
	private void selectConfiguration(String cfgName) {
		if (cfgName == null || cfgName.equals(currentSelectconfig)) {
			return;
		}

		updateComboList(false);

		// TODO: This may need to be in an aync UI thred
		// Get the current dropdown config name.
		int currentIdx = configCombo.getSelectionIndex();
		String currentName = ""; //$NON-NLS-1$
		if (currentIdx >= 0) {
			currentName = configCombo.getItem(currentIdx);
		}

		if (!currentName.equals(cfgName)) {
			// Find the index of the new cfgname in the combo box.
			int selectIndex = -1;
			for (int i = 0; i < configCombo.getItemCount(); i++) {
				if (configCombo.getItem(i).equals(cfgName)) {
					selectIndex = i;
					break;
				}
			}

			if (selectIndex > 0
					&& (configCombo.getItem(0).equals(SELECT_CONFIGURATION))) {
				configCombo.remove(0);
				selectIndex--;
			}

			if (selectIndex != -1) {
				configCombo.select(selectIndex);
			}

			currentIdx = configCombo.getSelectionIndex();
			currentSelectconfig = configCombo.getItem(currentIdx);

			// this method gets called by LibraryProcessor.setCurrentConfiguration(), so don't try
			// to call back LibraryProcessor.setCurrentConfiguration()
			//
//			performSelectionChanged();
			
			// TODO: it is not very efficient to save LibraryPlugin preferences every time the currently selected configuration is changed
			// to save this configuration's name
			//
			saveSelectedConfigIntoPersistence();
		}
	}

	private static void performSelectionChanged() {
		LibraryProcessor lp = LibraryProcessor.getInstance();
		lp.setCurrentConfiguration(currentSelectconfig);
		saveSelectedConfigIntoPersistence();
	}

	private static int chooseSelectedIdex(String[] configNames) {
		int index = -1;
		String lastSessionConfig = getSavedLastConfig();
		if (lastSessionConfig != null) {
			for (int i = 0; i < configNames.length; i++) {
				if (lastSessionConfig.equals(configNames[i])) {
					index = i;
					break;
				}
			}
		}
		return index;
	}

	private static void saveSelectedConfigIntoPersistence() {
		IPreferenceStore store = LibraryPlugin.getDefault()
				.getPreferenceStore();
		store
				.setValue(
						LibraryPreferenceConstants.PREF_SELECTED_CONFIG_IN_LAST_SESSION,
						currentSelectconfig);
		LibraryPlugin.getDefault().savePluginPreferences();
	}

	private static String getSavedLastConfig() {
		IPreferenceStore store = LibraryPlugin.getDefault()
				.getPreferenceStore();
		return store
				.getString(LibraryPreferenceConstants.PREF_SELECTED_CONFIG_IN_LAST_SESSION);
	}

}