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

// $Id: WSimBody.java,v 1.11 2003/06/03 15:32:18 cadlerun Exp $
// Time-stamp: <2001-02-06 12:53:50 moltmans>
package rec.simulate.widgets;


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


// This class is the base class of all the simulatable objects.  It is not
// very exciting, just holds the polygon instance from the widget it is 
// made from.  Maybe this will be more exciting later.
public abstract class WSimBody extends WSimObject
{
  protected GPolygon m_Polygon;
  protected double m_Mass;
  protected double m_Density;
  protected HashSet m_constraints;


  public abstract GShape getShape();

  // this must be overridden
  protected WSimBody(  )
  {
    setDefaultColor( "sim_body" );
    m_Polygon = null;
    m_constraints = new HashSet();
  }

  public void addConstraint( WSimConstraint constraint ) 
  {
    m_constraints.add( constraint );
  }

  public void clearConstraints() 
  {
    m_constraints.clear();
  }

  public Set getConstraints() 
  {
    return new HashSet( m_constraints );
  }

  public double mass()
  {
    return m_Mass;
  }

  public void setMass( double m )
  {
    m_Mass = m;
    // also change density here!!
  }

  public void setDensity( double d )
  {
    m_Density = d;
    // also change mass here!!
  }

  public boolean isAnchored() 
  {
    Iterator it = m_constraints.iterator();
    
    while( it.hasNext() ) {
      WSimConstraint c = (WSimConstraint)it.next();
      if( c instanceof WSimAnchor )
	return true;
    }
    return false;
  }
  



  ////////////////////////////////////////////////////////////////////


  public double size()
  {
    return( m_Polygon.size() );
  }

  public void resize( double scaleFactor )
  {
    m_Polygon.resize( scaleFactor );
    m_Mass = m_Mass + m_Mass * scaleFactor;
  }

  public void move( GPoint gp )
  {
    Console.writeln( "Moving polygon from " + getLocation().getCenter() + 
		     " to " + gp );

    // ada: moved the move command after the message, otherwise we lose the old location
    m_Polygon.translate( getLocation().getCenter(), gp );
  }

  public void rotate( GPoint gp, double angle )
  {
    m_Polygon.rotate( gp, angle );
  }
 
  public Location getLocation()
  {
    return( new Location( m_Polygon.getBounds() ) );
  }

  public Rectangle getBounds()
  {
    return( m_Polygon.getBounds() );
  }

  public GPolygon getPolygon()
  {
    return m_Polygon;
  }

///////////////////////////////////////////////////////////////////////////

  public void draw( Graphics g )
  {
//      if ( getColor() == null )
//        g.setColor( Colors.getColor( "sim_body" ) );
//      else
//        g.setColor( getColor() );
    m_Polygon.display( g );
  }

///////////////////////////////////////////////////////////////////////////

  //  public boolean includes( GPoint gp )
  //{
  // return( m_Polygon.includes( gp ) );
  //}

  public boolean includes( GPoint gp, double offset )
  {
    return( m_Polygon.includes( gp, offset ) );
  }

  public boolean includes( WLine l, double offset )
  {
    return( m_Polygon.includes( l.getLine(), offset ) );
  }

  public boolean contains( GPoint gp )
  {
    if( m_Polygon == null ) {
      Assert.note( "contains() should have been overwritten for this class: " +
		   getClass() );
      return false;
    }
		   
    return( m_Polygon != null && m_Polygon.contains( gp ) );
  }

  public boolean contains( GPoint gp, double offset )
  {
    return m_Polygon.contains( gp, offset );
  }


}

