/******************************************************************************
 * 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 java.util.List;
import java.util.ListIterator;

import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.gmf.runtime.common.core.service.IOperation;
import org.eclipse.gmf.runtime.diagram.ui.services.layout.AbstractLayoutNodeProvider;
import org.eclipse.gmf.runtime.diagram.ui.services.layout.ILayoutNode;
import org.eclipse.gmf.runtime.diagram.ui.services.layout.ILayoutNodeOperation;
import org.eclipse.gmf.runtime.notation.Bounds;
import org.eclipse.gmf.runtime.notation.Diagram;
import org.eclipse.gmf.runtime.notation.Node;
import org.eclipse.gmf.runtime.notation.View;

/**
 * @author sshaw
 *
 * Example provider for layout. Calculates a square grid and positions each node
 * inside the grid.
 */
public class SimulationPlacementLayoutProvider extends
    AbstractLayoutNodeProvider {

  public static String PLACEMENT_LAYOUT = "Placement"; //$NON-NLS-1$

  /*
   * (non-Javadoc)
   *
   * @see org.eclipse.gmf.runtime.common.core.service.IProvider#provides(org.eclipse.gmf.runtime.common.core.service.IOperation)
   */
  public boolean provides(IOperation operation) {
    // check to make sure all node are contained in a diagram
    if (operation instanceof ILayoutNodeOperation) {
      Iterator nodes = ((ILayoutNodeOperation) operation).getLayoutNodes()
          .listIterator();
      if (nodes.hasNext()) {
        Node node = ((ILayoutNode) nodes.next()).getNode();
        View container = (View) node.eContainer();
        if (!(container instanceof Diagram))
          return false;
      }
    } else {
      return false;
    }

    // Provide for SQUARE_LAYOUT hint.
    // Note: To override the default layout which is invoked from the Arrange
    // menu
    // then the provider can compare against ILayoutNodeProvider.DEFAULT_LAYOUT.
    IAdaptable layoutHint = ((ILayoutNodeOperation) operation).getLayoutHint();
    String layoutType = (String) layoutHint.getAdapter(String.class);
    // return DEFAULT_LAYOUT.equals(layoutType);
    return PLACEMENT_LAYOUT.equals(layoutType);
  }

  public Runnable layoutLayoutNodes(List layoutNodes,
      boolean offsetFromBoundingBox, IAdaptable layoutHint) {

    final List lnodes = layoutNodes;

    return new Runnable() {
      public void run() {
        ListIterator li = lnodes.listIterator();
        while (li.hasNext()) {
          ILayoutNode lnode = (ILayoutNode) li.next();
          brn.gui.graph.model.Node model =
            (brn.gui.graph.model.Node) lnode.getNode().getElement();

          Bounds bounds = (Bounds) lnode.getNode().getLayoutConstraint();
          bounds.setX(4 * (int)model.getX());
          bounds.setY(4 * (int)model.getY());
          lnode.getNode().setLayoutConstraint(bounds);
        }
      }
    };

  }
}
