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

package rec.house;


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

public class DataFixer extends Tracker
{
  public DataFixer()
  {
  }
  
  public Iterator getInputTypes()
  {
    Vector v = new Vector();
    
    v.addElement( "rec.house.Region" );
    v.addElement( "rec.house.Wall" );
    
    return v.iterator();
  }

  public Iterator getOutputTypes() 
  {
    return getInputTypes();
  }


  public void removed( Widget widget )
  {
    if ( widget instanceof Region )
      {
	// fix bordering walls.
	Region r = (Region)widget;
	Iterator e = r.walls();

	while( e.hasNext() )
	  {
	    Wall w = (Wall)e.next();
	    
	    w.removeRegion( r );

	    if ( !w.isBorder() )
	      {
		surface.unregister( this, w );
		surface.removeWidget( w );
	      }
	  }
      }
  }


  public void replaced( Widget ow, Collection nws )
  {
    if ( ow instanceof Region )
      {
	Console.indent();
	// region has been split.
	fixWalls( (Region)ow, nws );
	Console.outdent();
      }
    else if ( ow instanceof Wall )
      {
	// wall was split
	Console.writeln( "DataFixer fixing split wall." );
	Wall w = (Wall)ow;

	Iterator e = w.regions();
	while( e.hasNext() )
	  {
	    Region r = (Region) e.next();
	    
	    // remove from old wall.
	    r.removeWall( w );
	    w.removeRegion( r );

	    Iterator e2 = nws.iterator();
	    while( e2.hasNext() )
	      {
		Wall w2 =  (Wall)e2.next();
		r.addWall( w2 );
		w2.addRegion( r );
	      }
	  }
      }
    else
      Assert.note( "unknown replace of " + ow );
  }

  public void replaced( Widget ow, Widget nw )
  {
    Console.writeln( "DF: single replace of " + ow + " -> " + nw );
    if ( ow instanceof Wall )
      {
	// wall was split
	Console.writeln( "DataFixer fixing (merged?) wall." );
	Wall w = (Wall)ow;

	Iterator e = w.regions();
	while( e.hasNext() )
	  {
	    Region r = (Region) e.next();
	    
	    // remove from old wall.
	    // note--this changes structure of widget so it could
	    // be doing nothing if this is the second round of the
	    // merge's events
	    r.removeWall( w );
	    w.removeRegion( r );

	    Wall w2 =  (Wall)nw;
	    r.addWall( w2 );
	    w2.addRegion( r );
	  }
      }
  }


  public void altered( Widget widget, Transition t )
  {
  }
  
  private void fixWalls( Region r, Collection nws )
  {
    Iterator e = r.walls();

    while( e.hasNext() )
      {
	Wall w = (Wall)e.next();
	Console.writeln( "looking at " + w );

	// remove the old region
	w.removeRegion( r );
	r.removeWall( w );

	// find new region and add it
	Iterator e2 = nws.iterator();
	while( e2.hasNext() )
	  {
	    Region new_r = (Region)e2.next();
	    
	    if ( new_r.includes( w, RegionRecognizer.BREAK ) )
	      {
		Console.writeln( w + " is in " + new_r );
		Console.indent();
		w.addRegion( new_r );
		new_r.addWall( w );
		Console.outdent();
	      }
	    else
	      Console.writeln( w + " is not in " + new_r );
	  }
      }
  }

} // end DataFixer

