/*******************************************************************************
 * <copyright>
 *
 * Copyright (c) 2015-2018 SRC, SAP SE
 * 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:
 *    pjpaulin - initial API, implementation and documentation
 *    jsivadier - Bug 467502 - Improve DiagramComposite implementation without IWorkbenchPart
 *    mwenz - Bug 531207 - Prepare removal of deprecated CommandStackListener GEF interface
 *
 * </copyright>
 *
 *******************************************************************************/
package org.eclipse.graphiti.ui.editor;

import java.util.ArrayList;
import java.util.EventObject;
import java.util.Iterator;
import java.util.List;

import org.eclipse.draw2d.ColorConstants;
import org.eclipse.draw2d.IFigure;
import org.eclipse.gef.ContextMenuProvider;
import org.eclipse.gef.DefaultEditDomain;
import org.eclipse.gef.EditPart;
import org.eclipse.gef.GraphicalEditPart;
import org.eclipse.gef.GraphicalViewer;
import org.eclipse.gef.commands.CommandStack;
import org.eclipse.gef.commands.CommandStackEvent;
import org.eclipse.gef.commands.CommandStackEventListener;
import org.eclipse.gef.commands.CommandStackListener;
import org.eclipse.gef.ui.actions.ActionBarContributor;
import org.eclipse.gef.ui.actions.ActionRegistry;
import org.eclipse.gef.ui.actions.DeleteAction;
import org.eclipse.gef.ui.actions.PrintAction;
import org.eclipse.gef.ui.actions.RedoAction;
import org.eclipse.gef.ui.actions.SelectAllAction;
import org.eclipse.gef.ui.actions.UndoAction;
import org.eclipse.gef.ui.actions.UpdateAction;
import org.eclipse.gef.ui.parts.ScrollingGraphicalViewer;
import org.eclipse.gef.ui.parts.SelectionSynchronizer;
import org.eclipse.gef.ui.properties.UndoablePropertySheetPage;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.ISelectionListener;
import org.eclipse.ui.ISelectionService;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.actions.ActionFactory;

/**
 * Based on the original GEF GraphicalEditor class, this is a composite that
 * supports graphical editing.
 * 
 * @since 0.10
 * @experimental This API is in an experimental state and should be used by
 *               clients only with care, as it not final and can be removed or
 *               changed without prior notice!
 */
@SuppressWarnings("rawtypes")
public abstract class GraphicalComposite extends Composite
		implements CommandStackListener, CommandStackEventListener,
        ISelectionListener {

    @SuppressWarnings("serial")
    private static class ActionIDList extends ArrayList {

        @SuppressWarnings("unchecked")
        public boolean add(Object o) {
            if (o instanceof IAction) {
                try {
                    IAction action = (IAction) o;
                    o = action.getId();
                    throw new IllegalArgumentException(
                            "Action IDs should be added to lists, not the action: " + action); //$NON-NLS-1$
                }
                catch(IllegalArgumentException exc) {
                    exc.printStackTrace();
                }
            }
            return super.add(o);
        }
    }

    private DefaultEditDomain editDomain;
    private GraphicalViewer graphicalViewer;
    private ActionRegistry actionRegistry;
    private SelectionSynchronizer synchronizer;
    private List selectionActions = new ActionIDList();
    private List stackActions = new ActionIDList();
    private List propertyActions = new ActionIDList();

    /**
     * Constructs the editor part
     */
	public GraphicalComposite(Composite parent, int style) {
        super(parent, style);
		setLayout(new FillLayout());
    }

    /**
	 * When the command stack changes, the actions interested in the command
	 * stack are updated.
	 * 
	 * @param event
	 *            the change event
	 * @since 0.15
	 */
	@Override
	public void stackChanged(CommandStackEvent event) {
		if ((event.getDetail() & CommandStack.POST_MASK) != 0) {
			updateActions(stackActions);
		}
    }

	/**
	 * When the command stack changes, the actions interested in the command
	 * stack are updated.
	 * 
	 * @param event
	 *            the change event
	 * @deprecated Replaced by {@link #stackChanged(CommandStackEvent)} because
	 *             the class {@link CommandStackListener} is deprecated by GEF
	 */
	@Override
	public void commandStackChanged(EventObject event) {
		updateActions(stackActions);
	}

    /**
     * Called to configure the graphical viewer before it receives its contents. This is where the
     * root editpart should be configured. Subclasses should extend or override this method as
     * needed.
     */
    protected void configureGraphicalViewer() {
        getGraphicalViewer().getControl().setBackground(ColorConstants.listBackground);
    }

    /**
     * Creates actions for this editor. Subclasses should override this method to create and
     * register actions with the {@link ActionRegistry}.
     */
    @SuppressWarnings("unchecked")
    protected void createActions() {
		if (getWorkbenchPart() != null) {
			IWorkbenchPart workbenchPart = getWorkbenchPart();
			ActionRegistry registry = getActionRegistry();
			IAction action;

			action = new UndoAction(workbenchPart);
			registry.registerAction(action);
			getStackActions().add(action.getId());

			action = new RedoAction(workbenchPart);
			registry.registerAction(action);
			getStackActions().add(action.getId());

			action = new SelectAllAction(workbenchPart);
			registry.registerAction(action);

			action = new DeleteAction(workbenchPart);
			registry.registerAction(action);
			getSelectionActions().add(action.getId());

			registry.registerAction(new PrintAction(workbenchPart));
		}
    }

    /**
     * Creates the GraphicalViewer on the specified <code>Composite</code>.
     * 
     * @param parent
     *            the parent composite
     */
    protected void createGraphicalViewer() {
        GraphicalViewer viewer = new ScrollingGraphicalViewer();
        viewer.createControl(this);
        setGraphicalViewer(viewer);
        configureGraphicalViewer();
        hookGraphicalViewer();
        initializeGraphicalViewer();
    }

    /**
     * Realizes the Editor by creating it's Control.
     * <P>
     * WARNING: This method may or may not be called by the workbench prior to {@link #dispose()}.
     * 
     * @param parent
     *            the parent composite
     */
    public void createControl() {
        createGraphicalViewer();
    }

    /**
     * @see org.eclipse.ui.IWorkbenchPart#dispose()
     */
    public void dispose() {
		getCommandStack().removeCommandStackEventListener(this);
		if (getWorkbenchPart() != null)
			this.getWorkbenchPart().getSite().getWorkbenchWindow().getSelectionService()
                .removeSelectionListener(this);
        getEditDomain().setActiveTool(null);
		getActionRegistry().dispose();
        super.dispose();
    }

    /**
     * @see org.eclipse.ui.part.WorkbenchPart#firePropertyChange(int)
     */
    protected void firePropertyChange(int property) {
        /* TODO Need to communicate this to part somehow */
        // super.firePropertyChange(property);
        updateActions(propertyActions);
    }

    /**
     * Lazily creates and returns the action registry.
     * 
     * @return the action registry
     */
	public ActionRegistry getActionRegistry() {
        if (actionRegistry == null)
            actionRegistry = new ActionRegistry();
        return actionRegistry;
    }

    /**
     * Returns the adapter for the specified key.
     * 
     * <P>
     * <EM>IMPORTANT</EM> certain requests, such as the property sheet, may be made before or after
     * {@link #createPartControl(Composite)} is called. The order is unspecified by the Workbench.
     * 
     * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class)
     */
	public Object getAdapter(Class type) {
        if (type == org.eclipse.ui.views.properties.IPropertySheetPage.class) {
            return new UndoablePropertySheetPage(getCommandStack(), getActionRegistry().getAction(
                    ActionFactory.UNDO.getId()), getActionRegistry().getAction(
                    ActionFactory.REDO.getId()));
        }
        if (type == GraphicalViewer.class)
            return getGraphicalViewer();
        if (type == CommandStack.class)
            return getCommandStack();
        if (type == ActionRegistry.class)
            return getActionRegistry();
        if (type == EditPart.class && getGraphicalViewer() != null)
            return getGraphicalViewer().getRootEditPart();
        if (type == IFigure.class && getGraphicalViewer() != null)
            return ((GraphicalEditPart) getGraphicalViewer().getRootEditPart()).getFigure();
        return null;
    }

    /**
     * Returns the command stack.
     * 
     * @return the command stack
     */
    protected CommandStack getCommandStack() {
        return getEditDomain().getCommandStack();
    }

    /**
     * Returns the edit domain.
     * 
     * @return the edit domain
     */
    public DefaultEditDomain getEditDomain() {
        return editDomain;
    }

    /**
     * Returns the graphical viewer.
     * 
     * @return the graphical viewer
     */
    public GraphicalViewer getGraphicalViewer() {
        return graphicalViewer;
    }

    /**
     * Returns the list of {@link IAction IActions} dependant on property changes in the Editor.
     * These actions should implement the {@link UpdateAction} interface so that they can be updated
     * in response to property changes. An example is the "Save" action.
     * 
     * @return the list of property-dependant actions
     */
    protected List getPropertyActions() {
        return propertyActions;
    }

    /**
     * Returns the list of <em>IDs</em> of Actions that are dependant on changes in the workbench's
     * {@link ISelectionService}. The associated Actions can be found in the action registry. Such
     * actions should implement the {@link UpdateAction} interface so that they can be updated in
     * response to selection changes.
     * 
     * @see #updateActions(List)
     * @return the list of selection-dependant action IDs
     */
	public List getSelectionActions() {
        return selectionActions;
    }

    /**
     * Returns the selection syncronizer object. The synchronizer can be used to sync the selection
     * of 2 or more EditPartViewers.
     * 
     * @return the syncrhonizer
     */
    protected SelectionSynchronizer getSelectionSynchronizer() {
        if (synchronizer == null)
            synchronizer = new SelectionSynchronizer();
        return synchronizer;
    }

    /**
     * Returns the list of <em>IDs</em> of Actions that are dependant on the CommmandStack's state.
     * The associated Actions can be found in the action registry. These actions should implement
     * the {@link UpdateAction} interface so that they can be updated in response to command stack
     * changes. An example is the "undo" action.
     * 
     * @return the list of stack-dependant action IDs
     */
    protected List getStackActions() {
        return stackActions;
    }

    /**
     * Hooks the GraphicalViewer to the rest of the Editor. By default, the viewer is added to the
     * SelectionSynchronizer, which can be used to keep 2 or more EditPartViewers in sync. The
     * viewer is also registered as the ISelectionProvider for the Editor's PartSite.
     */
	public void hookGraphicalViewer() {
        getSelectionSynchronizer().addViewer(getGraphicalViewer());
		if (getWorkbenchPart() != null) {
			this.getWorkbenchPart().getSite().setSelectionProvider(getGraphicalViewer());
		}
    }

    protected void init() {
		getCommandStack().addCommandStackEventListener(this);
		if (getWorkbenchPart() != null) {
			this.getWorkbenchPart().getSite().getWorkbenchWindow().getSelectionService().addSelectionListener(this);
			initializeActionRegistry();
		}
        this.createControl();
    }

    /**
     * Initializes the ActionRegistry. This registry may be used by {@link ActionBarContributor
     * ActionBarContributors} and/or {@link ContextMenuProvider ContextMenuProviders}.
     * <P>
     * This method may be called on Editor creation, or lazily the first time
     * {@link #getActionRegistry()} is called.
     */
    protected void initializeActionRegistry() {
        createActions();
        updateActions(propertyActions);
        updateActions(stackActions);
    }

    /**
     * Override to set the contents of the GraphicalViewer after it has been created.
     * 
     * @see #createGraphicalViewer(Composite)
     */
    protected void initializeGraphicalViewer() {
        /* may be overridden */
    }

    /**
     * Returns <code>true</code> if the command stack is dirty
     * 
     * @see org.eclipse.ui.ISaveablePart#isDirty()
     */
    public boolean isDirty() {
        return getCommandStack().isDirty();
    }

    /**
     * @see org.eclipse.ui.ISelectionListener#selectionChanged(IWorkbenchPart, ISelection)
     */
    public void selectionChanged(IWorkbenchPart part, ISelection selection) {
        // If not the active part, ignore selection changed.
		if (getWorkbenchPart() != null
				&& getWorkbenchPart().equals(getWorkbenchPart().getSite().getPage().getActivePart()))
            updateActions(selectionActions);
    }

    /**
     * Sets the ActionRegistry for this EditorPart.
     * 
     * @param registry
     *            the registry
     */
    protected void setActionRegistry(ActionRegistry registry) {
        actionRegistry = registry;
    }

    /**
     * Sets the EditDomain for this EditorPart.
     * 
     * @param ed
     *            the domain
     */
	public void setEditDomain(DefaultEditDomain editDomain) {
		this.editDomain = editDomain;
    }

    public boolean setFocus() {
        return getGraphicalViewer().getControl().setFocus();
    }

    /**
     * Sets the graphicalViewer for this EditorPart.
     * 
     * @param viewer
     *            the graphical viewer
     */
	public void setGraphicalViewer(GraphicalViewer viewer) {
        getEditDomain().addViewer(viewer);
        this.graphicalViewer = viewer;
    }

    /**
     * A convenience method for updating a set of actions defined by the given List of action IDs.
     * The actions are found by looking up the ID in the {@link #getActionRegistry() action
     * registry}. If the corresponding action is an {@link UpdateAction}, it will have its
     * <code>update()</code> method called.
     * 
     * @param actionIds
     *            the list of IDs to update
     */
    protected void updateActions(List actionIds) {
        ActionRegistry registry = getActionRegistry();
        Iterator iter = actionIds.iterator();
        while (iter.hasNext()) {
            IAction action = registry.getAction(iter.next());
            if (action instanceof UpdateAction)
                ((UpdateAction) action).update();
        }
    }

	protected abstract IWorkbenchPart getWorkbenchPart();
}
