/*******************************************************************************
 * Copyright (c) 2000, 2010 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
 *******************************************************************************/
package org.eclipse.gef.internal.ui.palette;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Item;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.swt.widgets.ToolItem;
import org.eclipse.swt.widgets.Widget;

import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.ContributionItem;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IContributionManagerOverrides;
import org.eclipse.jface.action.IMenuCreator;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;

import org.eclipse.draw2d.rap.swt.SWT;

/**
 * A contribution item which delegates to an action.
 * <p>
 * This class may be instantiated; it is not intended to be subclassed.
 * </p>
 */
public class ToolbarDropdownContributionItem extends ContributionItem {

	private static ImageCache globalImageCache;

	/**
	 * The action.
	 */
	private IAction action;

	/**
	 * The widget created for this item; <code>null</code> before creation and
	 * after disposal.
	 */
	private Widget widget = null;

	/**
	 * Nested class handles notification from SWT widget and from Action, to
	 * avoid polluting ToolbarDropdownContributionItem with public listener
	 * methods.
	 */
	private class ActionListener implements Listener, IPropertyChangeListener {
		public void handleEvent(Event event) {
			ToolbarDropdownContributionItem.this.handleWidgetEvent(event);
		}

		public void propertyChange(PropertyChangeEvent event) {
			ToolbarDropdownContributionItem.this.actionPropertyChange(event);
		}
	}

	private ActionListener listener = new ActionListener();

	private class ImageCache {
		/** Map from ImageDescriptor to Entry */
		private Map entries = new HashMap(11);
		private Image missingImage;

		private class Entry {
			protected Image image;
			protected Image grayImage;

			void dispose() {
				if (image != null) {
					image.dispose();
					image = null;
				}
				if (grayImage != null) {
					grayImage.dispose();
					grayImage = null;
				}
			}
		}

		Entry getEntry(ImageDescriptor desc) {
			Entry entry = (Entry) entries.get(desc);
			if (entry == null) {
				entry = new Entry();
				entries.put(desc, entry);
			}
			return entry;
		}

		Image getImage(ImageDescriptor desc) {
			if (desc == null) {
				return null;
			}
			Entry entry = getEntry(desc);
			if (entry.image == null) {
				entry.image = desc.createImage();
			}
			return entry.image;
		}

		Image getGrayImage(ImageDescriptor desc) {
			if (desc == null) {
				return null;
			}
			Entry entry = getEntry(desc);
			if (entry.grayImage == null) {
				Image image = getImage(desc);
				if (image != null) {
					entry.grayImage = new Image(null, image, SWT.IMAGE_GRAY);
				}
			}
			return entry.grayImage;
		}

		Image getMissingImage() {
			if (missingImage == null) {
				missingImage = getImage(ImageDescriptor
						.getMissingImageDescriptor());
			}
			return missingImage;
		}

		void dispose() {
			for (Iterator i = entries.values().iterator(); i.hasNext();) {
				Entry entry = (Entry) i.next();
				entry.dispose();
			}
			entries.clear();
		}
	}

	/**
	 * Creates a new contribution item from the given action. The id of the
	 * action is used as the id of the item.
	 * 
	 * @param action
	 *            the action
	 */
	public ToolbarDropdownContributionItem(IAction action) {
		super(action.getId());
		this.action = action;
	}

	/**
	 * Handles a property change event on the action (forwarded by nested
	 * listener).
	 */
	private void actionPropertyChange(final PropertyChangeEvent e) {
		// This code should be removed. Avoid using free asyncExec

		if (isVisible() && widget != null) {
			Display display = widget.getDisplay();
			if (display.getThread() == Thread.currentThread()) {
				update(e.getProperty());
			} else {
				display.asyncExec(new Runnable() {
					public void run() {
						update(e.getProperty());
					}
				});
			}

		}
	}

	/**
	 * Checks whether the given menu item belongs to a context menu (the one
	 * that pops up if the user presses the right mouse button).
	 */
	private static boolean belongsToContextMenu(MenuItem item) {
		Menu menu = item.getParent();
		if (menu == null)
			return false;
		while (menu.getParentMenu() != null)
			menu = menu.getParentMenu();
		return (menu.getStyle() & SWT.BAR) == 0;
	}

	/**
	 * Compares this action contribution item with another object. Two action
	 * contribution items are equal if they refer to the identical Action.
	 */
	public boolean equals(Object o) {
		if (!(o instanceof ToolbarDropdownContributionItem)) {
			return false;
		}
		return action.equals(((ToolbarDropdownContributionItem) o).action);
	}

	/**
	 * The <code>ToolbarDropdownContributionItem</code> implementation of this
	 * <code>IContributionItem</code> method creates a SWT Button for the
	 * action. If the action's checked property has been set, a toggle button is
	 * created and primed to the value of the checked property.
	 */
	public void fill(Composite parent) {
		if (widget == null && parent != null) {
			int flags = SWT.PUSH;

			if (action != null) {
				if (action.getStyle() == IAction.AS_CHECK_BOX)
					flags = SWT.TOGGLE;
			}

			Button b = new Button(parent, flags);
			b.setData(this);
			b.addListener(SWT.Dispose, listener);
			// Don't hook a dispose listener on the parent
			b.addListener(SWT.Selection, listener);
			if (action.getHelpListener() != null)
				b.addHelpListener(action.getHelpListener());
			widget = b;

			update(null);

			action.addPropertyChangeListener(listener);
		}
	}

	/**
	 * The <code>ToolbarDropdownContributionItem</code> implementation of this
	 * <code>IContributionItem</code> method creates a SWT MenuItem for the
	 * action. If the action's checked property has been set, a toggle button is
	 * created and primed to the value of the checked property. If the action's
	 * menu creator property has been set, a cascading submenu is created.
	 */
	public void fill(Menu parent, int index) {
		if (widget == null && parent != null) {
			int flags = SWT.PUSH;
			Menu subMenu = null;

			if (action != null) {
				int style = action.getStyle();
				if (style == IAction.AS_CHECK_BOX)
					flags = SWT.CHECK;
				else if (style == IAction.AS_DROP_DOWN_MENU) {
					IMenuCreator mc = action.getMenuCreator();
					subMenu = mc.getMenu(parent);
					flags = SWT.CASCADE;
				}
			}

			MenuItem mi = null;
			if (index >= 0)
				mi = new MenuItem(parent, flags, index);
			else
				mi = new MenuItem(parent, flags);
			widget = mi;

			mi.setData(this);
			mi.addListener(SWT.Arm, listener);
			mi.addListener(SWT.Dispose, listener);
			mi.addListener(SWT.Selection, listener);
			if (action.getHelpListener() != null)
				mi.addHelpListener(action.getHelpListener());

			if (subMenu != null)
				mi.setMenu(subMenu);

			update(null);

			action.addPropertyChangeListener(listener);
		}
	}

	/**
	 * The <code>ToolbarDropdownContributionItem</code> implementation of this
	 * <code>IContributionItem</code> method creates a SWT ToolItem for the
	 * action. If the action's checked property has been set, a toggle button is
	 * created and primed to the value of the checked property. If the action's
	 * menu creator property has been set, a drop-down tool item is created.
	 */
	public void fill(ToolBar parent, int index) {
		if (widget == null && parent != null) {
			int flags = SWT.PUSH;

			if (action != null) {
				int style = action.getStyle();
				if (style == IAction.AS_CHECK_BOX)
					flags = SWT.CHECK;
				else if (style == IAction.AS_DROP_DOWN_MENU)
					flags = SWT.DROP_DOWN;
			}

			ToolItem ti = null;
			if (index >= 0)
				ti = new ToolItem(parent, flags, index);
			else
				ti = new ToolItem(parent, flags);
			ti.setData(this);
			ti.addListener(SWT.Selection, listener);
			ti.addListener(SWT.Dispose, listener);

			widget = ti;

			update(null);

			action.addPropertyChangeListener(listener);
		}
	}

	/**
	 * Returns the action associated with this contribution item.
	 * 
	 * @return the action
	 */
	public IAction getAction() {
		return action;
	}

	/**
	 * Returns the image cache. The cache is global, and is shared by all action
	 * contribution items. This has the disadvantage that once an image is
	 * allocated, it is never freed until the display is disposed. However, it
	 * has the advantage that the same image in different contribution managers
	 * is only ever created once.
	 */
	private ImageCache getImageCache() {
		ImageCache cache = globalImageCache;
		if (cache == null) {
			globalImageCache = cache = new ImageCache();
			Display display = Display.getDefault();
			if (display != null) {
				display.disposeExec(new Runnable() {
					public void run() {
						if (globalImageCache != null) {
							globalImageCache.dispose();
							globalImageCache = null;
						}
					}
				});
			}
		}
		return cache;
	}

	/**
	 * Handles a widget arm event.
	 */
	private void handleWidgetArm(Event e) {
		/*
		 * String description= null; if (fAction instanceof Action) //
		 * getDescription should go into IAction description=
		 * ((Action)fAction).getDescription(); if (description != null)
		 * ApplicationWindow.showDescription(e.widget, description); else
		 * ApplicationWindow.resetDescription(e.widget);
		 */
	}

	/**
	 * Handles a widget dispose event for the widget corresponding to this item.
	 */
	private void handleWidgetDispose(Event e) {
		if (e.widget == widget) {
			// the item is being disposed
			if (action.getStyle() == IAction.AS_DROP_DOWN_MENU) {
				action.getMenuCreator().dispose();
			}
			action.removePropertyChangeListener(listener);
			widget = null;
		}
	}

	/**
	 * Handles an event from the widget (forwarded from nested listener).
	 */
	private void handleWidgetEvent(Event e) {
		switch (e.type) {
		case SWT.Arm:
			handleWidgetArm(e);
			break;
		case SWT.Dispose:
			handleWidgetDispose(e);
			break;
		case SWT.Selection:
			handleWidgetSelection(e);
			break;
		}
	}

	/**
	 * Handles a widget selection event.
	 */
	private void handleWidgetSelection(Event e) {
		Widget item = e.widget;
		if (item != null) {

			int style = item.getStyle();

			if ((style & (SWT.TOGGLE | SWT.CHECK)) != 0) {
				if (action.getStyle() == IAction.AS_CHECK_BOX) {
					action.setChecked(!action.isChecked());
				}

			} else if ((style & SWT.DROP_DOWN) != 0) {
				/*
				 * Added by Pratik Shah Do this regardless of whether the down
				 * arrow button on the side was clicked, or the main button
				 * itself
				 */
				if (action.getStyle() == IAction.AS_DROP_DOWN_MENU) {
					IMenuCreator mc = action.getMenuCreator();
					ToolItem ti = (ToolItem) item;
					// we create the menu as a sub-menu of "dummy" so that we
					// can use
					// it in a cascading menu too.
					// If created on a SWT control we would get an SWT error...
					// Menu dummy= new Menu(ti.getParent());
					// Menu m= mc.getMenu(dummy);
					// dummy.dispose();

					Menu m = mc.getMenu(ti.getParent());
					if (m != null) {
						// position the menu below the drop down item
						Rectangle b = ti.getBounds();
						Point p = ti.getParent().toDisplay(
								new Point(b.x, b.y + b.height));
						m.setLocation(p.x, p.y); // waiting for SWT 0.42
						m.setVisible(true);
						return; // we don't fire the action
					}
				}
			}

			// Ensure action is enabled first.
			// See 1GAN3M6: ITPUI:WINNT - Any IAction in the workbench can be
			// executed
			// while disabled.
			if (action.isEnabled()) {
				action.runWithEvent(e);
			}
		}
	}

	/*
	 * (non-Javadoc) Method declared on Object.
	 */
	public int hashCode() {
		return action.hashCode();
	}

	/*
	 * (non-Javadoc) Method declared on IContributionItem.
	 */
	public boolean isEnabled() {
		return action != null && action.isEnabled();
	}

	/**
	 * The action item implementation of this <code>IContributionItem</code>
	 * method returns <code>true</code> for menu items and <code>false</code>
	 * for everything else.
	 */
	public boolean isDynamic() {
		if (widget instanceof MenuItem) {
			// Optimization. Only recreate the item is the check style has
			// changed.
			boolean itemIsCheck = (widget.getStyle() & SWT.CHECK) != 0;
			boolean actionIsCheck = getAction() != null
					&& getAction().getStyle() == IAction.AS_CHECK_BOX;
			return itemIsCheck != actionIsCheck;
		}
		return false;
	}

	/**
	 * Returns <code>true</code> if this item is allowed to enable,
	 * <code>false</code> otherwise.
	 * 
	 * @return if this item is allowed to be enabled
	 * @since 2.0
	 */
	protected boolean isEnabledAllowed() {
		if (getParent() == null)
			return true;
		Boolean value = getParent().getOverrides().getEnabled(this);
		return (value == null) ? true : value.booleanValue();
	}

	/**
	 * The action item implementation of this <code>IContributionItem</code>
	 * method calls <code>update(null)</code>.
	 */
	public final void update() {
		update(null);
	}

	/**
	 * Synchronizes the UI with the given property.
	 * 
	 * @param propertyName
	 *            the name of the property, or <code>null</code> meaning all
	 *            applicable properties
	 */
	public void update(String propertyName) {
		if (widget != null) {

			// determine what to do
			boolean textChanged = propertyName == null
					|| propertyName.equals(Action.TEXT);
			boolean imageChanged = propertyName == null
					|| propertyName.equals(Action.IMAGE);
			boolean tooltipTextChanged = propertyName == null
					|| propertyName.equals(Action.TOOL_TIP_TEXT);
			boolean enableStateChanged = propertyName == null
					|| propertyName.equals(Action.ENABLED)
					|| propertyName
							.equals(IContributionManagerOverrides.P_ENABLED);
			boolean checkChanged = (action.getStyle() == IAction.AS_CHECK_BOX)
					&& (propertyName == null || propertyName
							.equals(Action.CHECKED));

			if (widget instanceof ToolItem) {
				ToolItem ti = (ToolItem) widget;
				if (imageChanged) {
					updateImages(true);
				}
				if (tooltipTextChanged)
					ti.setToolTipText(action.getToolTipText());

				if (enableStateChanged) {
					boolean shouldBeEnabled = action.isEnabled()
							&& isEnabledAllowed();
					if (ti.getEnabled() != shouldBeEnabled)
						ti.setEnabled(shouldBeEnabled);
				}

				if (checkChanged) {
					boolean bv = action.isChecked();
					if (ti.getSelection() != bv)
						ti.setSelection(bv);
				}
				return;
			}

			if (widget instanceof MenuItem) {
				MenuItem mi = (MenuItem) widget;
				boolean isContextMenu = belongsToContextMenu(mi);

				// We only install an accelerator if the menu item doesn't
				// belong to a context menu (right mouse button menu).
				if (textChanged) {
					if (isContextMenu) {
						String text = action.getText();
						if (text != null) {
							text = Action.removeAcceleratorText(text);
							mi.setText(text);
						}
					} else {
						String text = null;
						IContributionManagerOverrides overrides = null;
						if (getParent() != null)
							overrides = getParent().getOverrides();
						if (overrides != null)
							text = getParent().getOverrides().getText(this);
						if (text == null)
							text = action.getText();
						if (text != null) {
							String label = Action.removeAcceleratorText(text);
							String accText = null;
							Integer acc = null;
							if (overrides != null) {
								accText = overrides.getAcceleratorText(this);
								acc = overrides.getAccelerator(this);
							}
							if ((accText == null)
									&& (label.length() + 1 < text.length()))
								accText = text.substring(label.length() + 1);
							if (acc == null)
								acc = new Integer(action.getAccelerator());
							// UNSUPPORTED - api not implemented in RAP
							// if (acc.intValue() >= 0)
							// mi.setAccelerator(acc.intValue());
							if (accText == null)
								mi.setText(label);
							else
								mi.setText(label + '\t' + accText);
						}
					}
				}
				if (imageChanged) {
					updateImages(false);
				}
				if (enableStateChanged) {
					boolean shouldBeEnabled = action.isEnabled()
							&& isEnabledAllowed();
					if (mi.getEnabled() != shouldBeEnabled)
						mi.setEnabled(shouldBeEnabled);
				}

				if (checkChanged) {
					boolean bv = action.isChecked();
					if (mi.getSelection() != bv)
						mi.setSelection(bv);
				}
				return;
			}

			if (widget instanceof Button) {
				Button button = (Button) widget;
				if (imageChanged) {
					if (updateImages(false)) {
						// don't update text if it has an image
						textChanged = false;
					}
				}
				if (textChanged) {
					String text = action.getText();
					if (text != null)
						button.setText(text);
				}
				if (tooltipTextChanged)
					button.setToolTipText(action.getToolTipText());

				if (enableStateChanged) {
					boolean shouldBeEnabled = action.isEnabled()
							&& isEnabledAllowed();
					if (button.getEnabled() != shouldBeEnabled)
						button.setEnabled(shouldBeEnabled);
				}

				if (checkChanged) {
					boolean bv = action.isChecked();
					if (button.getSelection() != bv)
						button.setSelection(bv);
				}
				return;
			}
		}
	}

	/**
	 * Updates the images for this action.
	 * 
	 * @param forceImage
	 *            <code>true</code> if some form of image is compulsory, and
	 *            <code>false</code> if it is acceptable for this item to have
	 *            no image
	 * @return <code>true</code> if there are images for this action,
	 *         <code>false</code> if not
	 */
	private boolean updateImages(boolean forceImage) {

		ImageCache cache = getImageCache();

		if (widget instanceof ToolItem) {
			Image image = cache.getImage(action.getImageDescriptor());
			Image hoverImage = cache.getImage(action.getHoverImageDescriptor());
			Image disabledImage = cache.getImage(action
					.getDisabledImageDescriptor());

			// If there is no regular image, but there is a hover image,
			// convert the hover image to gray and use it as the regular image.
			if (image == null && hoverImage != null) {
				image = cache.getGrayImage(action.getHoverImageDescriptor());
			} else {
				// If there is no hover image, use the regular image as the
				// hover image,
				// and convert the regular image to gray
				if (hoverImage == null && image != null) {
					hoverImage = image;
					image = cache.getGrayImage(action.getImageDescriptor());
				}
			}

			// Make sure there is a valid image.
			if (hoverImage == null && image == null && forceImage) {
				image = cache.getMissingImage();
			}

			// performance: more efficient in SWT to set disabled and hot image
			// before
			// regular image
			if (disabledImage != null) {
				// Set the disabled image if we were able to create one.
				// Assumes that SWT.ToolItem will use platform's default
				// behavior to show item when it is disabled and a disabled
				// image has not been set.
				((ToolItem) widget).setDisabledImage(disabledImage);
			}
			((ToolItem) widget).setHotImage(hoverImage);
			((ToolItem) widget).setImage(image);

			return image != null;
		} else if (widget instanceof Item || widget instanceof Button) {
			// Use hover image if there is one, otherwise use regular image.
			Image image = cache.getImage(action.getHoverImageDescriptor());
			if (image == null) {
				image = cache.getImage(action.getImageDescriptor());
			}
			// Make sure there is a valid image.
			if (image == null && forceImage) {
				image = cache.getMissingImage();
			}
			if (widget instanceof Item) {
				((Item) widget).setImage(image);
			} else if (widget instanceof Button) {
				((Button) widget).setImage(image);
			}
			return image != null;
		}
		return false;
	}
}
