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

// -*-Mode: Java-*- 
// $Id: MotionEvent.java,v 1.2 2003/03/06 00:40:43 moltmans Exp $
// MotionEvent.java -- 
// Author: Michael Oltmans <moltmans@ai.mit.edu> 
// Created: <Mon May 08 00:21:04 2000> 
// Time-stamp: <2000-05-13 18:14:37 moltmans> 
package rec.annotate.rules;

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

/**
 * This class is for storing information about the motion of bodies
 **/
public class MotionEvent implements Event
{
  protected Surface m_surface;
  protected Body m_body;
  protected Arrow m_arrow;
  protected Sentence m_sentence;

  public MotionEvent( Surface s, Body body, Arrow arrow )
  {
    Assert.notNull( arrow, "Cannot make MotionEvent with null arrow" );
    m_surface = s;
    m_body = body;
    m_arrow = arrow;
  }

  public MotionEvent( Surface s, Body body, Sentence path )
  {
    Assert.notNull( path, "Cannot make MotionEvent with null sentence" );
    m_surface = s;
    m_body = body;
    m_sentence = path;
  }

  public Annotation getBase()
  {
    if( m_arrow != null )
      return m_arrow;
    else
      return m_sentence;
  }

  public Widget getBaseWidget() 
  {
    if( m_arrow != null )
      return m_arrow.getArrow();
    else
      return m_sentence.getSentence();
  }

  public boolean isBasedOn( Annotation a ) 
  {
    return getBase().equals( a );
  }
    
  public Body getBody()
  {
    return m_body;
  }

  /**
   * Get the path.  The tail is the start location and the head the
   * final destination.
   **/
  public Arrow getArrow()
  {
    return m_arrow;
  }

  public Sentence getUtternace() 
  {
    return m_sentence;
  }

  public String getFactType() 
  {
    return Type.MOTION_EVENT;
  }

  public boolean sameFact( Fact fact ) 
  {
    if( fact instanceof MotionEvent ) {
      MotionEvent f = (MotionEvent)fact;
      if( !m_body.equals( f.m_body ) )
	return false;
      if( m_arrow != null )
	return m_arrow.equals( f.m_arrow );
      else
	return m_sentence.equals( f.m_sentence );
    }
    return false;
  }

  public boolean sameEvent( MotionEvent event )
  {
    if( sameFact( event ) )
      return true;
    
    if( !m_body.equals( event.m_body ) )
      return false;

    LinkedList widgets = m_surface.getTimeOrderedElectedWidgets();

    int x1 = widgets.indexOf( getBaseWidget() );
    int x2 = widgets.indexOf( event.getBaseWidget() );

    Assert.check( (x1 >= 0) && (x2 >= 0), "Widgets not found in last N" );
    return Math.abs( x1 - x2 ) <= 2;
  }

  public String toString() 
  {
    if( m_arrow != null )
      return "<Motion: [" + m_body + "] along [" + m_arrow + "]>";
    return "<Motion: [" + m_body + "] " + m_sentence + ">";
  }
}
