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

package rec.house;

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

public class Wall extends WLine
{
  Surface surface;

  // the neighboring regions (only 2 max, but since regions can briefly
  // overlap there can be up to 3--HACK HHACK PUKIE PUKE!)
  HashSet regions;

  static {
    Colors.setDefaultColor( "wall", "stroke" );
  }
  
  public Wall( Surface s, GPoint p1, GPoint p2 )
  {
    super( p1, p2 );
    regions = new HashSet();

    surface = s;
  }

  public Wall( Surface s, Squiggle st )
  {
    super( st );
    regions = new HashSet();

    surface = s;
  }

  public Object clone()
  {
    Wall w = new Wall( surface, getHead(), getTail() );
    
    w.regions = (HashSet)regions.clone();

    return w;
  }

  
  /**
   * Make a Wall, add it to the surface, add the transition.
   */
  static public Wall changeToWall( Surface s, WLine wl )
  {
    Wall w = new Wall( s, wl.getHead(), wl.getTail() );
    s.replaceWidget( wl, w );

    return w;
  }

  public void addRegion( Region r )
  {
    replaceRegion( null, r );
  }

  public void removeRegion( Region r )
  {
    replaceRegion( r, null );
  }

  void replaceRegion( Region old, Region new_r )
  {
    if ( old != null )
      {
	Assert.check( bordering( old ),
		      "Region " + old + " not bordering " + this );
      }

    Transition t = makeReplaceRegion( old, new_r );

    // get the reverse and do the deed
    t = t.undo();

    surface.addTransition( t );
  }

  /**
   * Make transition which sets position p to new_r, and the reverse of
   * which sets position p to the old value.
   */
  protected Transition makeReplaceRegion(  Region old_r, Region new_r )
  {
    final Region n = new_r;
    final Region o = old_r;
    final Wall the_wall = this;

    // make the transition effect here
    return new Transition( surface ) {
      public void doUndo()
	{
	  if ( o != null )
	    regions.remove( o );

	  if ( n != null )
	    regions.add( n );
	}

      public Transition makeRedoTransition( )
	{
	  return makeReplaceRegion( n, o );
	}

      public String name()
	{
	  return "repRegion[" + o + "->" + n + "]";
	}
    };      
  }

  public boolean bordering( Region r )
  {
    return regions.contains( r );
  }


  public boolean isBorder( )
  {
    return regions.size() > 0;
  }

  public boolean full()
  {
    return regions.size() >= 2;
  }


  public Iterator regions()
  {
    return ((HashSet)regions.clone()).iterator();
  }

  public void draw( Graphics g )
  {
    draw( g, false );
  }

  public void draw( Graphics g, boolean parent )
  {
    // WARNING--Make sure regions know us if we know them!
    // if we are border, then region will draw us.
    if ( !parent && isBorder() )
      return;

    Color bk = g.getColor();

    GPoint h = getHead();
    GPoint t = getTail();

    if ( getColor() == null )
      g.setColor( Colors.brighten(  Colors.getColor( "wall" ) ) );
    else
      g.setColor( Colors.brighten( getColor() ) );

    
    // get perp to the segment.
    double dy = t.x - h.x;
    double dx = -1 * ( t.y - h.y );
    double len = getLength();
    dx = ( 5 * dx / len );
    dy = ( 5 * dy / len );
    
    g.drawLine( (int)( h.x + dx), (int)(h.y + dy),
		(int)(t.x + dx), (int)(t.y + dy ));
    g.drawLine( (int)( h.x - dx), (int)(h.y - dy),
		(int)(t.x - dx), (int)(t.y - dy) );

    /*
    GPoint cent = getLocation().getCenter();

    g.setColor( Colors.getColor( "text" ) );

    g.drawString( "" + getId(),
		  (int)cent.x, (int)cent.y );
    */

    g.setColor( bk );
  }

  
}

