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

// -*-Mode: Java-*- 
// $Id: ExternalMotionUtteranceRule.java,v 1.4 2005/02/17 21:41:00 moltmans Exp $
// ExternalMotionUtteranceRule.java -- 
// Author: Michael Oltmans <moltmans@ai.mit.edu> 
// Created: <Mon May 15 16:25:56 2000> 
// Time-stamp: <2005-02-16 14:03:41 moltmans> 
package rec.annotate.rules;

import rec.annotate.facts.*;
import java.util.*;
import rec.util.*;
import rec.tms.*;
import rec.sys.*;

/**
 * Recognize "pushes/propels/moves" statements initiated by an
 * external force, like the user.  e.g. "Someone moves the ball up"
 **/
public class ExternalMotionUtteranceRule extends AnnotateRule
{

  public LinkedList getTriggers() 
  {
    LinkedList triggers = new LinkedList();
    triggers.add( Type.SENTENCE );
    triggers.add( Type.BODY );
    return triggers;
  }

  /**
   * The rule matches when it describes an external force propelling a
   * body.
   **/
  public boolean match( LinkedList params ) 
  {

    // must be a motion/propulsion sentence that has an external
    // subject and a directo object.
    Sentence sent = (Sentence)params.get(0);
    if( !( ( sent.isPropelsStatement() ||
	     sent.isMovesStatement() )
	   &&
	   sent.isSubjectExternal() &&
	   sent.hasDirectObject() ) )
    {
      return false;
    }
    if( params.size() < 2 )
      return true;

    // The direct object must be the body.
    Body body = (Body)params.get(1);
    return sent.getDirectObject().equals( body.getName() );
  }
  
  public void run( Surface s, Notebook book, LinkedList params )
  {
    Sentence sent = (Sentence)params.get(0);
    Body body = (Body)params.get(1);

    MotionEvent event = new MotionEvent( s, body, sent );
    ExternalAction action = new ExternalAction( event, sent );

    book.myassert( event, "ExternalMotionUtteranceRule", params );

    params.add( event );
    book.myassert( action, "ExternalMotionUtteranceRule", params );
  }
}

