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

package rec.simulate.widgets;

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

public abstract class WSimRotationalSpring extends WSimConstraint
{

  public WSimRotationalSpring( GToolkitSpiral spiral)
  {
      setDefaultColor( "rotationalspring", "sim_constraint" );
      m_body1 = null;
      setEnglishName( "Rotational Spring" );

      m_Components = new GShape[1];

      m_Components[0] = spiral;
      
      m_Name = "RotationalSpring" + getId();
      
  }

    public double getRotations(){
	return ((GToolkitSpiral)m_Components[0]).getRotations();
    }

  // the rotational spring can be attached to one or two bodies
    public boolean attach( WSimBody b )
    {	
	if( (m_body1 != null) && (m_body2 != null) ) {
	    Console.writeln( "Rotational Spring already attached to two bodies." );
	    return false;
	}
	if ( b.contains( getLocation().getCenter(), 0 ) ) {
	    if ( m_body1 == null ) {
		m_body1 = b;
		return true;
	    }
	    else {
		m_body2 = b;
		return true;
	    }
	}

	
	return false;
    }
    
    public void detach() 
    {
	m_body1 = null;
	m_body2 = null;
    }
    
    public int numAttached()
    {
	int count = 0;
	if ( m_body1 != null ) {
	    count++;
	}
	if ( m_body2 != null ) {
	    count++;
	}

	return count;
	
    }
    
    public List getBodies() 
    {
	List list = new ArrayList( numAttached() );
	if( m_body1 != null )
	    list.add( m_body1 );
	if( m_body2 != null )
	    list.add( m_body2 );
	return list;
    }
    
    public GPoint getAttachmentPoint( WSimBody body ) 
    {
	if( body.equals( m_body1 )|| body.equals( m_body2  )){
	    return getAdjustedCenterPoint();
	}
	else{
	    return null;
	}
    }


    public GPoint getAdjustedCenterPoint(){

	double distancebody1 = Double.MAX_VALUE;
	double distancebody2 = Double.MAX_VALUE;
	
	
	if (m_body1 == null && m_body2 == null){
	    return getLocation().getCenter();
	}
	if (m_body1 != null){
	    distancebody1 = Geometry.distance(m_body1.getLocation().getCenter(),
					      getLocation().getCenter());
	}
	if (m_body2 != null){
	    distancebody2 = Geometry.distance(m_body2.getLocation().getCenter(),
					      getLocation().getCenter());
	}
      
	if (distancebody1 <= distancebody2){
	    if (distancebody1 < 10){
		return m_body1.getLocation().getCenter();
	    }
	}
	else{
	    if (distancebody2 < 10){
		return m_body2.getLocation().getCenter();
	    }
	}
      
	return getLocation().getCenter();
      
    }

    
    protected WSimBody m_body1;
    protected WSimBody m_body2;
    
}
