/*******************************************************************************
 * Copyright (c) 2007 SAP AG 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:
 * Kaloyan Raev, kaloyan.raev@sap.com - initial API and implementation
 *******************************************************************************/
package org.eclipse.jst.j2ee.internal.actions;

import java.util.ArrayList;
import java.util.Arrays;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jdt.internal.ui.util.CoreUtility;
import org.eclipse.jdt.internal.ui.util.PixelConverter;
import org.eclipse.jem.util.logger.proxy.Logger;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.ActionContributionItem;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IMenuCreator;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.window.Window;
import org.eclipse.jface.wizard.WizardDialog;
import org.eclipse.jst.j2ee.internal.plugin.J2EEUIPlugin;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.INewWizard;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.IWorkbenchWindowPulldownDelegate2;
import org.eclipse.ui.PlatformUI;

public abstract class NewJavaEEDropDownAction extends Action implements IMenuCreator, IWorkbenchWindowPulldownDelegate2 {

	public static class NewJavaEEWizardAction extends Action implements Comparable {

		private final static String ATT_NAME = "name";//$NON-NLS-1$
		private final static String ATT_CLASS = "class";//$NON-NLS-1$
		private final static String ATT_ICON = "icon";//$NON-NLS-1$
		private final static String TAG_DESCRIPTION = "description";	//$NON-NLS-1$

		private Shell fShell;
		private IStructuredSelection fSelection;
		private IConfigurationElement fConfigurationElement;
		
		private int menuIndex;

		public NewJavaEEWizardAction(IConfigurationElement element) {
			fConfigurationElement= element;
			setText(element.getAttribute(ATT_NAME));
			
			String description = getDescriptionFromConfig(fConfigurationElement);
			setDescription(description);
			setToolTipText(description);
			setImageDescriptor(getIconFromConfig(fConfigurationElement));
			setMenuIndex(getMenuIndexFromConfig(fConfigurationElement));
		}

		/* (non-Javadoc)
		 * @see org.eclipse.jface.action.Action#run()
		 */
		public void run() {
			Shell shell = getShell();
			try {
				INewWizard wizard = createWizard();
				wizard.init(PlatformUI.getWorkbench(), getSelection());
				
				WizardDialog dialog = new WizardDialog(shell, wizard);
				PixelConverter converter = new PixelConverter(JFaceResources.getDialogFont());
				dialog.setMinimumPageSize(converter.convertWidthInCharsToPixels(70), converter.convertHeightInCharsToPixels(20));
				dialog.create();
				int res = dialog.open();
				
				notifyResult(res == Window.OK);
			} catch (CoreException e) {
				Logger.getLogger().log(e);
			}
		}
		
		/**
		 * Returns the configured selection. If no selection has been configured using {@link #setSelection(IStructuredSelection)},
		 * the currently selected element of the active workbench is returned.
		 * @return the configured selection
		 */
		protected IStructuredSelection getSelection() {
			if (fSelection == null) {
				return evaluateCurrentSelection();
			}
			return fSelection;
		}
		
		private IStructuredSelection evaluateCurrentSelection() {
			IWorkbenchWindow window = J2EEUIPlugin.getActiveWorkbenchWindow();
			if (window != null) {
				ISelection selection = window.getSelectionService().getSelection();
				if (selection instanceof IStructuredSelection) {
					return (IStructuredSelection) selection;
				}
			}
			return StructuredSelection.EMPTY;
		}
		
		/**
		 * Configures the selection to be used as initial selection of the wizard. 
		 * @param selection the selection to be set or <code>null</code> to use the selection of the active workbench window
		 */
		public void setSelection(IStructuredSelection selection) {
			fSelection = selection;
		}
		
		/**
		 * Returns the configured shell. If no shell has been configured using {@link #setShell(Shell)},
		 * 	the shell of the currently active workbench is returned.
		 * @return the configured shell
		 */
		protected Shell getShell() {
			if (fShell == null) {
				return J2EEUIPlugin.getActiveWorkbenchShell();
			}
			return fShell;
		}
		
		/**
		 * Configures the shell to be used as parent shell by the wizard.
		 * @param shell the shell to be set or <code>null</code> to use the shell of the active workbench window
		 */
		public void setShell(Shell shell) {
			fShell = shell;
		}
		
		private String getDescriptionFromConfig(IConfigurationElement config) {
			IConfigurationElement [] children = config.getChildren(TAG_DESCRIPTION);
			if (children.length >= 1) {
				return children[0].getValue();
			}
			return ""; //$NON-NLS-1$
		}

		private ImageDescriptor getIconFromConfig(IConfigurationElement config) {
			String iconName = config.getAttribute(ATT_ICON);
			if (iconName != null) {
				return J2EEUIPlugin.imageDescriptorFromPlugin(config.getContributor().getName(), iconName);
			}
			return null;
		}
		
		private int getMenuIndexFromConfig(IConfigurationElement config) {
			IConfigurationElement[] classElements = config.getChildren(TAG_CLASS);
			if (classElements.length > 0) {
				for (IConfigurationElement classElement : classElements) {
					IConfigurationElement[] paramElements = classElement.getChildren(TAG_PARAMETER);
					for (IConfigurationElement paramElement : paramElements) {
						if (ATT_MENUINDEX.equals(paramElement.getAttribute(TAG_NAME))) {
							return Integer.parseInt(paramElement.getAttribute(TAG_VALUE));
						}
					}
				}
			}
			return Integer.MAX_VALUE;
		}
		
		protected INewWizard createWizard() throws CoreException {
			return (INewWizard) CoreUtility.createExtension(fConfigurationElement, ATT_CLASS);
		}

		public int getMenuIndex() {
			return menuIndex;
		}

		public void setMenuIndex(int menuIndex) {
			this.menuIndex = menuIndex;
		}

		public int compareTo(Object o) {
			NewJavaEEWizardAction action = (NewJavaEEWizardAction) o;
			return getMenuIndex() - action.getMenuIndex();
		}
	}
	
	protected final static String TAG_WIZARD = "wizard";//$NON-NLS-1$
	protected final static String TAG_PARAMETER = "parameter";//$NON-NLS-1$
	protected final static String TAG_NAME = "name";//$NON-NLS-1$
	protected final static String TAG_VALUE = "value";//$NON-NLS-1$
	protected final static String TAG_CLASS = "class"; //$NON-NLS-1$
	protected final static String ATT_MENUINDEX = "menuIndex";//$NON-NLS-1$
	protected final static String PL_NEW = "newWizards"; //$NON-NLS-1$
	
	protected Menu fMenu;
	
	protected Shell fWizardShell;
	
	public NewJavaEEDropDownAction() {
		fMenu = null;
		setMenuCreator(this);
	}

	public void dispose() {
		if (fMenu != null) {
			fMenu.dispose();
			fMenu = null;
		}
	}

	public Menu getMenu(Menu parent) {
		return null;
	}

	public Menu getMenu(Control parent) {
		if (fMenu == null) {
			fMenu = new Menu(parent);
			NewJavaEEWizardAction[] actions = getActionFromDescriptors();
			for (NewJavaEEWizardAction action : actions) {
				action.setShell(fWizardShell);
				ActionContributionItem item = new ActionContributionItem(action);
				item.fill(fMenu, -1);
			}			
		}
		return fMenu;
	}
	
	public void run() {
		getDefaultAction().run();
	}
	
	public Action getDefaultAction() {
		Action[] actions = getActionFromDescriptors();
		if (actions.length > 0)
			return actions[0];
		return null;
	}
	
	public NewJavaEEWizardAction[] getActionFromDescriptors() {
		ArrayList<NewJavaEEWizardAction> containers = new ArrayList<NewJavaEEWizardAction>();
		
		IExtensionPoint extensionPoint = Platform.getExtensionRegistry().getExtensionPoint(PlatformUI.PLUGIN_ID, PL_NEW);
		if (extensionPoint != null) {
			IConfigurationElement[] elements = extensionPoint.getConfigurationElements();
			for (IConfigurationElement element : elements) {
				if (element.getName().equals(TAG_WIZARD) && isJavaEEProjectWizard(element)) {
					containers.add(new NewJavaEEWizardAction(element));
				}
			}
		}
		
		NewJavaEEWizardAction[] actions = (NewJavaEEWizardAction[]) containers.toArray(new NewJavaEEWizardAction[containers.size()]);
		Arrays.sort(actions);
		return actions; 
	}
		
	protected boolean isJavaEEProjectWizard(IConfigurationElement element) {
		IConfigurationElement[] classElements = element.getChildren(TAG_CLASS);
		if (classElements.length > 0) {
			for (IConfigurationElement classElement : classElements) {
				IConfigurationElement[] paramElements = classElement.getChildren(TAG_PARAMETER);
				for (IConfigurationElement paramElement : paramElements) {
					if (getTypeAttribute().equals(paramElement.getAttribute(TAG_NAME))) {
						return Boolean.valueOf(paramElement.getAttribute(TAG_VALUE)).booleanValue();
					}
				}
			}
		}
		// old way, deprecated
		if (Boolean.valueOf(element.getAttribute(getTypeAttribute())).booleanValue()) {
			return true;
		}
		return false;
	}
		
	
	/* (non-Javadoc)
	 * @see org.eclipse.ui.IWorkbenchWindowActionDelegate#init(org.eclipse.ui.IWorkbenchWindow)
	 */
	public void init(IWorkbenchWindow window) {
		fWizardShell = window.getShell();
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.ui.IActionDelegate#run(org.eclipse.jface.action.IAction)
	 */
	public void run(IAction action) {
		run();
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.ui.IActionDelegate#selectionChanged(org.eclipse.jface.action.IAction, org.eclipse.jface.viewers.ISelection)
	 */
	public void selectionChanged(IAction action, ISelection selection) {
		
	}
	
	protected abstract String getTypeAttribute();

}
