// (c) MIT 2003.  All rights reserved.

package rec.fsm;


import java.awt.*;
import java.util.*;
import rec.core.*;
import rec.util.*;
import rec.sys.*;
import rec.geo.*;

public class EdgeBreaker extends Aligner
{
  public final double SHORTEST_EDGE = 20.0;

  int cur_name = 0;

  public EdgeBreaker()
  {
  }
  
  public boolean recognize( Surface s, Widget w )
  {
    final Node n = (Node)w;
    boolean cut = false;

    // look for an edge to break
    Iterator e = s.getWidgetsIterator();
    while( e.hasNext() )
      {
	Object o = e.next();
	if ( o instanceof rec.fsm.Edge )
	  {
	    Edge ed = (Edge)o;
	    if ( ed.includes( n.getCenter(), n.getRadius() ) 
		 && !n.contains( ed.getHead(), SHORTEST_EDGE )
		 && !n.contains( ed.getTail(), SHORTEST_EDGE ) )
	      {
		//Console.writeln( "Going to cut " + ed );
		cut = true;

		// split the edge.
		Node h = ed.getNode( true );
		Node t = ed.getNode( false );
		
		makeEdge( s, ed, h, n );
		makeEdge( s, ed, n, t );

		// kill old edge
		s.removeWidget( ed );
	      }
	  }
      }

    // never interrupt, just cut and move on.
    return false;
  }

  
  void makeEdge( Surface s, Edge old, Node beg, Node end )
  {
    Edge ne = null;
    GPoint p1 = ( beg != null ) ? beg.getCenter() : old.getHead();
    GPoint p2 = ( end != null ) ? end.getCenter() : old.getTail();    

    ne = new Edge( p1, p2, s );

    // fix up the arrowheads
    ne.arrow_head = old.hasArrowhead( true );
    ne.arrow_tail = old.hasArrowhead( false );

    ne.name = old.getName();

    s.addWidget( ne, true );		  

    if ( beg != null )
      doSnap( s, ne, beg, true );
    
    if ( end != null )
      doSnap( s, ne, end, false );
  }

  
  public Iterator getInputTypes()
  {
    Vector v = new Vector();
    
    v.addElement( "rec.fsm.Node" );
    
    return v.iterator();
  }

  public Iterator getOutputTypes() 
  {
    Vector v = new Vector();
    v.addElement( "rec.fsm.Node" );

    return v.iterator();
  }


}
