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

////////////////////////////////////////////////////////////////////////////////
//
// FILE:	Part.java
//
// AUTHOR:	Manoj D. Muzumdar
//		archon@ai.mit.edu
//
// DATE:	07-XX-98
//
// COPYRIGHT:	Massachusetts Institute of Technology
//		All rights reserved.
//
// PURPOSE:     Representation for a mechanical engineering part
//
// HISTORY:     12-10-98 archon
//              integrated new rec.geo changes
//
////////////////////////////////////////////////////////////////////////////////

package rec.meche.util;

import java.awt.*;
import rec.util.*;
import rec.geo.*;
import rec.sys.*;

/**
 * A Part is a representation of a mechanical engineering part.
 *
 * The components are created beforehand and Part wraps them up.
 */
public class Part extends VisibleWidget
{
  public Part( GShape[] ws, double size )
  {
    Assert.check( ws != null && ws.length >= 1,
		  "parts must have at least one component" );

    m_Components = ws;
    m_Size = size;
  }

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

  public double size()
  {
    return( m_Size );
  }

  public void resize( double scaleFactor )
  {
    // do nothing for now!
  }

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

  public void move( GPoint p )
  {
    GPoint center = (new Location( getBounds() )).getCenter();

    for( int i = 0; i < m_Components.length; ++i ) {
      m_Components[i].translate( center, p );
    }
  }

  /**
   * @param p      The point of rotation.
   * @param angle  THe angle in radians.
   */
  public void rotate( GPoint p, double angle )
  {
    for( int i = 0; i < m_Components.length; ++i ) {
      m_Components[i].rotate( p, angle );
    }
  }

  /**
   * @param angle  The angle in radians.
   */
  public void rotateTo( double angle )
  {
    // It is important to get the center first from the bounds
    //      because the bounds will change after each
    //      component is rotated.

    GPoint center = (new Location( getBounds() )).getCenter();

    for( int i = 0; i < m_Components.length; ++i ) {
      m_Components[i].rotate( center, angle - Math.PI / 2.0 );
    }
  }

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

  public Location getLocation()
  {
    return( new Location( getBounds() ) );
  }

  public Rectangle getBounds()
  {
    Rectangle r = m_Components[0].getBounds();

    // Top left corner point.
    int tlx = r.x;
    int tly = r.y;

    // Bottom right corner point.
    int brx = r.x + r.width;
    int bry = r.y + r.height;

    for( int i = 1; i < m_Components.length; ++i ) {

      r = m_Components[i].getBounds();

      tlx = Math.min( tlx, r.x );
      tly = Math.min( tly, r.y );
      brx = Math.max( brx, r.x + r.width );
      bry = Math.max( bry, r.y + r.height );
    }

    return( new Rectangle( tlx, tly, brx - tlx, bry - tly ) );
  }

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

  public void draw( Graphics g )
  {
    for( int i = 0; i < m_Components.length; ++i ) {
      m_Components[i].display( g );
    }
  }

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

  public boolean includes( GPoint p, double offset )
  {
    for( int i = 0; i < m_Components.length; ++i ) {
      if( m_Components[i].includes( p, offset ) )
	return( true );
    }

    return( false );
  }

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

  public Object clone()
  {
    GShape[] ret = new GShape[m_Components.length];

    for( int i = 0; i < m_Components.length; ++i ) {
      ret[i] = (GShape)m_Components[i].clone();
    }

    return( new Part( ret, m_Size ) );
  }

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

  public GShape[] getComponents()
  {
    return( m_Components );
  }

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

  protected GShape[] m_Components;
  protected double m_Size;
}

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