/*******************************************************************************
 * 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.extension.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$
	}
}
