/*******************************************************************************
 * 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
 *******************************************************************************/
package org.eclipse.ui.actions;

import org.eclipse.core.commands.IHandlerAttributes;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.swt.events.HelpEvent;
import org.eclipse.swt.events.HelpListener;
import org.eclipse.swt.widgets.Event;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchPartSite;
import org.eclipse.ui.SubActionBars;
import org.eclipse.ui.internal.PartSite;

/**
 * A <code>RetargetAction</code> tracks the active part in the workbench.  
 * Each RetargetAction has an ID.  If the active part provides an action 
 * handler for the ID the enable and check state of the RetargetAction
 * is determined from the enable and check state of the handler.  If the 
 * active part does not provide an action handler then this action is 
 * disabled.
 * </p>
 * <p>
 * <b>Note:</b> instances of this class add themselves as listeners to their
 * action handler. It is important for the creator of a retarget action to call
 * dispose when the action is no longer needed. This will ensure that the 
 * listener is removed.
 * </p>
 * <p>
 * This class may be instantiated. It is not intented to be subclassed.
 * </p>
 *
 * @since 2.0 
 * @noextend This class is not intended to be subclassed by clients.
 */
public class RetargetAction extends PartEventAction implements
        ActionFactory.IWorkbenchAction {

    /**
     * The help listener assigned to this action, or <code>null</code> if none.
     */
    private HelpListener localHelpListener;

    private boolean enableAccelerator = true;

    private IAction handler;

    private IPropertyChangeListener propertyChangeListener = new IPropertyChangeListener() {
        public void propertyChange(PropertyChangeEvent event) {
            RetargetAction.this.propagateChange(event);
        }
    };

    /**
     * Constructs a RetargetAction with the given action id and text.
     * 
     * @param actionID the retargetable action id
     * @param text the action's text, or <code>null</code> if there is no text
     */
    public RetargetAction(String actionID, String text) {
        this(actionID, text, IAction.AS_UNSPECIFIED);
    }

    /**
     * Constructs a RetargetAction with the given action id, text and style.
     * 
     * @param actionID the retargetable action id
     * @param text the action's text, or <code>null</code> if there is no text
     * @param style one of <code>AS_PUSH_BUTTON</code>, <code>AS_CHECK_BOX</code>,
     * 		<code>AS_DROP_DOWN_MENU</code>, <code>AS_RADIO_BUTTON</code>, and
     * 		<code>AS_UNSPECIFIED</code>
     * @since 3.0
     */
    public RetargetAction(String actionID, String text, int style) {
        super(text, style);
        setId(actionID);
        setEnabled(false);
        super.setHelpListener(new HelpListener() {
            public void helpRequested(HelpEvent e) {
                HelpListener listener = null;
                if (handler != null) {
                    // if we have a handler, see if it has a help listener
                    listener = handler.getHelpListener();
                    if (listener == null) {
						// use our own help listener
                        listener = localHelpListener;
					}
                }
                if (listener != null) {
					// pass on the event
                    listener.helpRequested(e);
				}
            }
        });
    }

    /**
     * Disposes of the action and any resources held.
     */
    public void dispose() {
        if (handler != null) {
            handler.removePropertyChangeListener(propertyChangeListener);
            handler = null;
        }
        IWorkbenchPart part = getActivePart();
        if (part != null) {
            IWorkbenchPartSite site = part.getSite();
            SubActionBars bars = (SubActionBars) ((PartSite) site).getActionBars();
            bars.removePropertyChangeListener(propertyChangeListener);
        }
    }

    /**
     * Enables the accelerator for this action. 
     *
     * @param b the new enable state
     */
    public void enableAccelerator(boolean b) {
        enableAccelerator = b;
    }

    /* (non-Javadoc)
     * Retaget actions do not have accelerators.  It is up to the
     * part to hook the accelerator.
     */
    public int getAccelerator() {
        if (enableAccelerator) {
			return super.getAccelerator();
		}
        return 0;
    }

    /**
     * A workbench part has been activated. Try to connect
     * to it.
     *
     * @param part the workbench part that has been activated
     */
    public void partActivated(IWorkbenchPart part) {
        super.partActivated(part);
        IWorkbenchPartSite site = part.getSite();
        SubActionBars bars = (SubActionBars) ((PartSite) site).getActionBars();
        bars.addPropertyChangeListener(propertyChangeListener);
        setActionHandler(bars.getGlobalActionHandler(getId()));
    }

    /**
     * A workbench part has been closed. 
     *
     * @param part the workbench part that has been closed
     */
    public void partClosed(IWorkbenchPart part) {
        IWorkbenchPart activePart = part.getSite().getPage().getActivePart();
        if (activePart != null) {
			// We are going to get a part activated message so don't bother setting the 
            // action handler to null. This prevents enablement flash in the toolbar
            return;
		}
        if (part == getActivePart()) {
			setActionHandler(null);
		}
        super.partClosed(part);
    }

    /**
     * A workbench part has been deactivated. Disconnect from it.
     *
     * @param part the workbench part that has been deactivated
     */
    public void partDeactivated(IWorkbenchPart part) {
        super.partDeactivated(part);
        IWorkbenchPartSite site = part.getSite();
        SubActionBars bars = (SubActionBars) ((PartSite) site).getActionBars();
        bars.removePropertyChangeListener(propertyChangeListener);

        IWorkbenchPart activePart = part.getSite().getPage().getActivePart();
        if (activePart != null) {
			// We are going to get a part activated message so don't bother setting the 
            // action handler to null. This prevents enablement flash in the toolbar
            return;
		}

        setActionHandler(null);
    }

    /**
     * Either the action handler itself has changed, or the configured action
     * handlers on the action bars have changed. Update self.
     */
    protected void propagateChange(PropertyChangeEvent event) {
        if (event.getProperty().equals(IAction.ENABLED)) {
            Boolean bool = (Boolean) event.getNewValue();
            setEnabled(bool.booleanValue());
        } else if (event.getProperty().equals(IAction.CHECKED)) {
            Boolean bool = (Boolean) event.getNewValue();
            setChecked(bool.booleanValue());
        } else if (event.getProperty().equals(SubActionBars.P_ACTION_HANDLERS)) {
            if (event.getSource() instanceof IActionBars) {
                IActionBars bars = (IActionBars) event.getSource();
                setActionHandler(bars.getGlobalActionHandler(getId()));
            }
        }
    }

    /**
     * Invoked when an action occurs. 
     */
    public void run() {
        if (handler != null) {
			handler.run();
		}
    }

    /**
     * Invoked when an action occurs. 
     */
    public void runWithEvent(Event event) {
        if (handler != null) {
			handler.runWithEvent(event);
		}
    }

    /**
     * Returns the action handler. This method was made public in 3.0.
     * 
     * @return The current action handling this retargettable action. This
     *         handler will be <code>null</code> if there is no current
     *         handler.
     */
    public IAction getActionHandler() {
        return handler;
    }
    
    public final boolean isHandled() {
        return (handler != null);
    }

    /**
     * Sets the action handler.
     */
    protected void setActionHandler(IAction newHandler) {
        // Optimize.
        if (newHandler == handler) {
			return;
		}

        // Clear old action.
        if (handler != null) {
            handler.removePropertyChangeListener(propertyChangeListener);
            handler = null;
        }

        // Set new action.
		IAction oldHandler = handler;
        handler = newHandler;
        if (handler == null) {
            setEnabled(false);
            if (getStyle() == AS_CHECK_BOX || getStyle() == AS_RADIO_BUTTON) {
                setChecked(false);
            }
        } else {
            setEnabled(handler.isEnabled());
            if (getStyle() == AS_CHECK_BOX || getStyle() == AS_RADIO_BUTTON) {
                setChecked(handler.isChecked());
            }
            handler.addPropertyChangeListener(propertyChangeListener);
        }
		
		// Notify listeners that the handler has changed.
        firePropertyChange(IHandlerAttributes.ATTRIBUTE_HANDLED, oldHandler,
                newHandler);
    }

    /* (non-Javadoc)
     * Method declared on IAction.
     */
    public void setChecked(boolean checked) {
        super.setChecked(checked);
        // This call may come from the SWT control event handler
        // itself, so notify the handler action to keep things
        // in sync.
        if (handler != null) {
			handler.setChecked(checked);
		}
    }

    /** 
     * The <code>RetargetAction</code> implementation of this method declared on
     * <code>IAction</code> stores the help listener in a local field. The
     * supplied listener is only used if there is no hanlder.
     */
    public void setHelpListener(HelpListener listener) {
        localHelpListener = listener;
    }

	/**
	 * Returns a string representation of this action.
	 * 
	 * @return A string representation of this action.
	 * 
	 * @since 3.2 
	 */
	public final String toString() {
		final StringBuffer buffer = new StringBuffer();

		buffer.append("RetargetAction("); //$NON-NLS-1$
		buffer.append(getId());
		buffer.append(')');

		return buffer.toString();
	}
}
