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

// -*-Mode: Java-*- 
// $Id: PropelsUtteranceRule.java,v 1.7 2005/02/17 21:40:57 moltmans Exp $
// PropelsUtteranceRule.java -- 
// Author: Michael Oltmans <moltmans@ai.mit.edu> 
// Created: <Mon May 15 16:25:56 2000> 
// Time-stamp: <2005-02-16 14:04:48 moltmans> 
package rec.annotate.rules;

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

/**
 * Recognize "pushes/propels" statements and asserts motion events and
 * causality for them.
 **/
public class PropelsUtteranceRule extends AnnotateRule
{

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

  /**
   * The rule matches when it describes one body propelling another
   * body.
   **/
  public boolean match( LinkedList params ) 
  {
    Sentence sent = (Sentence)params.get(0);
    if( !sent.isPropelsStatement() )
      return false;
    if( params.size() < 2 )
      return true;

    Body body1 = (Body)params.get(1);
    if( !sent.getSubject().equals( body1.getName() ) )
      return false;
    if( params.size() < 3 )
      return true;

    Body body2 = (Body)params.get(2);
    return ( !body2.equals( body1 ) &&
	     sent.getDirectObject().equals( body2.getName() ) );
  }

  public void run( Surface s, Notebook book, LinkedList params )
  {
    Sentence sent = (Sentence)params.get(0);
    Body body1 = (Body)params.get(1);
    Body body2 = (Body)params.get(2);

    PropelsEvent event = new PropelsEvent( s, sent, body1, body2 );
    book.myassert( event, "PropelsUtteranceRule", params );

    MotionEvent event1 = new MotionEvent( s, body1, event );
    MotionEvent event2 = new MotionEvent( s, body2, event );
    Causes causes = new Causes( event1, event2 );

    LinkedList list = new LinkedList();
    list.add( event1 );
    list.add( event2 );
    SubEvent subEvent = new SubEvent( event, list );

    params.add( event );
    book.myassert( event1, "PropelsUtteranceRule", params );
    book.myassert( event2, "PropelsUtteranceRule", params );

    params.add( event1 );
    params.add( event2 );
    book.myassert( causes, "PropelsUtteranceRule", params );
    book.myassert( subEvent, "PropelsUtteranceRule", params );
  }
}

