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

package rec.simulate.recognizers;
// -*-Mode: Java-*- 
// PinJointRecognizer.java -- 
// Author: Christine Alvarado <calvarad@ai.mit.edu> 
// Maintainer: Christine Alvarado <calvarad@ai.mit.edu> 
// Version: 
// Created: <Fri Jun  4 12:26:13 1999> 
// Time-stamp: <1999-11-08 22:43:31 calvarad> 
// Keywords: 

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

public class PinJointRecognizer extends Recognizer
{
  public PinJointRecognizer()
  {
  }

  // for now circles are recognized as pine joins if they overlap with 
  // other objects.  This does not allow a circle to become a joint if the
  // bodies it overlaps are drawn after the circle is drawn.  The attachments
  // are done at simulate time, though (I think...)
  public boolean recognize( Surface s, Widget w ) 
  {
    WSimCircle c = (WSimCircle)w;

    // quick hack--big circles are not pin joints  (-lw)
    if ( c.getRadius() > 20 )
      return false;

    Console.writeln( "Pin joint recognizer called" );

    // check to see if any of the bodies on the surface are included inside
    // the circle.  If so, join them.
    boolean isJoint = false;
    Iterator it = s.getWidgetsIterator();
    while( it.hasNext() ) {
      Widget b = (Widget)it.next();
      if( b instanceof WSimBody ) {
	if ( !b.equals( w ) ) {
	  if ( ((WSimBody)b).contains( c.getLocation().getCenter(), 0 ) ) {
	    isJoint = true;
	    break;
	  }
	  if ( b instanceof WSimCircle ) {
	      GCircle p = ((WSimCircle)b).getCircle();
	      if( c.getCircle().overlaps( p ) ) {
		  isJoint = true;
		  break;
	      }
	  }
	  else if ( b instanceof WSimGear){
	      GCircle p = ((WSimGear)b).getCircle();
	      if( c.getCircle().overlaps( p ) ) {
		  isJoint = true;
		  break;
	      }
	  }
	  else {
	    GPolygon p = ((WSimBody)b).getPolygon();
	    if( c.getCircle().overlaps( p ) ) {
	      isJoint = true;
	      break;
	    }
	  }
	}
      }
    }
    
    if ( isJoint ) {
      WSimPinJoint j = ((SimulateSurface)s).makeSimPinJoint( c );
      s.replaceWidget( c, j );
      return true;
    }

    return false;

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

    v.addElement( "rec.simulate.widgets.WSimCircle" );
    v.addElement( "rec.simulate.widgets.wm.WMSimCircle" );

    return( v.iterator() );
  }

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

    v.addElement( "rec.simulate.widgets.WSimPinJoint" );

    return( v.iterator() );
  }

}
