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

// $Id: WSimCircle.java,v 1.10 2003/06/03 15:32:35 cadlerun Exp $
// Time-stamp: <2000-07-18 13:46:16 moltmans>
package rec.simulate.widgets;


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

// this is a body, even though it doesn't have a polygon associated with
// it because it has all the semantic properties of a body, if not the 
// geometric ones.
public abstract class WSimCircle extends WSimBody
{

  public WSimCircle( WCircle c )
  {
    setDefaultColor( "circle_body", "sim_body" );
    setEnglishName( "Circular body" );
    m_Radius = c.getRadius();
    m_Circle = new GCircle( c.getLocation().getCenter(), m_Radius );
    m_Name = "Circle" + getId();
    m_Polygon = null;
  }
  
  public GCircle getCircle()
  {
    return m_Circle;
  }

  public GShape getShape()
  {
    return m_Circle;
  }

  public boolean overlaps( WSimBody b ) 
  {
    if ( b instanceof WSimCircle ) {
      if ( m_Circle.overlaps( ((WSimCircle)b).getCircle() ) ) {
	return true;
      }
    }
    else {
      if ( m_Circle.overlaps( b.getPolygon() ) ) {
	return true;
      }
    }
    return false;
  }

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

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

  public void resize( double scaleFactor )
  {
    m_Circle.resize( scaleFactor );

    // ada: also update the radius of the circle
    m_Radius = m_Circle.getRadius();
  }

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

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

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

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

  /**
   * @return  true if the point is _inside_ the circle (within offset)
   */
  public boolean contains( GPoint gp, double offset )
  {
    return( m_Circle.contains( gp.x, gp.y, offset ) );
  }

  /**
   * @return  true if the point is _inside_ the circle
   */
  public boolean contains( GPoint gp )
  {
    return m_Circle.contains( gp );
  }

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

  public void move( GPoint gp )
  {
    m_Circle.translate( m_Circle.getCenter(), gp );
  }

  public void rotate( GPoint gp, double angle )
  {
    // Rotating a circle has no effect.
  }

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

  public Location getLocation()
  {
    return( new Location( m_Circle.getCenter(), m_Circle.getRadius() ) );
  }

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

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

  public void translate( double dx, double dy )
  {
    m_Circle.translate( dx, dy );
  }

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

  public GPoint getCenter()
  {
    return( m_Circle.getCenter() );
  }

  public double getRadius()
  {
    return( m_Circle.getRadius() );
  }

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

  public Object clone()
  {
    return( new WCircle( m_Circle.getCenter(), m_Circle.getRadius() ) );
  }
///////////////////////////////////////////////////////////////////////////
  
  public Collection isa()
  {
    Class c = null;
    try {
      c = Class.forName( "rec.simulate.widgets.WSimCircle" );
    }
    catch( ClassNotFoundException e ) {

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

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

  }

  
  protected GCircle m_Circle;
  protected double m_Radius;


}
