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

// -*-Mode: Java-*- 
// $Id: SelfDrawingWidget.java,v 1.7 2003/03/06 00:40:39 moltmans Exp $
// SelfDrawingWidget.java -- 
// Author: Michael Oltmans <moltmans@ai.mit.edu> 
// Created: <Fri Mar 17 11:23:02 2000> 
// Time-stamp: <2000-06-10 11:42:59 moltmans> 
package rec.sys;

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


/**
 * This clas takes care of the drawing translating, etc...
 **/
public class SelfDrawingWidget extends VisibleWidget
{
  protected GShape[] m_parts;
  protected double m_size;
  protected double m_angle;
  
  public SelfDrawingWidget() 
  {
    m_size = 0;
    m_angle = 0;
  }

  /**
   * @param parts Collection of GShapes that represent the widget.
   **/
  public SelfDrawingWidget( Collection parts )
  {
    this();
    setParts( parts );
  }

  public SelfDrawingWidget( GShape[] parts )
  {
    this();
    setParts( parts );
  }

  /** Don't copy the parts... so we can keep pointers to them **/
  public void setParts( Collection parts ) 
  {
    m_parts = (GShape[])parts.toArray();

//      m_parts = new GShape[ parts.size() ];
//      int i=0;
//      Iterator it = parts.iterator();
//      while( it.hasNext() ) {
//        GShape shape = (GShape)it.next();
//        m_parts[i] = (GShape)shape.clone();
//        i++;
//      }
  }

  /** Don't copy the parts... so we can keep pointers to them **/
  public void setParts( GShape[] parts ) 
  {
    m_parts = parts;

//      m_parts = new GShape[ parts.length ];
    
//      for( int i=0; i<parts.length; i++ ) {
//        m_parts[i] = (GShape)parts[i].clone();
//      }
  }
  
  public double size()
  {
    return m_size;
  }

  /**
   * There is no way to do this without knowing more info, subclasses
   * will have to cope with it themselves.  (imagine shrinking a
   * square, the edges need to be translated to maintain contact)
   **/
  public void resize( double scaleFactor )
  {
    String error = "SelfDrawingWidget.resize(double)";
    throw( new UnsupportedOperationException( error ) );
  }

  /**
   * Using a cordinate frame centered on our center, translate to
   * point p.
   **/
  public void translate( GPoint p )
  {
    GPoint center = getLocation().getCenter();

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

  }

  /**
   * Move ourselves so that our center is at p.
   **/
  public void move( GPoint p ) 
  {
    GPoint center = getLocation().getCenter();
    
    for( int i = 0; i < m_parts.length; i++ ) {
      m_parts[i].translate( center, p );
    }
  }

  /**
   * Rotate the object around point p by angle degrees
   **/
  public void rotate( GPoint p, double angle )
  {
    for( int i = 0; i < m_parts.length; ++i ) {
      m_parts[i].rotate( p, Radian.reduce( angle ) );
    }

    m_angle = Radian.reduce( m_angle + angle );
  }

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

  public Rectangle getBounds()
  {
    Rectangle r = m_parts[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_parts.length; ++i ) {

      r = m_parts[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 )
  {
    DebugWindow.addLine( "point", "Drawing" );
    for( int i = 0; i < m_parts.length; ++i ) {
      m_parts[i].display( g );
    }
  }

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

    return( false );
  }

  public boolean contains( GPoint p )
  {
    for( int i = 0; i < m_parts.length; ++i ) {
      if( m_parts[i].contains( p ) )
	return( true );
    }

    return( false );
  }

  
}

