/*******************************************************************************
 * Copyright (c) 2001, 2004 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
 *     Jens Lukowski/Innoopract - initial renaming/restructuring
 *     
 *******************************************************************************/
package org.eclipse.wst.sse.ui.internal.extension;



import java.util.StringTokenizer;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.ActionContributionItem;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IContributionItem;
import org.eclipse.swt.custom.BusyIndicator;
import org.eclipse.ui.help.WorkbenchHelp;
import org.eclipse.wst.sse.ui.internal.IActionValidator;
import org.eclipse.wst.sse.ui.internal.Logger;
import org.osgi.framework.Bundle;


/**
 * When 'action' tag is found in the registry, an object of this class is
 * created. It creates the appropriate action object and captures information
 * that is later used to add this action object into menu/tool bar. This class
 * is reused for global (workbench) menu/tool bar, popup menu actions, as well
 * as view's pulldown and local tool bar.
 */
public class ActionDescriptor {
	public static final String ATT_ACCELERATOR = "accelerator"; //$NON-NLS-1$
	public static final String ATT_CLASS = "class"; //$NON-NLS-1$
	public static final String ATT_DEFINITION_ID = "definitionId"; //$NON-NLS-1$
	public static final String ATT_DESCRIPTION = "description"; //$NON-NLS-1$
	public static final String ATT_DISABLEDICON = "disabledIcon"; //$NON-NLS-1$
	public static final String ATT_HELP_CONTEXT_ID = "helpContextId"; //$NON-NLS-1$
	public static final String ATT_HOVERICON = "hoverIcon"; //$NON-NLS-1$
	public static final String ATT_ICON = "icon"; //$NON-NLS-1$

	public static final String ATT_ID = "id"; //$NON-NLS-1$
	public static final String ATT_LABEL = "label"; //$NON-NLS-1$
	public static final String ATT_MENUBAR_PATH = "menubarPath"; //$NON-NLS-1$
	public static final String ATT_POPUPMENU_PATH = "popupmenuPath"; //$NON-NLS-1$
	public static final String ATT_STATE = "state"; //$NON-NLS-1$
	public static final String ATT_TOOLBAR_PATH = "toolbarPath"; //$NON-NLS-1$
	public static final String ATT_TOOLTIP = "tooltip"; //$NON-NLS-1$

	/**
	 * Creates an extension. If the extension plugin has not been loaded a
	 * busy cursor will be activated during the duration of the load.
	 * 
	 * @param element
	 *            the config element defining the extension
	 * @param classAttribute
	 *            the name of the attribute carrying the class
	 * @returns the extension object if successful. If an error occurs when
	 *          createing executable extension, the exception is logged, and
	 *          null returned.
	 */
	public static Object createExtension(final IConfigurationElement element, final String classAttribute) {
		final Object[] result = new Object[1];
		// If plugin has been loaded create extension.
		// Otherwise, show busy cursor then create extension.
		String pluginId = element.getDeclaringExtension().getNamespace();
		Bundle bundle = Platform.getBundle(pluginId);
		if (bundle.getState() == Bundle.ACTIVE) {
			try {
				result[0] = element.createExecutableExtension(classAttribute);
			} catch (Exception e) {
				// catch and log ANY exception from extension point
				handleCreateExecutableException(result, e);
			}
		} else {
			BusyIndicator.showWhile(null, new Runnable() {
				public void run() {
					try {
						result[0] = element.createExecutableExtension(classAttribute);
					} catch (Exception e) {
						// catch and log ANY exception from extension point
						handleCreateExecutableException(result, e);
					}
				}
			});
		}
		return result[0];
	}

	private static void handleCreateExecutableException(final Object[] result, Throwable e) {
		Logger.logException(e);
		result[0] = null;
	}

	private String id;

	private ActionContributionItem item;
	private String menuGroup;
	private String menuPath;
	private String popupmenuGroup;
	private String popupmenuPath;
	private String toolbarGroup;
	private String toolbarPath;

	/**
	 * Creates a new descriptor with the targetType
	 */
	public ActionDescriptor(IConfigurationElement actionElement) throws CoreException {

		// Calculate menu and toolbar paths.
		String mpath = actionElement.getAttribute(ATT_MENUBAR_PATH);
		String mgroup = null;
		if (mpath != null) {
			int loc = mpath.lastIndexOf('/');
			if (loc != -1) {
				mgroup = mpath.substring(loc + 1);
				mpath = mpath.substring(0, loc);
			} else {
				mgroup = mpath;
				mpath = null;
			}
		}
		menuPath = mpath;
		menuGroup = mgroup;

		String ppath = actionElement.getAttribute(ATT_POPUPMENU_PATH);
		String pgroup = null;
		if (ppath != null) {
			int loc = ppath.lastIndexOf('/');
			if (loc != -1) {
				pgroup = ppath.substring(loc + 1);
				ppath = ppath.substring(0, loc);
			} else {
				pgroup = ppath;
				ppath = null;
			}
		}
		popupmenuPath = ppath;
		popupmenuGroup = pgroup;

		String tpath = actionElement.getAttribute(ATT_TOOLBAR_PATH);
		String tgroup = null;
		if (tpath != null) {
			int loc = tpath.lastIndexOf('/');
			if (loc != -1) {
				tgroup = tpath.substring(loc + 1);
				tpath = tpath.substring(0, loc);
			} else {
				tgroup = tpath;
				tpath = null;
			}
		}
		toolbarPath = tpath;
		toolbarGroup = tgroup;

		// Create action.
		IAction action = createAction(actionElement);
		if (action == null)
			return;

		String label = actionElement.getAttribute(ATT_LABEL);
		if (label != null)
			action.setText(label);

		id = actionElement.getAttribute(ATT_ID);
		if (id == null) {
			id = actionElement.getAttribute(ATT_CLASS);
		}
		if (id != null)
			action.setId(id);

		String defId = actionElement.getAttribute(ATT_DEFINITION_ID);
		if (defId != null && defId.length() != 0) {
			action.setActionDefinitionId(defId);
		}

		String tooltip = actionElement.getAttribute(ATT_TOOLTIP);
		if (tooltip != null)
			action.setToolTipText(tooltip);

		String helpContextId = actionElement.getAttribute(ATT_HELP_CONTEXT_ID);
		if (helpContextId != null) {
			String fullID = helpContextId;
			if (helpContextId.indexOf(".") == -1) //$NON-NLS-1$
				// For backward compatibility we auto qualify the id if it is
				// not qualified)
				fullID = actionElement.getDeclaringExtension().getNamespace() + "." + helpContextId; //$NON-NLS-1$
			WorkbenchHelp.setHelp(action, fullID);
		}

		String description = actionElement.getAttribute(ATT_DESCRIPTION);
		if (description != null)
			action.setDescription(description);

		String state = actionElement.getAttribute(ATT_STATE);
		if (state != null) {
			action.setChecked(state.equals("true")); //$NON-NLS-1$
		}

		String icon = actionElement.getAttribute(ATT_ICON);
		if (icon != null) {
			action.setImageDescriptor(ImageUtil.getImageDescriptorFromExtension(actionElement.getDeclaringExtension(), icon));
		}

		String hoverIcon = actionElement.getAttribute(ATT_HOVERICON);
		if (hoverIcon != null) {
			action.setHoverImageDescriptor(ImageUtil.getImageDescriptorFromExtension(actionElement.getDeclaringExtension(), hoverIcon));
		}

		String disabledIcon = actionElement.getAttribute(ATT_DISABLEDICON);
		if (disabledIcon != null) {
			action.setDisabledImageDescriptor(ImageUtil.getImageDescriptorFromExtension(actionElement.getDeclaringExtension(), disabledIcon));
		}

		String accelerator = actionElement.getAttribute(ATT_ACCELERATOR);
		if (accelerator != null)
			processAccelerator(action, accelerator);

		item = new ActionContributionItem(action);
	}

	/**
	 * Parses the given accelerator text, and converts it to an accelerator
	 * key code.
	 * 
	 * @param acceleratorText
	 *            the accelerator text
	 * @result the SWT key code, or 0 if there is no accelerator
	 */
	private int convertAccelerator(String acceleratorText) {
		int accelerator = 0;
		StringTokenizer stok = new StringTokenizer(acceleratorText, "+"); //$NON-NLS-1$

		int keyCode = -1;

		boolean hasMoreTokens = stok.hasMoreTokens();
		while (hasMoreTokens) {
			String token = stok.nextToken();
			hasMoreTokens = stok.hasMoreTokens();
			// Every token except the last must be one of the modifiers
			// Ctrl, Shift, or Alt.
			if (hasMoreTokens) {
				int modifier = Action.findModifier(token);
				if (modifier != 0) {
					accelerator |= modifier;
				} else { //Leave if there are none
					return 0;
				}
			} else {
				keyCode = Action.findKeyCode(token);
			}
		}
		if (keyCode != -1) {
			accelerator |= keyCode;
		}
		return accelerator;
	}

	/**
	 */
	private IAction createAction(IConfigurationElement actionElement) {

		Object action = createExtension(actionElement, ATT_CLASS);
		if (action == null)
			return null;
		if (action instanceof IActionValidator) {
			if (!((IActionValidator) action).isValidAction())
				return null;
		}
		return (action instanceof IAction ? (IAction) ExtendedEditorActionProxy.newInstance(action) : null);
	}

	/**
	 * Returns the action object held in this descriptor.
	 */
	public IAction getAction() {
		return (item != null ? item.getAction() : null);
	}

	/**
	 * Returns the IContributionItem object held in this descriptor.
	 */
	public IContributionItem getContributionItem() {
		return item;
	}

	/**
	 * Returns action's id as defined in the registry.
	 */
	public String getId() {
		return id;
	}

	/**
	 * Returns named slot (group) in the menu where this action should be
	 * added.
	 */
	public String getMenuGroup() {
		return menuGroup;
	}

	/**
	 * Returns menu path where this action should be added. If null, the
	 * action will not be added into the menu.
	 */

	public String getMenuPath() {
		return menuPath;
	}

	/**
	 * Returns named slot (group) in the popup menu where this action should
	 * be added.
	 */
	public String getPopupMenuGroup() {
		return popupmenuGroup;
	}

	/**
	 * Returns popup menu path where this action should be added. If null, the
	 * action will not be added into the popup menu.
	 */

	public String getPopupMenuPath() {
		return popupmenuPath;
	}

	/**
	 * Returns the named slot (group) in the tool bar where this action should
	 * be added.
	 */

	public String getToolbarGroup() {
		return toolbarGroup;
	}

	/**
	 * Returns path in the tool bar where this action should be added. If
	 * null, action will not be added to the tool bar.
	 */
	public String getToolbarPath() {
		return toolbarPath;
	}

	/**
	 * Process the accelerator definition. If it is a number then process the
	 * code directly - if not then parse it and create the code
	 */
	private void processAccelerator(IAction action, String acceleratorText) {

		if (acceleratorText.length() == 0)
			return;

		//Is it a numeric definition?
		if (Character.isDigit(acceleratorText.charAt(0))) {
			try {
				action.setAccelerator(Integer.valueOf(acceleratorText).intValue());
			} catch (NumberFormatException exception) {
				Logger.log(Logger.ERROR, "Invalid accelerator declaration: " + id); //$NON-NLS-1$
			}
		} else
			action.setAccelerator(convertAccelerator(acceleratorText));
	}

	/**
	 * For debugging only.
	 */
	public String toString() {
		return "ActionDescriptor(" + id + ")"; //$NON-NLS-2$//$NON-NLS-1$
	}
}
