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

// $Id: Recognizer.java,v 1.8 2003/03/06 00:40:39 moltmans Exp $
// Time-stamp: <2000-03-11 18:59:37 moltmans>
package rec.sys;


////////////////////////////////////////////////////////////////////////////////
//
// FILE:	Recognizer.java
//
// AUTHOR:	Manoj D. Muzumdar
//		archon@ai.mit.edu
//
//              Adapted from code written by Luke Weisman
//              luke@mit.edu
//
// DATE:	June, 1998
//
// COPYRIGHT:	Massachusetts Institute of Technology
//		All rights reserved.
//
// PURPOSE:	Drawing recognition
//
// HISTORY:     September, 1998
//              MDM
//              modified to account for new module management and transition
//                   structure as well as a slightly modified recognition
//                   scheme
//
////////////////////////////////////////////////////////////////////////////////


import java.io.*;
import java.util.*;
import rec.util.*;

public abstract class Recognizer implements Serializable
{
  public Recognizer()
  {
    m_Id = new Id();

    // check the getOutputTypes method for valid class names.
    Class c = null;
    Iterator outputTypes = getOutputTypes();
    Assert.check( outputTypes != null, "Recognizer " + this + " should return an empty iterator instead of null for getOutputTypes()" );

    while ( outputTypes.hasNext() ) { 
      String outputType = (String)outputTypes.next();
      try {
	c = Class.forName( outputType );
      }
      catch( ClassNotFoundException e ) {
	Assert.error( "bad/unrecognized widget class name in output types of "
		      + this + ": " + outputType);
      }
    }

    Iterator inputTypes = getInputTypes();
    Assert.check( inputTypes != null, "Recognizer " + this + " must have at least one input type." );

    while ( inputTypes.hasNext() ) { 
      String inputType = (String)inputTypes.next();
      try {
	c = Class.forName( inputType );
      }
      catch( ClassNotFoundException e ) {
	Assert.error( "bad/unrecognized widget class name in input types of "
		      + this + ": " + inputType);
      }
    }

  }

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

  /**
   * Called by Surface on each relevant Recognizer.
   *
   * @param w   The last thing added to the Surface, the Widget
   *     which triggered this call.
   *
   * @return Return false to continue recognizing on the spark widget;
   //    return true otherwise.
   */
  public abstract boolean recognize( Surface s, Widget w );

  /**
   * @return the name of the Recognizer
   */
  public final String toString()
  {
    return( getClass().getName() );
  }

  /**
   * @return An Iterator of types in strings for the widget inputs that the
   *     recognizer accepts.  It must be a non-empty iterator and never null.
   */
  public abstract Iterator getInputTypes();

  /**
   * @return An Iterator of types in strings for the widget inputs
   *     that the recognizer outputs.  It can be an iterator or an
   *     empty iterator but not null.
   **/
  public abstract Iterator getOutputTypes();

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

  public final Id getId()
  {
    return( m_Id );
  }

  public final boolean equals( Recognizer r )
  {
    return( m_Id.equals( r.m_Id ) );
  }

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

  private Id m_Id;
}

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