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

// -*-Mode: Java-*- 
// $Id: Lever.java,v 1.3 2003/03/06 00:40:49 moltmans Exp $
// Lever.java -- 
// Author: Michael Oltmans <moltmans@ai.mit.edu> 
// Created: <Tue May 16 15:46:48 2000> 
// Time-stamp: <2000-07-19 16:56:39 moltmans> 
package rec.annotate.facts;

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

/**
 * This class is for storing information about pinjoints
 **/
public class Lever extends Annotation
{
  protected PinJoint m_pin;
  protected Body m_body;
  protected String m_name;

  public Lever( PinJoint pin, Body body, String name )
  {
    super( body.getStartTime(), body.getEndTime() );
    Assert.notNull( pin, "Cannot make Lever with null pin" );
    Assert.notNull( body, "Cannot make Lever with null body" );
    m_pin = pin;
    m_body = body;
    m_name = name;
  }

  public PinJoint getPinJoint()
  {
    return m_pin;
  }

  public Body getBody() 
  {
    return m_body;
  }

  public String getName() 
  {
    return m_name;
  }

  public boolean sameHalf( GPoint p1, GPoint p2 )
  {
    GSegment axis = null;

    if( m_body.getBody() instanceof WSimQuadrilateral ) {
      WSimQuadrilateral quad = (WSimQuadrilateral)m_body.getBody();
      axis = quad.getMinorAxis();
    }
    else if( m_body.getBody() instanceof WSimRectangle ) {
      WSimRectangle rect = (WSimRectangle)m_body.getBody();
      axis = rect.getMinorAxis();
    }

    GPoint pinLoc = m_pin.getPinJoint().getLocation().getCenter();
    GPoint projection1 = axis.perpendicular( p1 );
    GPoint projection2 = axis.perpendicular( p2 );
    GPoint pinPoint = axis.perpendicular( pinLoc );

    double d1 = Geometry.distance( axis.getHeadPoint(), projection1 );
    double d2 = Geometry.distance( axis.getHeadPoint(), projection2 );
    double dPin = Geometry.distance( axis.getHeadPoint(), pinPoint );
    return ((d1 <= dPin &&
	     d2 <= dPin) ||
	    (d1 >= dPin &&
	     d2 >= dPin));
  }
  


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

  public boolean sameFact( Fact fact ) 
  {
    if( fact instanceof Lever ) {
      Lever lever = (Lever)fact;
      return ( m_pin.sameFact( lever.m_pin ) &&
	       m_body.sameFact( lever.m_body ) &&
	       m_name.equals( lever.m_name ) );
    }
    return false;
  }

  public String toEnglish() 
  {
    return m_body.toEnglish() + " and " + m_pin.toEnglish() +
      " form a lever";
  }

  public String toString() 
  {
    return "<Lever: [" + m_body + "] [" + m_pin + "]>";
  }
}
