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

////////////////////////////////////////////////////////////////////////////////
//
// FILE:	WasherRecognizer.java
//
// AUTHOR:	Manoj D. Muzumdar
//		archon@ai.mit.edu
//
// DATE:	April 99
//
// COPYRIGHT:	Massachusetts Institute of Technology
//		All rights reserved.
//
// PURPOSE:	Washer recognition
//
// HISTORY:     April 99  archon  created
//
////////////////////////////////////////////////////////////////////////////////

package rec.meche;

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

public class WasherRecognizer extends Recognizer
{
  public static WMWasher isWasher( WOval o1, WOval o2 )
  {
    GOval bo = o1.getOval();
    GOval lo = o2.getOval();

    for( int i = 0; i < 2; ++i ) {

      if( i == 1 ) {
	GOval tmp = bo;
	bo = lo;
	lo = tmp;
      }

      double dist = Geometry.distance( bo.getCenter(), lo.getCenter() );

      GSegment bmajor = bo.getMajorAxis();
      GSegment bminor = bo.getMinorAxis();

      GSegment lmajor = lo.getMajorAxis();
      GSegment lminor = lo.getMinorAxis();

      if( bmajor.getLength() > lmajor.getLength() + dist * 2.0
	  && bminor.getLength() > lminor.getLength() + dist * 2.0 ) {

	return( new WMWasher( bo.getCenter(),
			      Geometry.angle( bminor.getHeadPoint(),
					      bminor.getTailPoint() ),
			      bo.size(),
			      null ) );
      }
    }

    return( null );
  }

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

  public WasherRecognizer()
  {
  }

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

  public boolean recognize( Surface s, Widget w )
  {
    WOval o = (WOval)w;

    GeometryCalculator gc = new GeometryCalculator( s );

    Iterator iter = gc.getVisibleWidgets().iterator();

    if( iter == null )
      return( false );

    while( iter.hasNext() ) {

      Widget vw = (Widget)iter.next();

      if( !( vw instanceof WOval ) || vw.equals( o ) )
	continue;

      WOval wo = (WOval)vw;

      WMWasher part = null;

      if( (part = isWasher( o, wo )) != null ) {

	s.removeWidget( o );
	s.removeWidget( wo );

	s.addWidget( part );

	return( true );
      }
    }

    return( false );
  }

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

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

    v.addElement( "rec.core.widgets.WOval" );

    return( v.iterator() );
  }

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

    v.addElement( "rec.meche.WMWasher" );

    return( v.iterator() );
  }
}

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