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

////////////////////////////////////////////////////////////////////////////////
//
// FILE:	CompressionSpringRecognizer.java
//
// AUTHOR:	Manoj D. Muzumdar
//		archon@ai.mit.edu
//
// DATE:	Mar 99
//
// COPYRIGHT:	Massachusetts Institute of Technology
//		All rights reserved.
//
// PURPOSE:	Mechanical engineering drawing recognition
//
// HISTORY:     Mar 99  archon  created
//
////////////////////////////////////////////////////////////////////////////////

package rec.meche;

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

public class CompressionSpringRecognizer extends Recognizer
{
  public static WMCompressionSpring isCompressionSpring( WMSpring s, WLine l1,
							 WLine l2 )
  {
    GSegment head = (GSegment)s.getComponents()[0];
    GSegment tail = (GSegment)s.getComponents()[10];
    double unit = s.size() / 5.0;

    GSegment s1 = l1.getLine();
    GSegment s2 = l2.getLine();

    // Check that the sizes match first.

    if( !( Estimator.isSameSize( unit, s1.size() )
	   && Estimator.isSameSize( unit, s2.size() ) ) )
      return( null );

    if( Estimator.connects( head, s1, 20.0 ) == head.getHeadPoint()
	&& Estimator.connects( tail, s2, 20.0 ) == tail.getTailPoint()
	&& Estimator.areAngle45( head, s1 )
	&& Estimator.areAngle45( tail, s2 ) ) {

      return( new WMCompressionSpring( s.getCenter(), s.getAngle(), s.size(),
				       null ) );
    }

    if( Estimator.connects( head, s2, 20.0 ) == head.getHeadPoint()
	&& Estimator.connects( tail, s1, 20.0 ) == tail.getTailPoint()
	&& Estimator.areAngle45( head, s2 )
	&& Estimator.areAngle45( tail, s1 ) ) {

      return( new WMCompressionSpring( s.getCenter(), s.getAngle(), s.size(),
				       null ) );
    }

    return( null );
  }

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

  public CompressionSpringRecognizer()
  {
  }

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

  public boolean recognize( Surface s, Widget w )
  {
    GeometryCalculator gc = new GeometryCalculator( s );
   
    Vector vect = new Vector( gc.getVisibleWidgets() );
    

    if( vect.size() < 3 )
      return( false );

    // Try to match with two other lines.

    if( w instanceof WMSpring ) {

      WMSpring sp = (WMSpring)w;

      for( int i = 0; i < vect.size(); ++i ) {

	Widget vw1 = (Widget)vect.elementAt( i );

	if( vw1 instanceof WLine ) {

	  for( int j = 0; j < vect.size(); ++j ) {

	    Widget vw2 = (Widget)vect.elementAt( j );
	      
	    if( vw2 instanceof WLine && !vw2.equals( vw1 ) ) {
	      
	      WMCompressionSpring part = isCompressionSpring( sp, (WLine)vw1,
							      (WLine)vw2 );

	      if( part != null ) {

		s.removeWidget( sp );
		s.removeWidget( vw1 );
		s.removeWidget( vw2 );
		s.addWidget( part );

		return( true );
	      }
	    }
	  }
	}
      }
    }

    // Try to match with another line and a spring.

    if( w instanceof WLine ) {

      WLine l = (WLine)w;

      for( int i = 0; i < vect.size(); ++i ) {

	Widget vw1 = (Widget)vect.elementAt( i );

	if( vw1 instanceof WMSpring ) {

	  for( int j = 0; j < vect.size(); ++j ) {

	    Widget vw2 = (Widget)vect.elementAt( j );

	    if( vw2 instanceof WLine && !vw2.equals( l ) ) {

	      WMCompressionSpring part = isCompressionSpring( (WMSpring)vw1,
							      l, (WLine)vw2 );

	      if( part != null ) {

		s.removeWidget( vw1 );
		s.removeWidget( l );
		s.removeWidget( vw2 );
		s.addWidget( part );

		return( true );
	      }
	    }
	  }
	}
      }
    }

    return( false );
  }

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

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

    v.addElement( "rec.core.widgets.WLine" );
    v.addElement( "rec.meche.WMSpring" );

    return( v.iterator() );
  }

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

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

    return( v.iterator() );
  }
}

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