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

// $Id: MotionCausesMotionConstraintRule.java,v 1.4 2005/02/17 21:40:59 moltmans Exp $
// MotionCausesMotionConstraintRule.java -- 
// Author: Michael Oltmans <moltmans@ai.mit.edu> 
// Created: <Mon Jul 17 15:59:46 2000> 
// Time-stamp: <2005-02-16 14:03:39 moltmans> 
package rec.annotate.rules;

import rec.annotate.facts.*;
import java.util.*;
import rec.util.*;
import rec.geo.*;
import rec.tms.*;
import rec.sys.*;
import rec.simulate.widgets.*;
import rec.core.widgets.*;

/**
 * Recognize motions that might cause other motions via constraints
 **/
public class MotionCausesMotionConstraintRule extends AnnotateRule
{
  public LinkedList getTriggers() 
  {
    LinkedList triggers = new LinkedList();
    triggers.add( Type.MOTION_EVENT );
    triggers.add( Type.PART_CONSTRAINT );
    triggers.add( Type.MOTION_EVENT );
    
    return triggers;
  }

  public boolean match( LinkedList params ) 
  {
    MotionEvent cause = (MotionEvent)params.get(0);

    if( params.size() == 1 ) {
      return true;
    }

    WSimConstraint constraint = ((PartConstraint)params.get(1)).getConstraint();
    Body body1 = cause.getSubject();

    if( params.size() == 2  ) {
      return( constraint.getBodies().contains( body1.getBody() ) );
    }
    
    MotionEvent effect = (MotionEvent)params.get(2);
    Body body2 = effect.getBody();
    Notebook book = getNotebook();
    
    int num = book.numAnnotations( cause, effect );
    return ( (num >= 0) && (num < 2) &&
	     !cause.sameEvent( effect ) &&
	     !body1.sameFact( body2 ) &&
	     constraint.getBodies().contains( body2.getBody() ) );

  }

  public void run( Surface s, Notebook book, LinkedList params )
  {
    MotionEvent cause = (MotionEvent)params.get(0);
    MotionEvent effect = (MotionEvent)params.get(2);

    Causes fact = new Causes( cause, effect );
    book.myassert( fact, "MotionCausesMotionConstraintRule", params );
  }
}

