/*******************************************************************************
 * Copyright (c) 2000, 2008 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 API and implementation
 *     Oracle - copied and modified from NewJavaEEDropDownAction and NewTypeDropDownAction
 *******************************************************************************/
package org.eclipse.jpt.ui.internal.wizards;

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.swt.widgets.Control;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.Shell;

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.window.Window;
import org.eclipse.jface.wizard.WizardDialog;
import org.eclipse.ui.INewWizard;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.IWorkbenchWindowPulldownDelegate2;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.plugin.AbstractUIPlugin;

import org.eclipse.jdt.ui.actions.AbstractOpenWizardAction;
import org.eclipse.jdt.internal.ui.util.CoreUtility;
import org.eclipse.jdt.internal.ui.util.PixelConverter;


/**
 * A type wizard is added to the type drop down if it has a paramater 'javatype':
 *     <wizard
 *         name="My JPT Wizard"
 *         icon="icons/wiz.gif"
 *         category="mycategory"
 *         id="xx.MyWizard">
 *         <class class="org.xx.MyWizard">
 *             <parameter name="jptartifact" value="true"/>
 *         </class> 
 *         <description>
 *             My JPT Wizard
 *         </description>
 *      </wizard>
 */
public class NewEntityDropDownAction extends Action implements IMenuCreator, IWorkbenchWindowPulldownDelegate2 {

	public static class OpenJptWizardAction extends AbstractOpenWizardAction implements Comparable<Object>  {

		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 static final String TAG_DESCRIPTION = "description";	//$NON-NLS-1$
		
		private IConfigurationElement fConfigurationElement;
		private int menuIndex;

		public OpenJptWizardAction(IConfigurationElement element) {
			this.fConfigurationElement= element;
			setText(element.getAttribute(ATT_NAME));
			
			String description= getDescriptionFromConfig(this.fConfigurationElement);
			setDescription(description);
			setToolTipText(description);
			setImageDescriptor(getIconFromConfig(this.fConfigurationElement));
			setMenuIndex(getMenuIndexFromConfig(this.fConfigurationElement));
		}
		
		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 AbstractUIPlugin.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;
		}
		
		@Override
		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);
			}
		}

		@Override
		protected INewWizard createWizard() throws CoreException {
			return (INewWizard) CoreUtility.createExtension(fConfigurationElement, ATT_CLASS);
		}

		public int getMenuIndex() {
			return this.menuIndex;
		}

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

		public int compareTo(Object o) {
			OpenJptWizardAction action = (OpenJptWizardAction) o;
			return getMenuIndex() - action.getMenuIndex();
		}

	}
	
	
	
	private final static String TAG_WIZARD = "wizard";//$NON-NLS-1$
	private final static String ATT_JPTARTIFACT = "jptartifact";//$NON-NLS-1$
	
	private final static String TAG_PARAMETER = "parameter";//$NON-NLS-1$
	private final static String TAG_NAME = "name";//$NON-NLS-1$
	private final static String TAG_VALUE = "value";//$NON-NLS-1$
	protected final static String ATT_MENUINDEX = "menuIndex";//$NON-NLS-1$
	
	private static final String PL_NEW = "newWizards"; //$NON-NLS-1$
	private static final String TAG_CLASS = "class"; //$NON-NLS-1$
	
	private Menu fMenu;
	
	private Shell fWizardShell;
	
	public NewEntityDropDownAction() {
		this.fMenu= null;
		setMenuCreator(this);
		//PlatformUI.getWorkbench().getHelpSystem().setHelp(this, IJavaHelpContextIds.OPEN_CLASS_WIZARD_ACTION);
	}

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

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

	public Menu getMenu(Control parent) {
		if (this.fMenu == null) {
			this.fMenu = new Menu(parent);
			OpenJptWizardAction[] actions = getActionFromDescriptors();
			for (int i = 0; i < actions.length; i++) {
				OpenJptWizardAction curr = actions[i];
				curr.setShell(this.fWizardShell);
				ActionContributionItem item = new ActionContributionItem(curr);
				item.fill(this.fMenu, -1);				
			}			
		
		}
		return this.fMenu;
	}
	
	@Override
	public void run() {
		getDefaultAction().run();
	}
	
	public Action getDefaultAction() {
		Action[] actions = getActionFromDescriptors();
		if (actions.length > 0)
			return actions[0];
		return null;
	}
	
	public static OpenJptWizardAction[] getActionFromDescriptors() {
		ArrayList<OpenJptWizardAction> containers= new ArrayList<OpenJptWizardAction>();
		
		IExtensionPoint extensionPoint = Platform.getExtensionRegistry().getExtensionPoint(PlatformUI.PLUGIN_ID, PL_NEW);
		if (extensionPoint != null) {
			IConfigurationElement[] elements = extensionPoint.getConfigurationElements();
			for (int i = 0; i < elements.length; i++) {
				IConfigurationElement element= elements[i];
				if (element.getName().equals(TAG_WIZARD) && isJptArtifactWizard(element)) {
					containers.add(new OpenJptWizardAction(element));
				}
			}
		}
		OpenJptWizardAction[] actions = containers.toArray(new OpenJptWizardAction[containers.size()]);
		Arrays.sort(actions);
		return actions;
	}
		
	private static boolean isJptArtifactWizard(IConfigurationElement element) {
		IConfigurationElement[] classElements= element.getChildren(TAG_CLASS);
		if (classElements.length > 0) {
			for (int i= 0; i < classElements.length; i++) {
				IConfigurationElement[] paramElements= classElements[i].getChildren(TAG_PARAMETER);
				for (int k = 0; k < paramElements.length; k++) {
					IConfigurationElement curr= paramElements[k];
					if (ATT_JPTARTIFACT.equals(curr.getAttribute(TAG_NAME))) {
						return Boolean.valueOf(curr.getAttribute(TAG_VALUE)).booleanValue();
					}
				}
			}
		}
		return false;
	}
		
	public void init(IWorkbenchWindow window) {
		fWizardShell= window.getShell();
	}
	
	public void run(IAction action) {
		run();
	}
	
	public void selectionChanged(IAction action, ISelection selection) {
	}

}
