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

////////////////////////////////////////////////////////////////////////////////
//
// FILE:	WGroup.java
//
// AUTHOR:	Manoj D. Muzumdar
//		archon@ai.mit.edu
//
// DATE:	06-XX-98
//
// COPYRIGHT:	Massachusetts Institute of Technology
//		All rights reserved.
//
// PURPOSE:	Drawing recognition
//
// HISTORY:     11-15-98 archon
//              Now aware of new rec.geo package
//
////////////////////////////////////////////////////////////////////////////////

package rec.core.widgets;

import java.awt.*;
import java.util.*;

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

public class WGroup extends VisibleWidget implements Registerable
{
  Rectangle bounds;

  Vector widgets;

  public WGroup()
  {
    setEnglishName( "Group of items" );
    widgets = new Vector();
    
    //setColor( Colors.getColor( "selected" ) );
  }

  public WGroup( Vector wid )
  {
    setEnglishName( "Group of items" );
    if ( wid != null )
      widgets = (Vector)wid.clone();
    else
      widgets = new Vector();

    //setColor( Colors.getColor( "selected" ) );
  }

  // I know, these are the same, just couldn't deal with going to find where
  // nsize occurs, and i think nsize is a silly name, besides, size must
  // be defined
  public double size()
  {
    return widgets.size();
  }

  public double nsize()
  {
    return widgets.size();
  }

  public void resize( double scaleFactor )
  {
  }

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

  public void add( VisibleWidget w )
  {
    widgets.addElement( w );
  }

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

  public void move( GPoint gp )
  {
    bounds = null;
  }

  public void rotate( GPoint gp, double angle )
  {
    Iterator e = widgets.iterator();

    while( e.hasNext() )
      {
	( (VisibleWidget)( e.next() ) ).rotate( gp, angle );
      }

    bounds = null;
  }


  protected Color selectedColor()
  {
    Color selcol =  Colors.getColor( "selected" );
    selcol = new Color( selcol.getRed(), selcol.getGreen(), selcol.getBlue(),
			80 );

    return selcol;
  }

  public void draw( Graphics g )
  {
//      Iterator e = widgets.iterator();

//      while( e.hasNext() )
//        {
//  	( (VisibleWidget)e.next() ).draw( g );
//        }

    drawSelection( g );
  }

  public void drawSquiggles( Graphics g ) 
  {
    drawSelection( g );
  }
  
  protected void drawSelection( Graphics g )
  {
    Color c = g.getColor();

    Rectangle r = getBounds();

    Color selCol = selectedColor();
    
    g.setColor( selCol );

    g.fillRect( r.x, r.y, r.width, r.height );

    g.setColor( c );
  }


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

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

  public Rectangle getBounds()
  {
    if ( bounds != null )
      return bounds;

    Iterator e = widgets.iterator();

    while( e.hasNext() )
      {
	VisibleWidget w = ( (VisibleWidget)( e.next() ) );

	if ( bounds == null )
	  bounds = w.getBounds();
	else
	  bounds = bounds.union( w.getBounds() );
      }

    return bounds;
  }


  public boolean includes( GPoint gp, double offset )
  {
    Iterator e = widgets.iterator();

    while( e.hasNext() )
      {
	if ( ( (VisibleWidget)e.next() ).includes( gp, offset ) )
	  return true;
      }

    return false;
  }

  public boolean contains( GPoint gp )
  {
    Iterator e = widgets.iterator();

    while( e.hasNext() )
    {
      if ( ( (VisibleWidget)e.next() ).contains( gp ) )
	return true;
    }
    return false;
  }

  public Iterator iterator( )
  {
    return widgets.iterator();
  }


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

  public Vector getWidgets()
  {
    return (Vector)widgets.clone();
  }

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

  public Object clone()
  {
    return( new WGroup( widgets ) );
  }

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




  /**
   * This gives a transition which unpacks the current group.
   *
   * UNUSED
   */
  private Transition getUnpack( Surface surf )
  {
    final WGroup g = this;

    return new Transition( surf ) {
      public void doUndo()
	{
	  Surface s = this.getSurface();

	  s.removeWidget( g );
	  Iterator e = widgets.iterator();
	  while( e.hasNext() )
	    {
	      s.addWidgetToSurface( (VisibleWidget)e.next() );
	    }
	}

      public Transition makeRedoTransition( )
	{
	  return getPack( this.getSurface() );
	}

      public String name()
	{
	  return "wgrouppack";
	}
    };
  }



  /**
   * This gives a transition which packs the current group.
   * 
   * UNUSED
   */
  private  Transition getPack( Surface surf )
  {
    final WGroup g = this;

    return new Transition( surf ) {
      public void doUndo()
	{
	  Surface s = this.getSurface();

	  Iterator e = widgets.iterator();
	  while( e.hasNext() )
	    {
	      s.removeWidgetFromSurface( (VisibleWidget)e.next() );
	    }

	  s.addWidget( g, false );
	}

      public Transition makeRedoTransition( )
	{
	  return getUnpack( this.getSurface() );
	}

      public String name()
	{
	  return "pack";
	}
    };
  }


  /**
   * This removes the widgets in the group from surface.
   */
  public void pack( Surface s )
  {
    WGroup g = this;

    // remove grouped widgets from surface
    Iterator e = widgets.iterator();
    while( e.hasNext() )
      s.removeWidgetFromSurface( (VisibleWidget)e.next() );

    // add group (us) to surface
    s.addWidgetToSurface( g );
  }

  /**
   * This removes the widgets in the group from surface.
   */
  public void unpack( Surface s )
  {
    WGroup g = this;

    Iterator e = widgets.iterator();
    while( e.hasNext() )
      s.addWidgetToSurface( (VisibleWidget)e.next() );

    // add group (us) to surface
    s.removeWidgetFromSurface( g );
  }


  public void altered( Widget w, Transition t )
  {
    //Console.writeln( "Group self-altering notification process" );
    // this is only for itself
    Iterator e = widgets.iterator();
    Surface s = getSurface();

    while( e.hasNext() )
      {
	VisibleWidget tw = ( (VisibleWidget)( e.next() ) );
	
	s.alterWidget( tw, (AlterTransition)t );
      }
  }

  // we MAY need to redefine some of the family member stuff here since
  // this is a group of widgets

  // redefine uproot to uproot all the widgets in the group.
//    public Collection uproot()
//    {
//      Collection dead_ones = new HashSet();
    
//      Iterator it = widgets.iterator();
//      while ( it.hasNext() ) {
//        dead_ones.addAll( ((Widget)it.next()).uproot() );
//      }

//      dead_ones.addAll( super.uproot() );
    
//      return dead_ones;
//    }
  
}

