/*******************************************************************************
 * Copyright (c) 2006, 2013 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.debug.ui.actions;

import org.eclipse.debug.core.IRequest;
import org.eclipse.debug.internal.ui.commands.actions.DebugCommandService;
import org.eclipse.debug.internal.ui.commands.actions.ICommandParticipant;
import org.eclipse.debug.internal.ui.commands.actions.IEnabledTarget;
import org.eclipse.debug.ui.DebugUITools;
import org.eclipse.debug.ui.contexts.DebugContextEvent;
import org.eclipse.debug.ui.contexts.IDebugContextListener;
import org.eclipse.debug.ui.contexts.IDebugContextService;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.swt.widgets.Event;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;

/**
 * Abstract base class for re-targeting actions which delegate execution to
 * {@link org.eclipse.debug.core.commands.IDebugCommandHandler} handlers.
 * The specific type of <code>IDebugCommandHandler</code> is determined by the
 * abstract {@link #getCommandType()} method.
 * <p>
 * This base class is an action which can be instantiated directly by views,
 * etc.  In order to contribute an action using an extension point, a class
 * implementing {@link org.eclipse.ui.IActionDelegate} should be created first.
 * The delegate should then use a <code>DebugCommandAction</code> to implement
 * the needed functionality. The IActionDelegate must use {@link #setActionProxy(IAction)}
 * specifying the workbench's action that is a proxy to the action delegate. This
 * way, the workbench action can be updated visually as needed.<br>
 * Note: <code>IDebugCommandHandler</code> command typically act on the active
 * debug context as opposed to the active selection in view or window.  The
 * action delegate should ignore the active window selection, and instead allow
 * the <code>DebugCommandAction</code> to update itself based on the active
 * debug context.
 * </p>
 * <p>
 * Clients may subclass this class.
 * </p>
 * @see org.eclipse.debug.core.commands.IDebugCommandHandler
 * @since 3.6
 */
public abstract class DebugCommandAction extends Action implements IDebugContextListener {

    private boolean fInitialized = false;

	/**
	 * The window this action is working for.
	 */
    private IWorkbenchWindow fWindow;

    /**
     * The part this action is working for, or <code>null</code> if global to
     * a window.
     */
    private IWorkbenchPart fPart;

    /**
     * Command service.
     */
    private DebugCommandService fUpdateService;

    /**
     * Delegate this action is working for or <code>null</code> if none.
     */
    private IAction fAction;

    private IEnabledTarget fEnabledTarget = new IEnabledTarget() {
        @Override
		public void setEnabled(boolean enabled) {
            DebugCommandAction.this.setEnabled(enabled);
        }
    };

    /**
     * Constructor
     */
    public DebugCommandAction() {
        super();
        String helpContextId = getHelpContextId();
        if (helpContextId != null) {
			PlatformUI.getWorkbench().getHelpSystem().setHelp(this, helpContextId);
		}
        setEnabled(false);
    }

	/**
     * Sets the current workbench action that is a proxy to an {@link org.eclipse.ui.IActionDelegate}
     * that is using this action to perform its actual work. This only needs to be called when
     * an {@link org.eclipse.ui.IActionDelegate} is using one of these actions to perform its
     * function.
     *
     * @param action workbench proxy action
     */
    public void setActionProxy(IAction action) {
        fAction = action;
        fAction.setEnabled(isEnabled());
    }

    /**
     * Executes this action on the given target object
     * @param targets the targets to perform the action on
     * @return if the command stays enabled while the command executes
     */
    private boolean execute(final Object[] targets) {
    	return fUpdateService.executeCommand(
    	    getCommandType(), targets,
    	    new ICommandParticipant() {
    	        @Override
				public void requestDone(org.eclipse.debug.core.IRequest request) {
    	            DebugCommandAction.this.postExecute(request, targets);
    	        }
    	    });
    }

    /**
     * This method is called after the completion of the execution of this
     * command.  Extending classes may override this method to perform additional
     * operation after command execution.
     *
     * @param request The completed request object which was given to the
     * debug command handler.
     * @param targets Objects which were the targets of this action
     */
    protected void postExecute(IRequest request, Object[] targets) {
        // do nothing by default
    }

    /**
     * Returns the {@link org.eclipse.debug.core.commands.IDebugCommandHandler}
     * command handler that type this action executes.
     *
     * @return command class.
     *
     * @see org.eclipse.debug.core.commands.IDebugCommandHandler
     */
	abstract protected Class<?> getCommandType();

    /**
     * @see org.eclipse.debug.ui.contexts.IDebugContextListener#debugContextChanged(org.eclipse.debug.ui.contexts.DebugContextEvent)
     */
    @Override
	public void debugContextChanged(DebugContextEvent event) {
    	fUpdateService.postUpdateCommand(getCommandType(), fEnabledTarget);
	}

    /**
     * @see org.eclipse.jface.action.Action#setEnabled(boolean)
     */
    @Override
	public void setEnabled(boolean enabled) {
        synchronized (this) {
            if (!fInitialized) {
                fInitialized = true;
                notifyAll();
            }
        }
        super.setEnabled(enabled);
        if (fAction != null) {
            fAction.setEnabled(enabled);
        }
    }

    /**
     * Initializes this action for a specific part.
     *
     * @param part workbench part
     */
    public void init(IWorkbenchPart part) {
    	fInitialized = false;
        fPart = part;
        fWindow = part.getSite().getWorkbenchWindow();
        fUpdateService = DebugCommandService.getService(fWindow);
        IDebugContextService service = getDebugContextService();
		String partId = part.getSite().getId();
		service.addDebugContextListener(this, partId);
        ISelection activeContext = service.getActiveContext(partId);
        if (activeContext != null) {
        	fUpdateService.updateCommand(getCommandType(), fEnabledTarget);
        } else {
        	setEnabled(getInitialEnablement());
        }
    }

    /**
     * Initializes this action for a workbench window.
     *
     * @param window the window
     */
    public void init(IWorkbenchWindow window) {
    	fInitialized = false;
        fWindow = window;
        fUpdateService = DebugCommandService.getService(fWindow);
        IDebugContextService contextService = getDebugContextService();
		contextService.addDebugContextListener(this);
        ISelection activeContext = contextService.getActiveContext();
        if (activeContext != null) {
        	fUpdateService.updateCommand(getCommandType(), fEnabledTarget);
        } else {
        	setEnabled(getInitialEnablement());
        }
    }

    /**
     * Returns whether this action should be enabled when initialized
     * and there is no active debug context. By default, <code>false</code>
     * is returned.
     *
     * @return initial enabled state when there is no active context.
     */
    protected boolean getInitialEnablement() {
    	return false;
    }

    /**
     * Returns the context (selection) this action operates on. By default
     * the active debug context in this action's associated part or window is used,
     * but subclasses may override as required.
     *
     * @return the context this action operates on
     * @since 3.7
     */
    protected ISelection getContext() {
		if (fPart != null) {
			getDebugContextService().getActiveContext(fPart.getSite().getId());
    	}
        return getDebugContextService().getActiveContext();
    }

    /*
     * (non-Javadoc)
     * @see org.eclipse.jface.action.Action#run()
     */
    @Override
	public void run() {
        synchronized (this) {
            if (!fInitialized) {
                try {
                    wait();
                } catch (InterruptedException e) {
                }
            }
        }

        ISelection selection = getContext();
        if (selection instanceof IStructuredSelection && isEnabled()) {
            IStructuredSelection ss = (IStructuredSelection) selection;
            boolean enabled = execute(ss.toArray());
            // disable the action according to the command
            setEnabled(enabled);
        }
    }

    /*
     * (non-Javadoc)
     * @see org.eclipse.jface.action.Action#runWithEvent(org.eclipse.swt.widgets.Event)
     */
    @Override
	public void runWithEvent(Event event) {
        run();
    }

    /**
     * Clean up when removing
     */
    public void dispose() {
        IDebugContextService service = getDebugContextService();
        if (fPart != null) {
        	service.removeDebugContextListener(this, fPart.getSite().getId());
        } else {
            service.removeDebugContextListener(this);
        }
        fWindow = null;
        fPart = null;
    }

    /**
     * Returns the context service this action linked to. By default, this actions is
     * associated with the context service for the window this action is operating in.
     *
     * @return associated context service
     */
    protected IDebugContextService getDebugContextService() {
    	return DebugUITools.getDebugContextManager().getContextService(fWindow);
    }

    /**
     * Returns the help context id for this action or <code>null</code> if none.
     *
     * @return The help context id for this action or <code>null</code>
     */
    public abstract String getHelpContextId();

    /*
     * (non-Javadoc)
     * @see org.eclipse.jface.action.Action#getId()
     */
    @Override
	public abstract String getId();

    /*
     * (non-Javadoc)
     * @see org.eclipse.jface.action.Action#getText()
     */
    @Override
	public abstract String getText();

    /*
     * (non-Javadoc)
     * @see org.eclipse.jface.action.Action#getToolTipText()
     */
    @Override
	public abstract String getToolTipText();

    /*
     * (non-Javadoc)
     * @see org.eclipse.jface.action.Action#getDisabledImageDescriptor()
     */
    @Override
	public abstract ImageDescriptor getDisabledImageDescriptor();

    /*
     * (non-Javadoc)
     * @see org.eclipse.jface.action.Action#getHoverImageDescriptor()
     */
    @Override
	public abstract ImageDescriptor getHoverImageDescriptor();

    /*
     * (non-Javadoc)
     * @see org.eclipse.jface.action.Action#getImageDescriptor()
     */
    @Override
	public abstract ImageDescriptor getImageDescriptor();

    /**
     * Returns the workbench proxy associated with this action or <code>null</code>
     * if none. This is the workbench proxy to an {@link org.eclipse.ui.IActionDelegate}
     * that is using this action to perform its actual work. This is only used when
     * an {@link org.eclipse.ui.IActionDelegate} is using one of these actions to perform its
     * function.
     *
     * @return workbench proxy action or <code>null</code>
     */
    protected IAction getActionProxy() {
    	return fAction;
    }
}
