/*******************************************************************************
 * Copyright (c) 2001, 2006 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.wst.xsd.ui.internal.design.editparts;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.draw2d.AbstractRouter;
import org.eclipse.draw2d.Connection;
import org.eclipse.draw2d.ConnectionAnchor;
import org.eclipse.draw2d.ConnectionRouter;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.draw2d.geometry.PointList;
import org.eclipse.draw2d.geometry.Ray;
import org.eclipse.draw2d.geometry.Rectangle;

// TODO Manhattan connection router is final
public class XSDModelGroupRouter extends AbstractRouter
{
  public XSDModelGroupRouter()
  {
    super();
  }
  private Map rowsUsed = new HashMap();
  private Map colsUsed = new HashMap();

  private Map reservedInfo = new HashMap();

  private class ReservedInfo {
    public List reservedRows = new ArrayList(2);
    public List reservedCols = new ArrayList(2);
  }

  private static Ray  UP    = new Ray(0, -1),
              DOWN  = new Ray(0, 1),
              LEFT  = new Ray(-1, 0),
              RIGHT = new Ray(1, 0);


  /**
   * @see ConnectionRouter#invalidate(Connection)
   */
  public void invalidate(Connection connection) {
    removeReservedLines(connection);
  }

  private int getColumnNear(Connection connection, int r, int n, int x) {
    int min = Math.min(n, x),
      max = Math.max(n, x);
    if (min > r) {
      max = min;
      min = r - (min - r);
    }
    if (max < r) {
      min = max;
      max = r + (r - max);
    }
    int proximity = 0;
    int direction = -1;
    if (r % 2 == 1)
      r--;
    Integer i;
    while (proximity < r) {
      i = new Integer(r + proximity * direction);
      if (!colsUsed.containsKey(i)) {
        colsUsed.put(i, i);
        reserveColumn(connection, i);
        return i.intValue();
      }
      int j = i.intValue();
      if (j <= min)
        return j + 2;
      if (j >= max)
        return j - 2;
      if (direction == 1)
        direction = -1;
      else {
        direction = 1;
        proximity += 2;
      }
    }
    return r;
  }

  /**
   * Returns the direction the point <i>p</i> is in relation to the given rectangle.
   * Possible values are LEFT (-1,0), RIGHT (1,0), UP (0,-1) and DOWN (0,1).
   * 
   * @param r the rectangle
   * @param p the point
   * @return the direction from <i>r</i> to <i>p</i>
   */
  protected Ray getDirection(Rectangle r, Point p) {
    int i, distance = Math.abs(r.x - p.x);
    Ray direction;
    
    direction = LEFT;

    i = Math.abs(r.y - p.y);
    if (i <= distance) {
      distance = i;
      direction = UP;
    }

    i = Math.abs(r.bottom() - p.y);
    if (i <= distance) {
      distance = i;
      direction = DOWN;
    }

    i = Math.abs(r.right() - p.x);
    if (i < distance) {
      distance = i;
      direction = RIGHT;
    }

    return direction;
  }

  protected Ray getEndDirection(Connection conn) {
    ConnectionAnchor anchor = conn.getTargetAnchor();
    Point p = getEndPoint(conn);
    Rectangle rect;
    if (anchor.getOwner() == null)
      rect = new Rectangle(p.x - 1, p.y - 1, 2, 2);
    else {
      rect = conn.getTargetAnchor().getOwner().getBounds().getCopy();
      conn.getTargetAnchor().getOwner().translateToAbsolute(rect);
    }
    return getDirection(rect, p);
  }

  protected int getRowNear(Connection connection, int r, int n, int x) {
    int min = Math.min(n, x),
      max = Math.max(n, x);
    if (min > r) {
      max = min;
      min = r - (min - r);
    }
    if (max < r) {
      min = max;
      max = r + (r - max);
    }

    int proximity = 0;
    int direction = -1;
    if (r % 2 == 1)
      r--;
    Integer i;
    while (proximity < r) {
      i = new Integer(r + proximity * direction);
      if (!rowsUsed.containsKey(i)) {
        rowsUsed.put(i, i);
        reserveRow(connection, i);
        return i.intValue();
      }
      int j = i.intValue();
      if (j <= min)
        return j + 2;
      if (j >= max)
        return j - 2;
      if (direction == 1)
        direction = -1;
      else {
        direction = 1;
        proximity += 2;
      }
    }
    return r;
  }

  protected Ray getStartDirection(Connection conn) {
    ConnectionAnchor anchor = conn.getSourceAnchor();
    Point p = getStartPoint(conn);
    Rectangle rect;
    if (anchor.getOwner() == null)
      rect = new Rectangle(p.x - 1, p.y - 1, 2, 2);
    else {
      rect = conn.getSourceAnchor().getOwner().getBounds().getCopy();
      conn.getSourceAnchor().getOwner().translateToAbsolute(rect);
    }
    return getDirection(rect, p);
  }

  protected void processPositions(Ray start, Ray end, List positions, 
                    boolean horizontal, Connection conn) {
    removeReservedLines(conn);

    int pos[] = new int[positions.size() + 2];
    if (horizontal)
      pos[0] = start.x;
    else
      pos[0] = start.y;
    int i;
    for (i = 0; i < positions.size(); i++) {
      pos[i + 1] = ((Integer)positions.get(i)).intValue();
    }
    if (horizontal == (positions.size() % 2 == 1))
      pos[++i] = end.x;
    else
      pos[++i] = end.y;

    PointList points = new PointList();
    points.addPoint(new Point(start.x, start.y));
    Point p;
    int current, prev, min, max;
    boolean adjust;
    for (i = 2; i < pos.length - 1; i++) {
      horizontal = !horizontal;
      prev = pos[i - 1];
      current = pos[i];

      adjust = (i != pos.length - 2);
      if (horizontal) {
        if (adjust) {
          min = pos[i - 2];
          max = pos[i + 2];
          pos[i] = current = getRowNear(conn, current, min, max);
        }
        p = new Point(prev, current);
      } else {
        if (adjust) {
          min = pos[i - 2];
          max = pos[i + 2];
          pos[i] = current = getColumnNear(conn, current, min, max);
        }
        p = new Point(current, prev);
      }
      points.addPoint(p);
    }
    points.addPoint(new Point(end.x, end.y));
    conn.setPoints(points);
  }

  /**
   * @see ConnectionRouter#remove(Connection)
   */
  public void remove(Connection connection) {
    removeReservedLines(connection);
  }

  protected void removeReservedLines(Connection connection) {
    ReservedInfo rInfo = (ReservedInfo) reservedInfo.get(connection);
    if (rInfo == null) 
      return;
    
    for (int i = 0; i < rInfo.reservedRows.size(); i++) {
      rowsUsed.remove(rInfo.reservedRows.get(i));
    }
    for (int i = 0; i < rInfo.reservedCols.size(); i++) {
      colsUsed.remove(rInfo.reservedCols.get(i));
    }
    reservedInfo.remove(connection);
  }

  protected void reserveColumn(Connection connection, Integer column) {
    ReservedInfo info = (ReservedInfo) reservedInfo.get(connection);
    if (info == null) {
      info = new ReservedInfo();
      reservedInfo.put(connection, info);
    }
    info.reservedCols.add(column);
  }

  protected void reserveRow(Connection connection, Integer row) {
    ReservedInfo info = (ReservedInfo) reservedInfo.get(connection);
    if (info == null) {
      info = new ReservedInfo();
      reservedInfo.put(connection, info);
    }
    info.reservedRows.add(row);
  }

  /**
   * @see ConnectionRouter#route(Connection)
   */
  public void route(Connection conn) {
    if ((conn.getSourceAnchor() == null) || (conn.getTargetAnchor() == null)) 
      return;
    int i;
    Point startPoint = getStartPoint(conn);
    conn.translateToRelative(startPoint);
    Point endPoint = getEndPoint(conn);
    conn.translateToRelative(endPoint);

    Ray start = new Ray(startPoint);
    Ray end = new Ray(endPoint);
    Ray average = new Ray(startPoint.x + 2, startPoint.y); // start.getAveraged(end);

    Ray direction = new Ray(start, end);
    Ray startNormal = getStartDirection(conn);
    Ray endNormal   = getEndDirection(conn);

    List positions = new ArrayList(5);
    boolean horizontal = startNormal.isHorizontal();
    if (horizontal) 
      positions.add(new Integer(start.y));
    else
      positions.add(new Integer(start.x));
    horizontal = !horizontal;

    if (startNormal.dotProduct(endNormal) == 0) {
      if ((startNormal.dotProduct(direction) >= 0) 
        && (endNormal.dotProduct(direction) <= 0)) {
        // 0
      } else {
        // 2
        if (startNormal.dotProduct(direction) < 0)
          i = startNormal.similarity(start.getAdded(startNormal.getScaled(10)));
        else {
          if (horizontal) 
            i = average.y;
          else 
            i = average.x;
        }
        positions.add(new Integer(i));
        horizontal = !horizontal;

        if (endNormal.dotProduct(direction) > 0)
          i = endNormal.similarity(end.getAdded(endNormal.getScaled(10)));
        else {
          if (horizontal) 
            i = average.y;
          else 
            i = average.x;
        }
        positions.add(new Integer(i));
        horizontal = !horizontal;
      }
    } else {
      if (startNormal.dotProduct(endNormal) > 0) {
        //1
        if (startNormal.dotProduct(direction) >= 0)
          i = startNormal.similarity(start.getAdded(startNormal.getScaled(10)));
        else
          i = endNormal.similarity(end.getAdded(endNormal.getScaled(10)));
        positions.add(new Integer(i));
        horizontal = !horizontal;
      } else {
        //3 or 1
        if (startNormal.dotProduct(direction) < 0) {
          i = startNormal.similarity(start.getAdded(startNormal.getScaled(10)));
          positions.add(new Integer(i));
          horizontal = !horizontal;
        }

        if (horizontal) 
          i = average.y;
        else 
          i = average.x;
        positions.add(new Integer(i));
        horizontal = !horizontal;

        if (startNormal.dotProduct(direction) < 0) {
          i = endNormal.similarity(end.getAdded(endNormal.getScaled(10)));
          positions.add(new Integer(i));
          horizontal = !horizontal;
        }
      }
    }
    if (horizontal) 
      positions.add(new Integer(end.y));
    else 
      positions.add(new Integer(end.x));
    
    processPositions(start, end, positions, startNormal.isHorizontal(), conn);
  }

}
