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

package rec.fsm;

////////////////////////////////////////////////////////////////////////////////
//
// FILE:	SmartNodeRecognizer.java
//
// AUTHOR:      Luke Weisman
//              luke@ai.mit.edu
//
// DATE:	June, 1998
//
// COPYRIGHT:	Massachusetts Institute of Technology
//		All rights reserved.
//
// PURPOSE:	Drawing recognition system
//
////////////////////////////////////////////////////////////////////////////////


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


public class SmartNodeRecognizer extends NodeRecognizer
{

  public SmartNodeRecognizer()
  {
  }

  /////////////////////////////////////////////////////////////////////////////
  
  /**
   * Each new stroke generated gets put into the pipe here.
   *     It will remove and add objects to the 'out' target
   *     as it deems fit.
   *
   * @return a Transition if changes were made.
   */
  public boolean recognize( Surface s, Widget w )
  {
    final WCircle c = (WCircle)w;
    
    if ( c.getRadius() < 3.0 * Node.NORMAL_RADIUS )
      {

	// look for nearby lines/edges
	GeometryCalculator gc = new GeometryCalculator( s );
	GeoFunction gf = new GeoFunction() {
	  public boolean check( VisibleWidget vw )
	    {
	      if ( vw instanceof WLine )
		{
		  WLine wl = (WLine)vw;
		  if ( c.contains( wl.getHead(), 5 )
		       || c.contains( wl.getTail(), 5 ) )
		    return true;
		}
	      else if ( vw instanceof Edge )
		{
		  Edge wl = (Edge)vw;
		  if ( c.contains( wl.getHead(), 5 )
		       || c.contains( wl.getTail(), 5 ) 
		       || ( wl.includes( c.getCenter(), 20 ) ) )
		    return true;
		}
	      return false;
	    }
	};
	Widget fw = gc.findWidget( gf );

	if ( fw == null )
	  return false;

	gc.recheck( gf );

	Console.writeln( "node (smart) online" );

	Node n = new Node( c, s );
	s.replaceWidget( c, n );

	return true;
      }
    
    return false;
  }

  public Iterator getInputTypes()
  {
    Vector v = new Vector();

    v.addElement( "rec.core.WCircle" );

    return( v.iterator() );
  }

  public Iterator getOutputTypes()
  {

    Vector v = new Vector();
    v.addElement( "rec.fsm.Node" );

    return v.iterator();
  }
}

////////////////////////////////////////////////////////////////////////////////
