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

package rec.simulate.widgets;
// -*-Mode: Java-*- 
// WSimAnchor.java -- 
// Author: Christine Alvarado <calvarad@ai.mit.edu> 
// Maintainer: Christine Alvarado <calvarad@ai.mit.edu> 
// Version: 
// Created: <Wed May 26 14:08:41 1999> 
// Time-stamp: <2001-09-10 18:30:29 moltmans> 
// Keywords: 

import java.util.*;
import rec.util.*;
import rec.sys.*;
import rec.core.widgets.*;
import rec.geo.*;

public abstract class WSimRod extends WSimConstraint
{
  public WSimRod( WLine base )
  {
    setDefaultColor( "rod", "sim_constraint" );
    setEnglishName( "Rod" );

    m_head = null;
    m_tail = null;

    // fill up the components
    m_Components = new GShape[1];

    // ada: changed so that the angle size is updated
    GSegment gSeg = new GSegment( base.getHead(), base.getTail() );
    m_Angle = gSeg.getAngle();
    m_Components[0] = gSeg;
    
    m_Size = base.size();

    //    setColor( Color.black );
    
    m_Name = "Rod" + getId();

  }

  public boolean attach( WSimBody b )
  {
    if ( ( m_head != null ) && ( m_tail != null ) ) {
      Console.writeln( "Rod already attached to two bodies.  Cannot attach to body" + b.getName() );
      return false;
    }
    // check to see if one of the ends is touching or inside the body in 
    // question.
    // the offset is set to 10, meaning the end must be pretty close to 
    // the body
    if ( m_head == null ) {
      if ( b.includes( getHeadPoint(), 10 ) || 
	   b.contains( getHeadPoint(), 0 ) ) {
	m_head = b;
	return true;
      }
    }
    if ( m_tail == null ) {
      if ( b.includes( getTailPoint(), 10 ) || 
	   b.contains( getTailPoint(), 0 ) ) {
	m_tail = b;
	return true;
      }
    }
    return false;
    
  }

  public GPoint getHeadPoint() 
  {
    return ((GSegment)m_Components[0]).getHeadPoint();
  }

  public GPoint getTailPoint() 
  {
    return ((GSegment)m_Components[0]).getTailPoint();
  }

  public void detach() 
  {
    m_head = null;
    m_tail = null;
  }

  public int numAttached()
  {
    int count = 0;
    
    if ( m_head != null ) {
      count++;
    }
    if ( m_tail != null ) {
      count++;
    }
    return count;
  }

  public List getBodies() 
  {
    List list = new ArrayList( numAttached() );
    if( m_head != null )
      list.add( m_head );
    if( m_tail != null )
      list.add( m_tail );
    return list;
  }

  public GPoint getAttachmentPoint( WSimBody body ) 
  {
    if( body.equals( m_head ) )
      return getHeadPoint();
    else if( body.equals( m_tail ) )
      return getTailPoint();
    else
      return null;
  }

  
  public WSimBody getHeadBody() 
  {
    return m_head;
  }

  public WSimBody getTailBody() 
  {
    return m_tail;
  }
    
  public Collection isa()
  {
    Class c = null;
    try {
      c = Class.forName( "rec.simulate.widgets.WSimRod" );
    }
    catch( ClassNotFoundException e ) {

      Assert.error( "bad/unrecognized widget class name" );
    }

    Collection types = super.isa();
    types.add( c );
    
    return types;
  }

  
  protected WSimBody m_head;
  protected WSimBody m_tail;

} 

