/******************************************************************************
 * Copyright (c) 2005 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 brn.gui.fwdgraph.diagram.custom.layout;

import java.util.Iterator;

import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Status;
import org.eclipse.emf.transaction.TransactionalEditingDomain;
import org.eclipse.emf.transaction.util.TransactionUtil;
import org.eclipse.emf.workspace.AbstractEMFOperation;
import org.eclipse.gmf.runtime.diagram.ui.services.layout.LayoutService;
import org.eclipse.gmf.runtime.notation.Diagram;
import org.eclipse.gmf.runtime.notation.View;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.IWorkbenchWindowActionDelegate;
import org.eclipse.ui.PlatformUI;

import brn.gui.commands.ICommandIds;


/**
 * @author sshaw
 *
 * Sample action for demonstrating invokation of a custom layout provider.  In this
 * case the square layout provider is invoked through a separate menu action.
 */
public class SimulationPlacementLayoutAction extends Action
  implements IWorkbenchWindowActionDelegate {

	/**
	 * Title of diagram creation operation
	 */
	private static final String KEY_PLACEMENT_LAYOUT = "placementLayoutTitle"; //$NON-NLS-1$

  private final static String IMAGE = "/icons/outline_co.gif";

	/**
	 * Constructor
	 */
	public SimulationPlacementLayoutAction() {
    setText("Simulation Placement");
    // The id is used to refer to the action in a menu or toolbar
    setId(ICommandIds.CMD_LAYOUT_SIMULATION_PLACEMENT);
    // Associate the action with a pre-defined command, to allow key bindings.
    setActionDefinitionId(ICommandIds.CMD_LAYOUT_SIMULATION_PLACEMENT);
    setImageDescriptor(brn.gui.Activator.getImageDescriptor(IMAGE));
	}

	/**
	 * Walk the selected objects and creates a new diagram for each visited
	 * packages
	 */
	public void run(IAction action) {
    run();
	}

  /*
   * (non-Javadoc)
   * @see org.eclipse.ui.IActionDelegate#selectionChanged(org.eclipse.jface.action.IAction, org.eclipse.jface.viewers.ISelection)
   */
	public void selectionChanged(IAction action, ISelection selection) {
		//No-op
	}

  /*
   * (non-Javadoc)
   * @see org.eclipse.ui.IWorkbenchWindowActionDelegate#dispose()
   */
	public void dispose() {
		//No-op
	}

	/*
   * (non-Javadoc)
   * @see org.eclipse.ui.IWorkbenchWindowActionDelegate#init(org.eclipse.ui.IWorkbenchWindow)
	 */
  public void init(IWorkbenchWindow windowIn) {
		//No-op
	}

  /* (non-Javadoc)
   * @see org.eclipse.jface.action.Action#run()
   */
  @Override
  public void run() {

    /* Get selection */
    IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();

    // Get selection from the window
    final ISelection selection = window.getSelectionService().getSelection();
        Diagram diagramView = null;

        // get the editing domain
        if (selection instanceof IStructuredSelection) {

            IStructuredSelection structuredSelection = (IStructuredSelection) selection;

            // Walk selection
            for (Iterator i = structuredSelection.iterator(); i.hasNext();) {

                // Try to adapt the selection to a view
                Object selectedObject = i.next();
                if (selectedObject instanceof IAdaptable) {

                    // Try to get a View (new notation)
                    Object object = ((IAdaptable) selectedObject)
                        .getAdapter(View.class);

                    diagramView = ((View)object).getDiagram();
                }
            }
        }

        if (diagramView != null) {
            final Diagram diag = diagramView;
            TransactionalEditingDomain ted = TransactionUtil.getEditingDomain(diagramView);
            AbstractEMFOperation operation = new AbstractEMFOperation(
                ted, KEY_PLACEMENT_LAYOUT, null) {

                protected IStatus doExecute(IProgressMonitor monitor,
                        IAdaptable info)
                    throws ExecutionException {

                    LayoutService.getInstance().layout(diag,
                        SimulationPlacementLayoutProvider.PLACEMENT_LAYOUT);

                    return Status.OK_STATUS;
                }
            };
            try {
                operation.execute(new NullProgressMonitor(), null);
            }
            catch (Exception e) {
                throw new RuntimeException(e.getCause());
            }
        }
  }
}
