package edu.neu.ccs.demeter.aplib;

import java.util.*;

/**
 * The intersection of two traversals, that is, the set of paths that
 * are in both traversals.
 */
public class TraversalIntersection extends TraversalCombination {
  public TraversalIntersection(Traversal l, Traversal r)
    throws IncompatibleClassGraphsException
  {
    super(l, r);
  }

  public String toString() {
    return "intersection(" + left + ", " + right + ")";
  }

  protected List combineNodeSetLists(List l, List r) {
    List x = new ArrayList();
    for (Iterator li = l.iterator(); li.hasNext();) {
      Traversal.NodeSet ls = (Traversal.NodeSet) li.next();
      for (Iterator ri = r.iterator(); ri.hasNext();) {
	Traversal.NodeSet rs = (Traversal.NodeSet) ri.next();
	if (ls.sameNode(rs)) x.add(combineNodeSets(ls, rs));
      }
    }
    return Collections.unmodifiableList(x);
  }

  protected Traversal.NodeSet combineNodeSets(Traversal.NodeSet l,
					      Traversal.NodeSet r)
  {
    return (l == null || r == null) ? null : new NodeSet(l, r);
  }

  class NodeSet extends TraversalCombination.NodeSet {
    NodeSet(Traversal.NodeSet l, Traversal.NodeSet r) { super(l,r); }
    String indicesToString() { return "intersect" + super.indicesToString(); }
  }

  protected List combineEdgeSetLists(List l, List r) {
    List x = new ArrayList();
    for (Iterator li = l.iterator(); li.hasNext();) {
      Traversal.EdgeSet ls = (Traversal.EdgeSet) li.next();
      for (Iterator ri = r.iterator(); ri.hasNext();) {
	Traversal.EdgeSet rs = (Traversal.EdgeSet) ri.next();
	if (ls.sameEdge(rs)) x.add(combineEdgeSets(ls, rs));
      }
    }
    return Collections.unmodifiableList(x);
  }

  protected Traversal.EdgeSet combineEdgeSets(Traversal.EdgeSet l,
					      Traversal.EdgeSet r)
  {
    return (l == null || r == null) ? null : new EdgeSet(l, r);
  }

  class EdgeSet extends TraversalCombination.EdgeSet {
    EdgeSet(Traversal.EdgeSet l, Traversal.EdgeSet r) { super(l,r); }
    String indicesToString() { return "intersect" + super.indicesToString(); }
  }
}

