// (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 edu.mit.sketch.geom.*;

public abstract class WSimTorque extends WSimConstraint
{

    public WSimTorque( WToolkitArc arc, 
		       WLine line1, 
		       WLine line2,
		       boolean clockwise)
    {
	m_clockwise = clockwise;
	m_radius = arc.getArc().getToolkitArc().getRadius();
	Point center = arc.getArc().getToolkitArc().getCenter();
	m_center = new GPoint(center.x, center.y);

	setDefaultColor( "torque", "sim_constraint" );
	m_body1 = null;
	setEnglishName( "Torque" );

	// fill up the components
	m_Components = new GShape[3];
      
	Arc temparc = arc.getArc().getToolkitArc();
      
	m_Components[0] =  new GToolkitArc((Arc)temparc.copy());
      
	m_Components[1] = new GSegment(line1.getHead(),
				       line1.getTail());
	m_Components[2] = new GSegment(line2.getHead(),
				       line2.getTail());        
	m_Name = "Torque" + getId();

    }

    public GPoint getCenter(){
	Point center = ((GToolkitArc)m_Components[0]).getToolkitArc()
	    .getCenter();
	return new GPoint(center.x, center.y);    
    }

    // the torque must be attached to one body
    public boolean attach( WSimBody b )
    {
	if( m_body1 != null ) { 
	    Console.writeln( "Torque already attached to a body.  " + 
			     "Cannot attach to body " 
			     + b.getName() );
	    return false;
	} 
	// check to see if torque is inside the body in question
	if ( b.contains(getCenter(), 0 ) ) {
	    m_body1 = b; 
	    return true;
	}
	return false;
    
    }

    public void detach() 
    {
	m_body1 = null;
    }

    public int numAttached()
    {
	if ( m_body1 == null ) {
	    return 0;
	}
	else {
	    return 1;
	}
    }

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

    public GPoint getAttachmentPoint( WSimBody body ) 
    {
	if( body.equals( m_body1 ) )
	    return getLocation().getCenter();
	else
	    return null;
    }
    
    protected WSimBody m_body1;  
    protected boolean m_clockwise;
    protected double m_radius;
    protected GPoint m_center;

} 
